Refactor das1800_probe() to return an errno instead of the boardinfo pointer. Add the board 'id' to the boardinfo to tidy up this function to clarify the sanity check when the user provided a board name when trying to attach to the driver. Currently when this function probes for a boardinfo based on the board id it returns the wrong boardinfo for the "st-da" and "hr-da" types. This causes the analog input subdevice for those boards to not be available. Fix the probe so that a proper boardinfo is used. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/das1800.c | 206 +++++++++++++++++++------------ 1 file changed, 130 insertions(+), 76 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 6f40bb8..bb99efc 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -167,13 +167,6 @@ TODO: #define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */ -enum { - das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, - das1702hr_da, - das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, - das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao -}; - static const struct comedi_lrange das1801_ai_range = { 8, { BIP_RANGE(5), /* bipolar gain = 1 */ @@ -200,8 +193,38 @@ static const struct comedi_lrange das1802_ai_range = { } }; +enum das1800_boardid { + BOARD_DAS1701ST, + BOARD_DAS1701ST_DA, + BOARD_DAS1702ST, + BOARD_DAS1702ST_DA, + BOARD_DAS1702HR, + BOARD_DAS1702HR_DA, + BOARD_DAS1701AO, + BOARD_DAS1702AO, + BOARD_DAS1801ST, + BOARD_DAS1801ST_DA, + BOARD_DAS1802ST, + BOARD_DAS1802ST_DA, + BOARD_DAS1802HR, + BOARD_DAS1802HR_DA, + BOARD_DAS1801HC, + BOARD_DAS1802HC, + BOARD_DAS1801AO, + BOARD_DAS1802AO +}; + +/* board probe id values (hi byte of the digital input register) */ +#define DAS1800_ID_ST_DA 0x3 +#define DAS1800_ID_HR_DA 0x4 +#define DAS1800_ID_AO 0x5 +#define DAS1800_ID_HR 0x6 +#define DAS1800_ID_ST 0x7 +#define DAS1800_ID_HC 0x8 + struct das1800_board { const char *name; + unsigned char id; unsigned int ai_speed; unsigned int is_16bit:1; unsigned int has_64_ai_chan:1; @@ -217,89 +240,124 @@ struct das1800_board { * user manual.) */ static const struct das1800_board das1800_boards[] = { - { + [BOARD_DAS1701ST] = { .name = "das-1701st", + .id = DAS1800_ID_ST, .ai_speed = 6250, .das1801_range = 1, - }, { + }, + [BOARD_DAS1701ST_DA] = { .name = "das-1701st-da", + .id = DAS1800_ID_ST_DA, .ai_speed = 6250, .das1801_range = 1, .has_ao = 1, .has_4_ao_chan = 1, - }, { + }, + [BOARD_DAS1702ST] = { .name = "das-1702st", + .id = DAS1800_ID_ST, .ai_speed = 6250, - }, { + }, + [BOARD_DAS1702ST_DA] = { .name = "das-1702st-da", + .id = DAS1800_ID_ST_DA, .ai_speed = 6250, .has_ao = 1, .has_4_ao_chan = 1, - }, { + }, + [BOARD_DAS1702HR] = { .name = "das-1702hr", + .id = DAS1800_ID_HR, .ai_speed = 20000, .is_16bit = 1, - }, { + }, + [BOARD_DAS1702HR_DA] = { .name = "das-1702hr-da", + .id = DAS1800_ID_HR_DA, .ai_speed = 20000, .is_16bit = 1, .has_ao = 1, - }, { + }, + [BOARD_DAS1701AO] = { .name = "das-1701ao", + .id = DAS1800_ID_AO, .ai_speed = 6250, .das1801_range = 1, .has_wform_ao = 1, - }, { + }, + [BOARD_DAS1702AO] = { .name = "das-1702ao", + .id = DAS1800_ID_AO, .ai_speed = 6250, .has_wform_ao = 1, - }, { + }, + [BOARD_DAS1801ST] = { .name = "das-1801st", + .id = DAS1800_ID_ST, .ai_speed = 3000, .das1801_range = 1, - }, { + }, + [BOARD_DAS1801ST_DA] = { .name = "das-1801st-da", + .id = DAS1800_ID_ST_DA, .ai_speed = 3000, .das1801_range = 1, .has_ao = 1, .has_4_ao_chan = 1, - }, { + }, + [BOARD_DAS1802ST] = { .name = "das-1802st", + .id = DAS1800_ID_ST, .ai_speed = 3000, - }, { + }, + [BOARD_DAS1802ST_DA] = { .name = "das-1802st-da", + .id = DAS1800_ID_ST_DA, .ai_speed = 3000, .has_ao = 1, .has_4_ao_chan = 1, - }, { + }, + [BOARD_DAS1802HR] = { .name = "das-1802hr", + .id = DAS1800_ID_HR, .ai_speed = 10000, .is_16bit = 1, - }, { + }, + [BOARD_DAS1802HR_DA] = { .name = "das-1802hr-da", + .id = DAS1800_ID_HR_DA, .ai_speed = 10000, .is_16bit = 1, .has_ao = 1, - }, { + }, + [BOARD_DAS1801HC] = { .name = "das-1801hc", + .id = DAS1800_ID_HC, .ai_speed = 3000, .has_64_ai_chan = 1, .das1801_range = 1, .has_ao = 1, .has_8_do_chan = 1, - }, { + }, + [BOARD_DAS1802HC] = { .name = "das-1802hc", + .id = DAS1800_ID_HC, .ai_speed = 3000, .has_64_ai_chan = 1, .has_ao = 1, .has_8_do_chan = 1, - }, { + }, + [BOARD_DAS1801AO] = { .name = "das-1801ao", + .id = DAS1800_ID_AO, .ai_speed = 3000, .das1801_range = 1, .has_wform_ao = 1, - }, { + }, + [BOARD_DAS1802AO] = { .name = "das-1802ao", + .id = DAS1800_ID_AO, .ai_speed = 3000, .has_wform_ao = 1, }, @@ -1094,68 +1152,67 @@ static void das1800_free_dma(struct comedi_device *dev) comedi_isadma_free(devpriv->dma); } -static const struct das1800_board *das1800_probe(struct comedi_device *dev) +static int das1800_probe(struct comedi_device *dev) { const struct das1800_board *board = dev->board_ptr; - int index = board ? board - das1800_boards : -EINVAL; - int id; + unsigned char id; + + id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* * The dev->board_ptr will be set by comedi_device_attach() if the * board name provided by the user matches a board->name in this * driver. If so, this function sanity checks the id to verify that * the board is correct. - * - * If the dev->board_ptr is not set, the user is trying to attach - * an unspecified board to this driver. In this case the id is used - * to 'probe' for the correct dev->board_ptr. */ - id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; + if (board) { + if (board->id == id) + return 0; + dev_err(dev->class_dev, + "probed id does not match board id (0x%x != 0x%x)\n", + id, board->id); + return -ENODEV; + } + + /* + * If the dev->board_ptr is not set, the user is trying to attach + * an unspecified board to this driver. In this case the id is used + * to 'probe' for a dev->board_ptr. + */ switch (id) { - case 0x3: - if (index == das1801st_da || index == das1802st_da || - index == das1701st_da || index == das1702st_da) - return board; - index = das1801st; + case DAS1800_ID_ST_DA: + /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */ + board = &das1800_boards[BOARD_DAS1801ST_DA]; break; - case 0x4: - if (index == das1802hr_da || index == das1702hr_da) - return board; - index = das1802hr; + case DAS1800_ID_HR_DA: + /* das-1702hr-da, das-1802hr-da */ + board = &das1800_boards[BOARD_DAS1802HR_DA]; break; - case 0x5: - if (index == das1801ao || index == das1802ao || - index == das1701ao || index == das1702ao) - return board; - index = das1801ao; + case DAS1800_ID_AO: + /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */ + board = &das1800_boards[BOARD_DAS1801AO]; break; - case 0x6: - if (index == das1802hr || index == das1702hr) - return board; - index = das1802hr; + case DAS1800_ID_HR: + /* das-1702hr, das-1802hr */ + board = &das1800_boards[BOARD_DAS1802HR]; break; - case 0x7: - if (index == das1801st || index == das1802st || - index == das1701st || index == das1702st) - return board; - index = das1801st; + case DAS1800_ID_ST: + /* das-1701st, das-1702st, das-1801st, das-1802st */ + board = &das1800_boards[BOARD_DAS1801ST]; break; - case 0x8: - if (index == das1801hc || index == das1802hc) - return board; - index = das1801hc; + case DAS1800_ID_HC: + /* das-1801hc, das-1802hc */ + board = &das1800_boards[BOARD_DAS1801HC]; break; default: - dev_err(dev->class_dev, - "Board model: probe returned 0x%x (unknown, please report)\n", - id); - return NULL; + dev_err(dev->class_dev, "invalid probe id 0x%x\n", id); + return -ENODEV; } - dev_err(dev->class_dev, - "Board model (probed, not recommended): %s series\n", - das1800_boards[index].name); - - return &das1800_boards[index]; + dev->board_ptr = board; + dev->board_name = board->name; + dev_warn(dev->class_dev, "probed id 0x%0x: %s series (not recommended)\n", + id, board->name); + return 0; } static int das1800_attach(struct comedi_device *dev, @@ -1176,13 +1233,10 @@ static int das1800_attach(struct comedi_device *dev, if (ret) return ret; - board = das1800_probe(dev); - if (!board) { - dev_err(dev->class_dev, "unable to determine board type\n"); - return -ENODEV; - } - dev->board_ptr = board; - dev->board_name = board->name; + ret = das1800_probe(dev); + if (ret) + return ret; + board = dev->board_ptr; /* waveform 'ao' boards have additional io ports */ if (board->has_wform_ao) { -- 2.6.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel