staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
authorBernd Porr <mail@berndporr.me.uk>
Mon, 18 Nov 2019 23:07:59 +0000 (23:07 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Nov 2019 17:29:06 +0000 (18:29 +0100)
commit 5618332e5b955b4bff06d0b88146b971c8dd7b32 upstream.

The userspace comedilib function 'get_cmd_generic_timed' fills
the cmd structure with an informed guess and then calls the
function 'usbduxfast_ai_cmdtest' in this driver repeatedly while
'usbduxfast_ai_cmdtest' is modifying the cmd struct until it
no longer changes. However, because of rounding errors this never
converged because 'steps = (cmd->convert_arg * 30) / 1000' and then
back to 'cmd->convert_arg = (steps * 1000) / 30' won't be the same
because of rounding errors. 'Steps' should only be converted back to
the 'convert_arg' if 'steps' has actually been modified. In addition
the case of steps being 0 wasn't checked which is also now done.

Signed-off-by: Bernd Porr <mail@berndporr.me.uk>
Cc: <stable@vger.kernel.org> # 4.4+
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Link: https://lore.kernel.org/r/20191118230759.1727-1-mail@berndporr.me.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/usbduxfast.c

index 608403c..f0572d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk
+ *  Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
  * Description: University of Stirling USB DAQ & INCITE Technology Limited
  * Devices: [ITL] USB-DUX-FAST (usbduxfast)
  * Author: Bernd Porr <mail@berndporr.me.uk>
- * Updated: 10 Oct 2014
+ * Updated: 16 Nov 2019
  * Status: stable
  */
 
@@ -31,6 +31,7 @@
  *
  *
  * Revision history:
+ * 1.0: Fixed a rounding error in usbduxfast_ai_cmdtest
  * 0.9: Dropping the first data packet which seems to be from the last transfer.
  *      Buffer overflows in the FX2 are handed over to comedi.
  * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
@@ -359,6 +360,7 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
                                 struct comedi_cmd *cmd)
 {
        int err = 0;
+       int err2 = 0;
        unsigned int steps;
        unsigned int arg;
 
@@ -408,11 +410,16 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
         */
        steps = (cmd->convert_arg * 30) / 1000;
        if (cmd->chanlist_len !=  1)
-               err |= comedi_check_trigger_arg_min(&steps,
-                                                   MIN_SAMPLING_PERIOD);
-       err |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD);
-       arg = (steps * 1000) / 30;
-       err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
+               err2 |= comedi_check_trigger_arg_min(&steps,
+                                                    MIN_SAMPLING_PERIOD);
+       else
+               err2 |= comedi_check_trigger_arg_min(&steps, 1);
+       err2 |= comedi_check_trigger_arg_max(&steps, MAX_SAMPLING_PERIOD);
+       if (err2) {
+               err |= err2;
+               arg = (steps * 1000) / 30;
+               err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
+       }
 
        if (cmd->stop_src == TRIG_COUNT)
                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);