staging: comedi: comedi_test: limit maximum convert_arg
When testing the parameters for setting up an asynchronous command on
the AI subdevice, limit the maximum conversion period
(`cmd->convert_arg`) so that the number of conversions in a scan
(`cmd->scan_end_arg`, same as `cmd->chanlist_len`) multiplied by the
conversion period fits within an `unsigned int`, as that is used to
limit the minimum scan period (`cmd->scan_begin_arg`).
Also ensure rounding of the conversion period and scan period to the
nearest microsecond both fit in an `unsigned int`. Do all this in stage
4 ("fix up any arguments") of the command testing.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
87f64803ca
commit
5afdcad2f8
@@ -234,7 +234,7 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
|
||||
struct comedi_cmd *cmd)
|
||||
{
|
||||
int err = 0;
|
||||
unsigned int arg;
|
||||
unsigned int arg, limit;
|
||||
|
||||
/* Step 1 : check if triggers are trivially valid */
|
||||
|
||||
@@ -265,16 +265,8 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
|
||||
if (cmd->convert_src == TRIG_NOW)
|
||||
err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
|
||||
NSEC_PER_USEC);
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
err |= comedi_check_trigger_arg_min(&cmd->
|
||||
scan_begin_arg,
|
||||
cmd->convert_arg *
|
||||
cmd->chanlist_len);
|
||||
}
|
||||
}
|
||||
err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
|
||||
NSEC_PER_USEC);
|
||||
|
||||
err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
|
||||
err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
|
||||
@@ -290,21 +282,29 @@ static int waveform_ai_cmdtest(struct comedi_device *dev,
|
||||
|
||||
/* step 4: fix up any arguments */
|
||||
|
||||
if (cmd->scan_begin_src == TRIG_TIMER) {
|
||||
arg = cmd->scan_begin_arg;
|
||||
/* round to nearest microsec */
|
||||
arg = NSEC_PER_USEC *
|
||||
((arg + (NSEC_PER_USEC / 2)) / NSEC_PER_USEC);
|
||||
err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
|
||||
}
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
/* round convert_arg to nearest microsecond */
|
||||
arg = cmd->convert_arg;
|
||||
/* round to nearest microsec */
|
||||
arg = NSEC_PER_USEC *
|
||||
((arg + (NSEC_PER_USEC / 2)) / NSEC_PER_USEC);
|
||||
arg = min(arg,
|
||||
rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
|
||||
arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
|
||||
/* limit convert_arg to keep scan_begin_arg in range */
|
||||
limit = UINT_MAX / cmd->scan_end_arg;
|
||||
limit = rounddown(limit, (unsigned int)NSEC_PER_SEC);
|
||||
arg = min(arg, limit);
|
||||
err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
|
||||
}
|
||||
|
||||
/* round scan_begin_arg to nearest microsecond */
|
||||
arg = cmd->scan_begin_arg;
|
||||
arg = min(arg, rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC));
|
||||
arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC);
|
||||
if (cmd->convert_src == TRIG_TIMER) {
|
||||
/* but ensure scan_begin_arg is large enough */
|
||||
arg = max(arg, cmd->convert_arg * cmd->scan_end_arg);
|
||||
}
|
||||
err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
|
||||
|
||||
if (err)
|
||||
return 4;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user