mirror of https://gitee.com/openkylin/linux.git
staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
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>
This commit is contained in:
parent
1637a947e6
commit
5618332e5b
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2004-2014 Bernd Porr, mail@berndporr.me.uk
|
||||
* Copyright (C) 2004-2019 Bernd Porr, mail@berndporr.me.uk
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,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
|
||||
*/
|
||||
|
||||
|
@ -22,6 +22,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.
|
||||
|
@ -350,6 +351,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;
|
||||
|
||||
|
@ -399,11 +401,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);
|
||||
|
|
Loading…
Reference in New Issue