Age | Commit message (Collapse) | Author |
|
commit bf279ece37d2a3eaaa9813fcd7a1d8a81eb29c20 upstream.
Move comedi_proc_init to the end to avoid orphaned proc entry
if module loading failed.
Signed-off-by: Cheah Kok Cheong <thrust73@gmail.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit a9332e9ad09c2644c99058fcf6ae2f355e93ce74 upstream.
There is a clean-up bug in the core comedi module initialization
functions, `comedi_init()`. If the `comedi_num_legacy_minors` module
parameter is non-zero (and valid), it creates that many "legacy" devices
and registers them in SysFS. A failure causes the function to clean up
and return an error. Unfortunately, it fails to destroy the "comedi"
class that was created earlier. Fix it by adding a call to
`class_destroy(comedi_class)` at the appropriate place in the clean-up
sequence.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 8ec04a491825e08068e92bed0bba7821893b6433 upstream.
The timer expiry routine `jr3_pci_poll_dev()` checks for expiry by
checking whether the absolute value of `jiffies` (stored in local
variable `now`) is greater than the expected expiry time in jiffy units.
This will fail when `jiffies` wraps around. Also, it seems to make
sense to handle the expiry one jiffy earlier than the current test. Use
`time_after_eq()` to check for expiry.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 45292be0b3db0b7f8286683b376e2d9f949d11f9 upstream.
For some reason, the driver does not consider allocation of the
subdevice private data to be a fatal error when attaching the COMEDI
device. It tests the subdevice private data pointer for validity at
certain points, but omits some crucial tests. In particular,
`jr3_pci_auto_attach()` calls `jr3_pci_alloc_spriv()` to allocate and
initialize the subdevice private data, but the same function
subsequently dereferences the pointer to access the `next_time_min` and
`next_time_max` members without checking it first. The other missing
test is in the timer expiry routine `jr3_pci_poll_dev()`, but it will
crash before it gets that far.
Fix the bug by returning `-ENOMEM` from `jr3_pci_auto_attach()` as soon
as one of the calls to `jr3_pci_alloc_spriv()` returns `NULL`. The
COMEDI core will subsequently call `jr3_pci_detach()` to clean up.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit f6b1160eb27f990cc1c48b67a5f83cb63115284e upstream.
Arnd Bergmann pointed out that gcc-6 warns about passing negative signed
integer into swab16() due to the macro expansion of 'outw'.
It appears that the register map constants are causing the warnings.
Actually, it might just be the (1 << 15) ones...
Convert all the constants as suggested by checkpatch.pl:
CHECK: Prefer using the BIT macro
The BIT() macro will make all the constants explicitly 'unsigned', which
helps to avoid the warning.
Fix the, unsused, DT2821_CHANCSR_PRESLA() macro. The "Present List
Address" (PRESLA) bits in the CHANCSR register are read only. This
define was meant to extract the bits from the read value.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reported-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Tested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 857a661020a2de3a0304edf33ad656abee100891 upstream.
Commit 0557344e2149 ("staging: comedi: ni_mio_common: fix local var for
32-bit read") changed the type of local variable `d` from `unsigned
short` to `unsigned int` to fix a bug introduced in
commit 9c340ac934db ("staging: comedi: ni_stc.h: add read/write
callbacks to struct ni_private") when reading AI data for NI PCI-6110
and PCI-6111 cards. Unfortunately, other parts of the function rely on
the variable being `unsigned short` when an offset value in local
variable `signbits` is added to `d` before writing the value to the
`data` array:
d += signbits;
data[n] = d;
The `signbits` variable will be non-zero in bipolar mode, and is used to
convert the hardware's 2's complement, 16-bit numbers to Comedi's
straight binary sample format (with 0 representing the most negative
voltage). This breaks because `d` is now 32 bits wide instead of 16
bits wide, so after the addition of `signbits`, `data[n]` ends up being
set to values above 65536 for negative voltages. This affects all
supported "E series" cards except PCI-6143 (and PXI-6143). Fix it by
ANDing the value written to the `data[n]` with the mask 0xffff.
Fixes: 0557344e2149 ("staging: comedi: ni_mio_common: fix local var for 32-bit read")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 655c4d442d1213b617926cc6d54e2a9a793fb46b upstream.
For NI M Series cards, the Comedi `insn_read` handler for the AI
subdevice is broken due to ANDing the value read from the AI FIFO data
register with an incorrect mask. The incorrect mask clears all but the
most significant bit of the sample data. It should preserve all the
sample data bits. Correct it.
Fixes: 817144ae7fda ("staging: comedi: ni_mio_common: remove unnecessary use of 'board->adbits'")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 5ca05345c56cb979e1a25ab6146437002f95cac8 upstream.
For counter subdevices, the `s->insn_write` handler is being set to the
wrong function, `ni_tio_insn_read()`. It should be
`ni_tio_insn_write()`.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reported-by: Éric Piel <piel@delmic.com>
Fixes: 10f74377eec3 ("staging: comedi: ni_tio: make ni_tio_winsn() a
proper comedi (*insn_write)"
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit f0f4b0cc3a8cffd983f5940d46cd0227f3f5710a upstream.
Commit ebb657babfa9 ("staging: comedi: ni_mio_common: clarify the
cmd->start_arg validation and use") introduced a backwards compatibility
issue in the use of asynchronous commands on the AO subdevice when
`start_src` is `TRIG_EXT`. Valid values for `start_src` are `TRIG_INT`
(for internal, software trigger), and `TRIG_EXT` (for external trigger).
When set to `TRIG_EXT`. In both cases, the driver relies on an
internal, software trigger to set things up (allowing the user
application to write sufficient samples to the data buffer before the
trigger), so it acts as a software "pre-trigger" in the `TRIG_EXT` case.
The software trigger is handled by `ni_ao_inttrig()`.
Prior to the above change, when `start_src` was `TRIG_INT`, `start_arg`
was required to be 0, and `ni_ao_inttrig()` checked that the software
trigger number was also 0. After the above change, when `start_src` was
`TRIG_INT`, any value was allowed for `start_arg`, and `ni_ao_inttrig()`
checked that the software trigger number matched this `start_arg` value.
The backwards compatibility issue is that the internal trigger number
now has to match `start_arg` when `start_src` is `TRIG_EXT` when it
previously had to be 0.
Fix the backwards compatibility issue in `ni_ao_inttrig()` by always
allowing software trigger number 0 when `start_src` is something other
than `TRIG_INT`.
Thanks to Spencer Olson for reporting the issue.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Reported-by: Spencer Olson <olsonse@umich.edu>
Fixes: ebb657babfa9 ("staging: comedi: ni_mio_common: clarify the cmd->start_arg validation and use")
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 403fe7f34e3327ddac2e06a15e76a293d613381e upstream.
Commit 73e0e4dfed4c ("staging: comedi: comedi_test: fix timer lock-up")
fixed a lock-up in the timer routine `waveform_ai_timer()` (which was
called `waveform_ai_interrupt()` at the time) caused by
commit 240512474424 ("staging: comedi: comedi_test: use
comedi_handle_events()"). However, it introduced a race condition that
can result in the timer routine misbehaving, such as accessing freed
memory or dereferencing a NULL pointer.
73e0... changed the timer routine to do nothing unless a
`WAVEFORM_AI_RUNNING` flag was set, and changed `waveform_ai_cancel()`
to clear the flag and replace a call to `del_timer_sync()` with a call
to `del_timer()`. `waveform_ai_cancel()` may be called from the timer
routine itself (via `comedi_handle_events()`), or from `do_cancel()`.
(`do_cancel()` is called as a result of a file operation (usually a
`COMEDI_CANCEL` ioctl command, or a release), or during device removal.)
When called from `do_cancel()`, the call to `waveform_ai_cancel()` is
followed by a call to `do_become_nonbusy()`, which frees up stuff for
the current asynchronous command under the assumption that it is now
safe to do so. The race condition occurs when the timer routine
`waveform_ai_timer()` checks the `WAVEFORM_AI_RUNNING` flag just before
it is cleared by `waveform_ai_cancel()`, and is still running during the
call to `do_become_nonbusy()`. In particular, it can lead to a NULL
pointer dereference:
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffffc0c63add>] waveform_ai_timer+0x17d/0x290 [comedi_test]
That corresponds to this line in `waveform_ai_timer()`:
unsigned int chanspec = cmd->chanlist[async->cur_chan];
but `do_become_nonbusy()` frees `cmd->chanlist` and sets it to `NULL`.
Fix the race by calling `del_timer_sync()` instead of `del_timer()` in
`waveform_ai_cancel()` when not in an interrupt context. The only time
`waveform_ai_cancel()` is called in an interrupt context is when it is
called from the timer routine itself, via `comedi_handle_events()`.
There is no longer any need for the `WAVEFORM_AI_RUNNING` flag, so get
rid of it.
The bug was copied from the AI subdevice to the AO when support for
commands on the AO subdevice was added by commit 0cf55bbef2f9 ("staging:
comedi: comedi_test: implement commands on AO subdevice"). That
involves the timer routine `waveform_ao_timer()`, the comedi "cancel"
routine `waveform_ao_cancel()`, and the flag `WAVEFORM_AO_RUNNING`. Fix
it in the same way as for the AI subdevice.
Fixes: 73e0e4dfed4c ("staging: comedi: comedi_test: fix timer lock-up")
Fixes: 0cf55bbef2f9 ("staging: comedi: comedi_test: implement commands
on AO subdevice")
Reported-by: Éric Piel <piel@delmic.com>
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Cc: Éric Piel <piel@delmic.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 80e162ee9b31d77d851b10f8c5299132be1e120f upstream.
`daqboard2000_find_boardinfo()` is supposed to check if the
DaqBoard/2000 series model is supported, based on the PCI subvendor and
subdevice ID. The current code is wrong as it is comparing the PCI
device's subdevice ID to an expected, fixed value for the subvendor ID.
It should be comparing the PCI device's subvendor ID to this fixed
value. Correct it.
Fixes: 7e8401b23e7f ("staging: comedi: daqboard2000: add back subsystem_device check")
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit d375278d666760e195693b57415ba0a125cadd55 upstream.
DMA is optional with this driver. If it was not enabled the devpriv->dma
pointer will be NULL.
Fix the possible NULL pointer dereference when trying to disable the DMA
channels in das1800_ai_cancel() and tidy up the comments to fix the
checkpatch.pl issues:
WARNING: line over 80 characters
It's probably harmless in das1800_ai_setup_dma() because the 'desc' pointer
will not be used if DMA is disabled but fix it there also.
Fixes: 99dfc3357e98 ("staging: comedi: das1800: remove depends on ISA_DMA_API limitation")
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit bd3a3cd6c27b117fb9a43a38c8072c95332beecc upstream.
Memory mapped io (dev->mmio) should not also be writing to the ioport
(dev->iobase) registers. Add the missing 'else' to these functions.
Fixes: 0953ee4acca0 ("staging: comedi: ni_mio_common: checkpatch.pl cleanup (else not useful)")
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
commit 1fd24a4702d2af0ea4d5845126cf57d4d1796216 upstream.
This fixes a bug in function ni_tio_input_inttrig(). The trigger number
should be compared to cmd->start_arg, not cmd->start_src.
Fixes: 6a760394d7eb ("staging: comedi: ni_tiocmd: clarify the cmd->start_arg validation and use")
Signed-off-by: Spencer E. Olson <olsonse@umich.edu>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Implement COMEDI asynchronous commands on the fake analog output
subdevice. This is useful for testing asynchronous commands in the
"write" direction when no real hardware is available.
A normal kernel timer is used to drive the command. The new timer
expiry function `waveform_ao_timer()` handles whole "scans" at a time
according to the number of scan period that have elapsed since the last
scan. Data for each channel in the scan is written to the internal
loopback array `devpriv->ao_loopbacks[]` and can be read back on the
analog input channels. However, if several scan periods are outstanding
in the timer expiry function, only the latest available scan data is
written to the loopback array in order to save processing time. The
expiry function also checks for underrun conditions, and checks for
normal termination of the asynchronous command when a "stop" scan count
is reached.
After the command is tested by `waveform_ao_cmdtest()` and set up by
`waveform_ao_cmd()`, it is not started until an internal trigger
function `waveform_ao_inttrig_start()` is called as a result of the user
performing an `INSN_INTTRIG` instruction on the subdevice. The command
is stopped when the "cancel" handler `waveform_ao_cancel()` is called.
This may be due to the command terminating due to completion or an
error, or as a result of the user cancelling the command.
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>
|
|
`waveform_ai_interrupt()` is a timer expiry function used to generate
fake waveform data for an analog input subdevice. Rename it to
`waveform_ai_timer()`.
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>
|
|
For asynchronous command handling on the analog input subdevice, a
kernel timer routine is used to generate the fake waveform data. A
"scan" consists of a number of conversions separated in time by a
conversion period. Successive scans are separated in time by a scan
period, which is at least the conversion period multiplied by the number
of conversions per scan. Currently, the timer routine does not generate
any data until the end of a scan period, generating whole scans of data
at a time. Change it to generate data at the end of each conversion
period, with an extra delay after the final conversion in each scan if
necessary. Use new member `ai_convert_time` in the private data
structure `struct waveform_private` to keep track of when the next
conversion is due. This replaces the old member `ai_last_scan_time`
which kept track of the time of the previous scan.
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>
|
|
COMEDI drivers often allow the last value written to a channel on an
analog output subdevice to be read back via the "insn_read" handler.
The "comedi_test" driver does not currently support that. It is a bit
special because it loops back the last values written to the channel on
the analog output subdevice to be read back via corresponding channels
on the analog input subdevice. The "insn_read" handler for the analog
input subdevice is `waveform_ai_insn_read()`. Set that as the
"insn_read" handler for the analog output subdevice as well.
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>
|
|
The last sample values written to the AO subdevice channels by its
"insn_write" handler `waveform_ao_insn_write()` are stored in the member
array `ao_loopbacks[]` in the device private data `struct
waveform_private`. They can be read back via the "insn_read" handler of
the AI subdevice `waveform_ai_insn_read()`. As the stored sample values
are only 16 bits wide, change the type of the `ao_loopbacks[]` member to
`unsigned short` to save some space.
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>
|
|
The asynchronous command handling for the analog input subdevice uses a
kernel timer which expires approximately `HZ` times a second. However,
it only needs to do anything after each scan period. Set the timer to
expire just after the next scan period.
Although the timer expiry function `waveform_ai_interrupt()` uses
precise time values to generate the fake waveforms used to generate the
data, those time values are constructed in a precise sequence, and do
not depend on the time the timer expiry function is actually called. So
the timer expiry rate does not have to be very precise.
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>
|
|
Rename the members `struct waveform_private` associated with fake
waveform generation. The affected members are `uvolt_amplitude` -->
`wf_amplitude` (the amplitude of the waveform), `usec_period` -->
`wf_period` (the period of the waveform), and `usec_current` -->
`wf_current` (the current time within a waveform period).
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>
|
|
Rename the members of `struct waveform_private` that are used to handle
AI commands, apart from those members used to control fake waveform
generation. The renames are `timer` --> `ai_timer`, `scan_period` -->
`ai_scan_period`, and `convert_period` --> `ai_convert_period`.
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>
|
|
The private data structure `struct waveform_private` currently uses
member `last` to remember the time of the last timer interrupt, and the
member `usec_remainder` to keep track of how far into a simulated scan
the interrupt occurred. Replace these with a single new member
`ai_last_scan_time` that records the time of the last scan. This
simplifies the calculation of the number of scans to simulate in the
timer routine, `waveform_ai_interrupt()`.
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>
|
|
Use `unsigned int` instead of `unsigned long` to hold the period of the
fake waveform generator and the current time within each waveform. The
waveform period will be no more than `INT_MAX` and the current time
within the waveform (prior to the modulo operation to bring it actually
within the waveform period) will be no more than `INT_MAX + UINT_MAX /
1000`.
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>
|
|
The fake waveform generator functions, `fake_sawtooth()` and
`fake_squarewave()`, called from `fake_waveform()`, have a
`current_time` parameter which is the time since the start of a waveform
period. The parameter value may be greater than the waveform period so
they do a modulo operation to bring it into range. Do the modulo
operations outside the functions in `waveform_ai_interrupt()` so that
the waveform generator functions always get a `current_time` parameter
less than the waveform period and do not have to do the modulo operation
themselves. Also, only do the modulo operations when the time since the
start of a waveform exceeds the waveform period. Usually, several
samples are produced in each waveform period and modulo operations are
typically more expensive than a simple comparison.
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>
|
|
It is quite common for COMEDI subdevices that support commands to
support setting `scan_begin_src` to `TRIG_FOLLOW`. This means the next
scan begins once all conversions in the current scan are complete.
Support the following timing combinations for the AI subdevice:
scan_begin_src == TRIG_TIMER && convert_src == TRIG_TIMER
scan_begin_src == TRIG_TIMER && convert_src == TRIG_NOW
scan_begin_src == TRIG_FOLLOW && convert_src == TRIG_TIMER
The actual scan period in microseconds is stored in the `scan_period`
member of the private data structure `struct waveform_private`. An
`unsigned int` is still wide enough, because the conversion period is no
more than `UINT_MAX / 1000` microseconds and the number of conversions
is no more than 16 (`N_CHANS * 2`).
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>
|
|
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>
|
|
The `static const int nano_per_micro` variable is set to 1000, the
number of nanoseconds in a microsecond. Remove it and use the
`NSEC_PER_USEC` macro from <linux/time.h> instead.
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>
|
|
While an asynchronous command is running on the analog input subdevice,
fake waveform generators are connected to each channel to provide the
input voltages that are converted to sample value. Channel 0 is
connected to a sawtooth generator, channel 1 is connected to a
squarewave generator, and the remaining channels are connected to a
flatline generator. The non-flatline generators share the same
amplitude (in microvolts) and period (in microseconds) which are
configured when the COMEDI device is attached. All waveforms are
centered around 0 microvolts and the non-flatline waveforms go between
-amplitude and +amplitude.
It is possible for the waveforms to swing outside the input range of the
channels to which they are connected. When that happens, the sample
values resulting from simulated A-to-D conversion will wrap around due
to integer overflow. Prevent that by clamping the sample values that
would go out of range. This is closer to how a real hardware device
would behave (assuming the input voltage is not high enough to damage
the hardware!).
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>
|
|
Use the preferred style for multi-line comments.
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>
|
|
`comedi_nsamples_left(s, nsamples)` returns the number of samples
remaining to complete an asynchronous command or the passed in
`nsamples`, whichever is lower. However, it goes wrong in the extreme
case of setting the `nsamples` parameter to `UINT_MAX` when the number
of conversions per "scan" (`s->async->cmd.scan_end_arg`) is 1. It uses
`comedi_nscans_remaining(s, nscans)` to determine the number of scans
remaining, or the parameter `nscans`, whichever is lower. To determine
the parameter `nscans`, it divides `nsamples` by the number of
conversions per scan and adds 1. The addition of 1 is to avoid setting
the parameter `nscans` to 0, as `comedi_nscans_remaining(s, nscans)`
treats that value specially. However in the extreme case where
`nsamples` is `UINT_MAX` and the number of samples per scan is 1, the
addition of 1 to `nscans` overflows, producing the unwanted 0.
Fix it by refactoring new a function `__comedi_nscans_remaining(s,
nscans)` out of `comedi_nscans_remaining(s, nscans)`. The new function
does everything except the special handling when `nscans` is 0. Change
`comedi_nsamples_remaining()` to call the new function without adding 1
to `nscans` to avoid the overflow.
This overflow bug doesn't affect any of the current COMEDI drivers. I
stumbled across it while changing to one of the drivers.
Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
For aesthetics, init the dmalen[01] local variables when they are declared.
Use a local variable, 'scan_bytes', for the (devpriv->ai_n_realscanlen << 1)
calculation. For aesthetics and clarification, use comedi_bytes_per_sample()
instead of the '<< 1' shift to calculate the value.
The local variable 'i' is badly named. Remove it and use a local variable
'tmp' where it is used.
When checking the DMA buffer lengths for non-neverending commands the
scan length calculation, (devpriv->ai_n_realscanlen << 1) * cmd->stop_arg,
could overflow. Use and unsigned long long local variable to hold the
calculation and avoid the overflow.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
For aesthetics, rename these functions so it they namespace associated
with the driver.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Rename this function so it has namespace associated with the driver.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Rename this function so it has namespace associated with the driver.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
For aesthetics, remove "interrupt_" from this functions name to shorten
it a bit.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
This define is only used to initialize the analog input sudevice
'len_chanlist'. Remove the define and just open code the value.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
These defines are not used in the driver. Remove them.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Rename this function to give it namespace associated with the driver.
Currently this function is called by both the AI (*do_cmdtest) and the (*do_cmd)
functions. It really only needs to be called by the (*do_cmdtest) to validate
that the chanlist meets the requirements of the hardware. It's only called by
the (*do_cmd) to verify that the scan length is not to large after adding the
extra samples needed to satisfy the DMA.
Move the extra scan length check into the (*do_cmd) function and remove the
unnecessary parameters 'frontadd' and 'backadd'.
Tidy up the reset of the function.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Step 3 of the AI (*do_cmdtest) validates that the cmd->chanlist_len is >= 1. If
it's not the (*do_cmdtest) fails and check_channel_list() is never called. This
This function is also called by the AI (*do_cmd) and the comedi core ensures
that the async command has a valid chanlist. Remove the unnecessary 'n_chan'
check.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
The (*do_cmdtest) in this driver validated the scan_begin_src as being
TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT. The TRIG_INT source is not valid.
Remove the Step 2 mutual compatibility check that makes sure that TRIG_INT
is only used for the start_src or the scan_begin_src.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Simplify function return flow. Issue found
with coccinelle.
Signed-off-by: Cristina Moraru <cristina.moraru09@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Change the MODULE_DESCRIPTION to something more useful than the
generic "Comedi low-level driver".
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
The comedi core expects (*insn_write) functions to write insn->n
data values to the hardware. Fix this function to work like the
core expects.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
The comedi core expects (*insn_write) functions to write insn->n
data values to the hardware. Fix this function to work like the
core expects.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
The ao (*cancel) function does not need commented.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
This inline function just returns the bits needd to enable
a calibration source. For aethetics, absorb it into the callers.
Sorten the variable name in the private data used to hold the
current calibration source.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
The analog output and analog input interrupts are currently cleared
as they are handled. Refactor the code to gather all the bits needed
to clear the interrupts and do it once at the end of the interrupt
handler.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Clarify the interrupt handler by splitting the analog input handling
into a new function.
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
This patch makes ni_tio_has_gate2_registers return boolean, since
this function only uses either one or zero as its return value.
Signed-off-by: Geliang Tang <geliangtang@163.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|