[PATCH 03/10] staging: comedi: adl_pci9118: tidy up check_channel_list()

H Hartley Sweeten hsweeten at visionengravers.com
Mon Oct 19 20:12:58 UTC 2015


Rename this function to give it namespace associated with the driver.

Currently this function is called by both the AI (*do_cmdtest) and the (*do_cmd)
functions. It really only needs to be called by the (*do_cmdtest) to validate
that the chanlist meets the requirements of the hardware. It's only called by
the (*do_cmd) to verify that the scan length is not to large after adding the
extra samples needed to satisfy the DMA.

Move the extra scan length check into the (*do_cmd) function and remove the
unnecessary parameters 'frontadd' and 'backadd'.

Tidy up the reset of the function.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/adl_pci9118.c | 104 +++++++++++++--------------
 1 file changed, 51 insertions(+), 53 deletions(-)

diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
index dcfe5cc..08cd046 100644
--- a/drivers/staging/comedi/drivers/adl_pci9118.c
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -169,11 +169,6 @@ static const struct comedi_lrange pci9118hg_ai_range = {
 	}
 };
 
-#define PCI9118_BIPOLAR_RANGES	4	/*
-					 * used for test on mixture
-					 * of BIP/UNI ranges
-					 */
-
 enum pci9118_boardid {
 	BOARD_PCI9118DG,
 	BOARD_PCI9118HG,
@@ -296,46 +291,44 @@ static void pci9118_ai_reset_fifo(struct comedi_device *dev)
 	outl(0, dev->iobase + PCI9118_FIFO_RESET_REG);
 }
 
-static int check_channel_list(struct comedi_device *dev,
-			      struct comedi_subdevice *s, int n_chan,
-			      unsigned int *chanlist, int frontadd, int backadd)
+static int pci9118_ai_check_chanlist(struct comedi_device *dev,
+				     struct comedi_subdevice *s,
+				     struct comedi_cmd *cmd)
 {
 	struct pci9118_private *devpriv = dev->private;
-	unsigned int i, differencial = 0, bipolar = 0;
+	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+	unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
+	int i;
 
-	if ((frontadd + n_chan + backadd) > s->len_chanlist) {
-		dev_err(dev->class_dev,
-			"range/channel list is too long for actual configuration!\n");
+	/* single channel scans are always ok */
+	if (cmd->chanlist_len == 1)
 		return 0;
-	}
 
-	if (CR_AREF(chanlist[0]) == AREF_DIFF)
-		differencial = 1;	/* all input must be diff */
-	if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
-		bipolar = 1;	/* all input must be bipolar */
-	if (n_chan > 1)
-		for (i = 1; i < n_chan; i++) {	/* check S.E/diff */
-			if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
-			    (differencial)) {
-				dev_err(dev->class_dev,
-					"Differential and single ended inputs can't be mixed!\n");
-				return 0;
-			}
-			if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
-			    (bipolar)) {
-				dev_err(dev->class_dev,
-					"Bipolar and unipolar ranges can't be mixed!\n");
-				return 0;
-			}
-			if (!devpriv->usemux && differencial &&
-			    (CR_CHAN(chanlist[i]) >= (s->n_chan / 2))) {
-				dev_err(dev->class_dev,
-					"AREF_DIFF is only available for the first 8 channels!\n");
-				return 0;
-			}
+	for (i = 1; i < cmd->chanlist_len; i++) {
+		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+		unsigned int range = CR_RANGE(cmd->chanlist[i]);
+		unsigned int aref = CR_AREF(cmd->chanlist[i]);
+
+		if (aref != aref0) {
+			dev_err(dev->class_dev,
+				"Differential and single ended inputs can't be mixed!\n");
+			return -EINVAL;
+		}
+		if (comedi_range_is_bipolar(s, range) !=
+		    comedi_range_is_bipolar(s, range0)) {
+			dev_err(dev->class_dev,
+				"Bipolar and unipolar ranges can't be mixed!\n");
+			return -EINVAL;
+		}
+		if (!devpriv->usemux && aref == AREF_DIFF &&
+		    (chan >= (s->n_chan / 2))) {
+			dev_err(dev->class_dev,
+				"AREF_DIFF is only available for the first 8 channels!\n");
+			return -EINVAL;
 		}
+	}
 
-	return 1;
+	return 0;
 }
 
 static void pci9118_set_chanlist(struct comedi_device *dev,
@@ -940,6 +933,7 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 	struct comedi_8254 *pacer = dev->pacer;
 	struct comedi_cmd *cmd = &s->async->cmd;
 	unsigned int addchans = 0;
+	unsigned int scanlen;
 
 	devpriv->ai12_startstop = 0;
 	devpriv->ai_flags = cmd->flags;
@@ -1025,19 +1019,20 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 		}
 	}
 	/* well, we now know what must be all added */
-	devpriv->ai_n_realscanlen =	/*
-					 * what we must take from card in real
-					 * to have cmd->scan_end_arg on output?
-					 */
-	    (devpriv->ai_add_front + cmd->chanlist_len +
-	     devpriv->ai_add_back) * (cmd->scan_end_arg /
-				      cmd->chanlist_len);
-
-	/* check and setup channel list */
-	if (!check_channel_list(dev, s, cmd->chanlist_len,
-				cmd->chanlist, devpriv->ai_add_front,
-				devpriv->ai_add_back))
+	scanlen = devpriv->ai_add_front + cmd->chanlist_len +
+		  devpriv->ai_add_back;
+	/*
+	 * what we must take from card in real to have cmd->scan_end_arg
+	 * on output?
+	 */
+	devpriv->ai_n_realscanlen = scanlen *
+				    (cmd->scan_end_arg / cmd->chanlist_len);
+
+	if (scanlen > s->len_chanlist) {
+		dev_err(dev->class_dev,
+			"range/channel list is too long for actual configuration!\n");
 		return -EINVAL;
+	}
 
 	/*
 	 * Configure analog input and load the chanlist.
@@ -1307,10 +1302,13 @@ static int pci9118_ai_cmdtest(struct comedi_device *dev,
 	if (err)
 		return 4;
 
+	/* Step 5: check channel list if it exists */
+
 	if (cmd->chanlist)
-		if (!check_channel_list(dev, s, cmd->chanlist_len,
-					cmd->chanlist, 0, 0))
-			return 5;	/* incorrect channels list */
+		err |= pci9118_ai_check_chanlist(dev, s, cmd);
+
+	if (err)
+		return 5;
 
 	return 0;
 }
-- 
2.5.1



More information about the devel mailing list