Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7e2a040 authored by Bernd Porr's avatar Bernd Porr Committed by Greg Kroah-Hartman
Browse files

staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error



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: default avatarBernd Porr <mail@berndporr.me.uk>
Cc: <stable@vger.kernel.org> # 4.4+
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Link: https://lore.kernel.org/r/20191118230759.1727-1-mail@berndporr.me.uk


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4101916e
Loading
Loading
Loading
Loading
+14 −7
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0+
// 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
 * Description: University of Stirling USB DAQ & INCITE Technology Limited
 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
 * Devices: [ITL] USB-DUX-FAST (usbduxfast)
 * Author: Bernd Porr <mail@berndporr.me.uk>
 * Author: Bernd Porr <mail@berndporr.me.uk>
 * Updated: 10 Oct 2014
 * Updated: 16 Nov 2019
 * Status: stable
 * Status: stable
 */
 */


@@ -22,6 +22,7 @@
 *
 *
 *
 *
 * Revision history:
 * 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.
 * 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.
 *      Buffer overflows in the FX2 are handed over to comedi.
 * 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
 * 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)
				 struct comedi_cmd *cmd)
{
{
	int err = 0;
	int err = 0;
	int err2 = 0;
	unsigned int steps;
	unsigned int steps;
	unsigned int arg;
	unsigned int arg;


@@ -399,11 +401,16 @@ static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
	 */
	 */
	steps = (cmd->convert_arg * 30) / 1000;
	steps = (cmd->convert_arg * 30) / 1000;
	if (cmd->chanlist_len !=  1)
	if (cmd->chanlist_len !=  1)
		err |= comedi_check_trigger_arg_min(&steps,
		err2 |= comedi_check_trigger_arg_min(&steps,
						     MIN_SAMPLING_PERIOD);
						     MIN_SAMPLING_PERIOD);
	err |= comedi_check_trigger_arg_max(&steps, MAX_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;
		arg = (steps * 1000) / 30;
		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
	}


	if (cmd->stop_src == TRIG_COUNT)
	if (cmd->stop_src == TRIG_COUNT)
		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);