staging: comedi: amplc_pci224: factor out chanlist checking from (*do_cmdtest)
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 16 Apr 2014 21:19:08 +0000 (14:19 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Apr 2014 17:18:47 +0000 (10:18 -0700)
Step 5 of the (*do_cmdtest) validates that the cmd->chanlist is compatible
with the hardware.

For aesthetics, factor the step 5 code for the analog output async command
support. Tidy up the factored out code.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/amplc_pci224.c

index 29e01e280039d2c0519a52baaab16db15aaae4bb..e99829e58635e1bea4f3275a4f43413e84497fe2 100644 (file)
@@ -687,6 +687,37 @@ pci224_ao_inttrig_start(struct comedi_device *dev, struct comedi_subdevice *s,
        return 1;
 }
 
+static int pci224_ao_check_chanlist(struct comedi_device *dev,
+                                   struct comedi_subdevice *s,
+                                   struct comedi_cmd *cmd)
+{
+       unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
+       unsigned int chan_mask = 0;
+       int i;
+
+       for (i = 0; i < cmd->chanlist_len; i++) {
+               unsigned int chan = CR_CHAN(cmd->chanlist[i]);
+               unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+               if (chan_mask & (1 << chan)) {
+                       dev_dbg(dev->class_dev,
+                               "%s: entries in chanlist must contain no duplicate channels\n",
+                               __func__);
+                       return -EINVAL;
+               }
+               chan_mask |= (1 << chan);
+
+               if (range != range0) {
+                       dev_dbg(dev->class_dev,
+                               "%s: entries in chanlist must all have the same range index\n",
+                               __func__);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 #define MAX_SCAN_PERIOD                0xFFFFFFFFU
 #define MIN_SCAN_PERIOD                2500
 #define CONVERT_PERIOD         625
@@ -871,48 +902,9 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
        if (err)
                return 4;
 
-       /* Step 5: check channel list. */
-
-       if (cmd->chanlist && (cmd->chanlist_len > 0)) {
-               unsigned int range;
-               enum { range_err = 1, dupchan_err = 2, };
-               unsigned errors;
-               unsigned int n;
-               unsigned int ch;
-
-               /*
-                * Check all channels have the same range index.  Don't care
-                * about analogue reference, as we can't configure it.
-                *
-                * Check the list has no duplicate channels.
-                */
-               range = CR_RANGE(cmd->chanlist[0]);
-               errors = 0;
-               tmp = 0;
-               for (n = 0; n < cmd->chanlist_len; n++) {
-                       ch = CR_CHAN(cmd->chanlist[n]);
-                       if (tmp & (1U << ch))
-                               errors |= dupchan_err;
-
-                       tmp |= (1U << ch);
-                       if (CR_RANGE(cmd->chanlist[n]) != range)
-                               errors |= range_err;
-
-               }
-               if (errors) {
-                       if (errors & dupchan_err) {
-                               dev_dbg(dev->class_dev,
-                                       "%s: entries in chanlist must contain no duplicate channels\n",
-                                       __func__);
-                       }
-                       if (errors & range_err) {
-                               dev_dbg(dev->class_dev,
-                                       "%s: entries in chanlist must all have the same range index\n",
-                                       __func__);
-                       }
-                       err++;
-               }
-       }
+       /* Step 5: check channel list if it exists */
+       if (cmd->chanlist && cmd->chanlist_len > 0)
+               err |= pci224_ao_check_chanlist(dev, s, cmd);
 
        if (err)
                return 5;