[PATCH 15/35] staging: comedi: das1800: tidy up das1800_probe()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux