From 8a3bee801d420be8a7a0bae4a26547b353b8fe22 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 22 Apr 2026 15:46:37 +0100 Subject: comedi: comedi_test: Fix limiting of convert_arg in waveform_ai_cmdtest() The function checks and possibly modifies the description of an asynchronous command to be run on the analog input subdevice of a comedi device attached to the "comedi_test" driver, returning 0 if no modifications were required, or a positive value that indicates which step of the checking process it failed on. Step 4 fixes up various argument values for various trigger sources. There are two bugs in the fixing up of the `convert_arg` value to keep the `scan_begin_arg` value within the range of `unsigned int` when `scan_begin_src` and `convert_src` both have the value `TRIG_TIMER`, which indicates that the corresponding `_arg` values hold a time period in nanoseconds. The code also uses `scan_end_arg` which hold the number of "conversions" within each "scan". The goal is to end up with the scan period being less than or equal to the convert period multiplied by the number of conversions per scan. It intends to do that by clamping the `convert_arg` value to a maximum value of `UINT_MAX / scan_end_arg` rounded down to a multiple of 1000 (`NSEC_PER_USEC`). (The rounding from nanoseconds to microseconds is because the driver is modelling a device that uses a 1 MHz clock for timing. This is partly because that is a more typical timing base for real hardware devices driven by comedi, and partly because the driver used to use `struct timeval` internally.) The first bug is that the code checks if `scan_begin_arg == TRIG_TIMER` when it should be checking if `scan_begin_src == TRIG_TIMER`. The bugged check will always fail because if `scan_begin_src == TRIG_TIMER`, then `scan_begin_arg` will be at least 1000 (`NSEC_PER_USEC`), otherwise `scan_begin_src == TRIG_FOLLOW` and `scan_begin_arg` will be 0. (N.B `TRIG_TIMER` is defined as `0x10`.) The second bug is that is rounding the maximum value down to a multiple of 1000000000 (`NSEC_PER_SEC`) instead of 1000 (`NSEC_PER_USEC`), however this bug is not reached due to the first bug. This patch fixes both bugs. Fixes: 783ddaebd397 ("staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW") Fixes: 5afdcad2f818 ("staging: comedi: comedi_test: limit maximum convert_arg") Cc: stable Signed-off-by: Ian Abbott Link: https://patch.msgid.link/20260422144637.27692-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/comedi_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 01aafce20ef8..4050f66193e5 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -324,10 +324,10 @@ static int waveform_ai_cmdtest(struct comedi_device *dev, arg = min(arg, rounddown(UINT_MAX, (unsigned int)NSEC_PER_USEC)); arg = NSEC_PER_USEC * DIV_ROUND_CLOSEST(arg, NSEC_PER_USEC); - if (cmd->scan_begin_arg == TRIG_TIMER) { + if (cmd->scan_begin_src == TRIG_TIMER) { /* 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); + limit = rounddown(limit, (unsigned int)NSEC_PER_USEC); arg = min(arg, limit); } err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); -- cgit v1.2.3