Commit Graph

8006 Commits

Author SHA1 Message Date
Cheah Kok Cheong
b5a48676e7 Staging: comedi: comedi_fops: Avoid orphaned proc entry
commit bf279ece37 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>
2017-08-06 19:19:40 -07:00
Ian Abbott
cb2bc13d0b staging: comedi: fix clean-up of comedi_class in comedi_init()
commit a9332e9ad0 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>
2017-07-15 11:57:50 +02:00
Ian Abbott
d3c04901f7 staging: comedi: jr3_pci: cope with jiffies wraparound
commit 8ec04a4918 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>
2017-05-20 14:26:59 +02:00
Ian Abbott
7fc6659b19 staging: comedi: jr3_pci: fix possible null pointer dereference
commit 45292be0b3 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>
2017-05-20 14:26:59 +02:00
H Hartley Sweeten
f5a636fd41 staging: comedi: dt282x: tidy up register bit defines
commit f6b1160eb2 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>
2017-01-12 11:22:50 +01:00
Ian Abbott
01b6089b56 staging: comedi: ni_mio_common: fix E series ni_ai_insn_read() data
commit 857a661020 upstream.

Commit 0557344e21 ("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 9c340ac934 ("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: 0557344e21 ("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>
2017-01-09 08:07:44 +01:00
Ian Abbott
5283a7bedb staging: comedi: ni_mio_common: fix M Series ni_ai_insn_read() data mask
commit 655c4d442d 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: 817144ae7f ("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>
2017-01-09 08:07:44 +01:00
Ian Abbott
fbde41faa1 staging: comedi: ni_mio_common: fix wrong insn_write handler
commit 5ca05345c5 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: 10f74377ee ("staging: comedi: ni_tio: make ni_tio_winsn() a
  proper comedi (*insn_write)"
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-09-07 08:32:45 +02:00
Ian Abbott
b03ee3d047 staging: comedi: ni_mio_common: fix AO inttrig backwards compatibility
commit f0f4b0cc3a upstream.

Commit ebb657babf ("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: ebb657babf ("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>
2016-09-07 08:32:45 +02:00
Ian Abbott
fd51408913 staging: comedi: comedi_test: fix timer race conditions
commit 403fe7f34e upstream.

Commit 73e0e4dfed ("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 2405124744 ("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 0cf55bbef2 ("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: 73e0e4dfed ("staging: comedi: comedi_test: fix timer lock-up")
Fixes: 0cf55bbef2 ("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>
2016-09-07 08:32:45 +02:00
Ian Abbott
bc93350cb4 staging: comedi: daqboard2000: bug fix board type matching code
commit 80e162ee9b 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: 7e8401b23e ("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>
2016-09-07 08:32:45 +02:00
H Hartley Sweeten
023bea7452 staging: comedi: das1800: fix possible NULL dereference
commit d375278d66 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: 99dfc3357e ("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>
2016-06-01 12:15:52 -07:00
H Hartley Sweeten
62fe263236 staging: comedi: ni_mio_common: fix the ni_write[blw]() functions
commit bd3a3cd6c2 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: 0953ee4acc ("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>
2016-04-12 09:08:49 -07:00
Spencer E. Olson
a5e8deb7f0 staging: comedi: ni_tiocmd: change mistaken use of start_src for start_arg
commit 1fd24a4702 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: 6a760394d7 ("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>
2016-04-12 09:08:48 -07:00
Ian Abbott
0cf55bbef2 staging: comedi: comedi_test: implement commands on AO subdevice
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
9406a3140a staging: comedi: comedi_test: rename waveform_ai_interrupt()
`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>
2015-10-29 08:58:36 +09:00
Ian Abbott
1eb85ae857 staging: comedi: comedi_test: handle partial scans in timer routine
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
e0c6fe1294 staging: comedi: comedi_test: allow read-back of AO channels
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
3b2468fe98 staging: comedi: comedi_test: use unsigned short for loopback values
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
4e5ffbf29c staging: comedi: comedi_test: make timer rate similar to scan rate
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
f3f24dff89 staging: comedi: comedi_test: rename waveform members
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
807060a369 staging: comedi: comedi_test: rename members for AI commands
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
66d4da800d staging: comedi: comedi_test: simplify time since last AI scan
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
21ec1bf734 staging: comedi: comedi_test: use unsigned int for waveform timing
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
8fa8a260d2 staging: comedi: comedi_test: move modulo operations for waveform
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
783ddaebd3 staging: comedi: comedi_test: support scan_begin_src == TRIG_FOLLOW
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
5afdcad2f8 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>
2015-10-29 08:58:36 +09:00
Ian Abbott
87f64803ca staging: comedi: comedi_test: remove nano_per_micro
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
19e86985b0 staging: comedi: comedi_test: saturate fake waveform values
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
cbad8cf426 staging: comedi: comedi_test: reformat multi-line comments
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>
2015-10-29 08:58:36 +09:00
Ian Abbott
92d354cbe9 staging: comedi: fix extreme case of comedi_nsamples_left()
`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>
2015-10-27 14:31:25 +09:00
H Hartley Sweeten
eb96c7fc24 staging: comedi: adl_pci9118: tidy up pci9118_ai_setup_dma()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
45037a9569 staging: comedi: adl_pci9118: rename interrupt_*() functions
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
5c912f1f28 staging: comedi: adl_pci9118: rename move_block_from_dma()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
9459ff2b6b staging: comedi: adl_pci9118: rename valid_samples_in_act_dma_buf()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
ad1a9646b7 staging: comedi: adl_pci9118: rename interrupt_pci9118_ai_mode4_switch()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
dd2907c3e7 staging: comedi: adl_pci9118: remove PCI9118_CHANLEN
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
766957f6f1 staging: comedi: adl_pci9118: remove unused defines
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
0f3cb85ac8 staging: comedi: adl_pci9118: tidy up check_channel_list()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
7c999314ef staging: comedi: adl_pci9118: remove unnecessary check in check_channel_list()
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>
2015-10-24 19:17:13 -07:00
H Hartley Sweeten
323538b825 staging: comedi: adl_pci9118: TRIG_INT is not vaild for scan_begin_src
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>
2015-10-24 19:17:13 -07:00
Cristina Moraru
9aed06693d staging: comedi: Fix return flow
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>
2015-10-24 19:16:20 -07:00
H Hartley Sweeten
64289a6506 staging: comedi: cb_pcidas: update MODULE_DESCRIPTION
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
d52688055c staging: comedi: cb_pcidas: fix cb_pcidas_ao_nofifo_insn_write()
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
ef7e20934e staging: comedi: cb_pcidas: fix cb_pcidas_ao_fifo_insn_write()
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
f92738ca2f staging: comedi: cb_pcidas: remove superfluous comment
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
042bac563b staging: comedi: cb_pcidas: absorb cal_enable_bits()
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
46c95d970f staging: comedi: cb_pcidas: consolidate interrupt clear code
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>
2015-10-24 19:15:22 -07:00
H Hartley Sweeten
7d78346987 staging: comedi: cb_pcidas: split ai code out of interrupt handler
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>
2015-10-24 19:15:22 -07:00
Geliang Tang
abfe2196e0 staging: comedi: make ni_tio_has_gate2_registers return boolean
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>
2015-10-24 19:14:25 -07:00