Ian Abbott [Mon, 12 Oct 2015 16:21:24 +0000 (17:21 +0100)]
staging: comedi: avoid bad truncation of a size_t in comedi_read()
At one point in `comedi_read()`, the variable `n` gets assigned to the
minimum of the parameter `nbytes` and the amount of readable buffer
space `m`. The way that is done currently is unsafe in the unlikely
case that `nbytes` exceeds `UINT_MAX`, so fix it.
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>
Ian Abbott [Mon, 12 Oct 2015 16:21:23 +0000 (17:21 +0100)]
staging: comedi: make some variables unsigned in comedi_read()
In `comedi_read()`, the `n` and `m` variables are of type `int`. Change
them to `unsigned int` as they are used to measure a positive number of
bytes. The `count` variable is also of type `int` and holds the
returned number of bytes. Change it to type `ssize_t` to match the
function's return type.
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>
Ian Abbott [Mon, 12 Oct 2015 16:21:22 +0000 (17:21 +0100)]
staging: comedi: do extra checks for becoming non-busy for "read"
`comedi_read()` is the handler for the "read" file operation for COMEDI
devices. It mostly runs without using the main mutex of the COMEDI
device, but uses the `attach_lock` rwsemaphore to protect against the
COMEDI device becoming "detached". A file object can read data
resulting from a COMEDI asynchonous command if it initiated the command.
The COMEDI subdevice is marked as busy when the command is started. At
some point, the "read" handler detects that the command has terminated
and all available data has been read and so marks the subdevice as
non-busy.
In order to mark the subdevice as non-busy, the "read" handler needs to
release the `attach_lock` rwsemaphore and `acquire the main `mutex`.
There is a vulnerable point between the two, so it checks that the
device is still attached after acquiring the mutex. However, it does
not currently check that the conditions for becoming non-busy still
hold. Add some more checks that the subdevice is still busy with a
command initiated by the same file object, that command is in the correct
direction (in case the subdevice supports both "read" and "write"), that
command has terminated, and has no data available to be read.
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>
Ian Abbott [Mon, 12 Oct 2015 16:21:21 +0000 (17:21 +0100)]
staging: comedi: don't consider "unmunged" data when becoming non-busy
If an asynchronous "read" command is no longer running but the subdevice
is still busy, it becomes non-busy once there is no more data available
in the buffer. Some or all of the data written to the buffer might not
have been "munged" yet, and it cannot be read until it has been munged
by the writer. However, since the command is no longer running, we
cannot expect any remaining unmunged data to get munged so we should
ignore it. Call `comedi_buf_read_n_available()` to check the amount of
munged data available to be read, replacing the call to
`comedi_buf_n_bytes_ready()` which checked the amount of written (but
possibly not yet munged) data available to be read. This affects both
the "read" file operation (done in `comedi_read()`) and the
`COMEDI_BUFINFO` ioctl handling (done in `do_bufinfo_ioctl()`). (The
latter is used when data is transferred directly through the mmapped
buffer instead of via the "read" file operation.)
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>
Ian Abbott [Mon, 12 Oct 2015 16:21:20 +0000 (17:21 +0100)]
staging: comedi: remain busy until read end-of-file
If a COMEDI subdevice is busy handling an asynchronous command in the
"read" direction, then after the command has terminated itself, the
"read" file operation handler, `comedi_read()` should keep the subdevice
busy until all available data has been read and it has returned 0 to
indicate an "end-of-file" condition. Currently, it has a bug where it
can mark the subdevice as non-busy even when returning a non-zero count.
The bug is slightly hidden because the next "read" will return 0 because
the subdevice is no longer busy. Fix it by checking the return count is
0 before deciding to mark the subdevice as non-busy.
The call to `comedi_is_subdevice_idle()` is superfluous as the
`become_nonbusy` variable will have been set to `true` when considering
becoming non-busy. Strictly speaking, checking the return count is
superfluous too, as `become_nonbusy` doesn't get set to `true` unless
the count is 0, but check the return count anyway to make the intention
clearer.
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>
Ian Abbott [Fri, 9 Oct 2015 11:26:52 +0000 (12:26 +0100)]
staging: comedi: don't use mutex when polling file
The main mutex in a comedi device can get held for quite a while when
processing comedi instructions, so for performance reasons, the "read"
and "write" file operations do not use it; they use use the
`attach_lock` rwsemaphore to protect against the comedi device becoming
detached at an inopportune moment. Do the same for the "poll" file
operation.
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>
Ian Abbott [Fri, 9 Oct 2015 11:26:51 +0000 (12:26 +0100)]
staging: comedi: check command started by file being polled
Currently, the "poll" file operation checks if an asynchronous "read"
(or "write" command is active on the "read" (or "write" subdevice, but
does not consider whether the command was started from the file object
being polled. Since that is the only file object able to read (or
write) data, take it into consideration.
With this change, if no read (or write) command is running on the
subdevice, or it is started by a different file object, the file object
is marked as readable (or writeable) regardless, but the read (or write)
file operation will return an error.
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>
Ian Abbott [Fri, 9 Oct 2015 11:26:50 +0000 (12:26 +0100)]
staging: comedi: don't allocate buffer space when polling for write
When handling the "poll" file operation and checking for `POLLOUT`,
don't allocate space from the buffer for writing, just check that space
is available for writing. That check is done after checking that an
asynchronous "write" command is running on the subdevice. Allocating
the buffer space before checking a "write" command is running can cause
problems if the subdevice supports commands in either direction and
currently has an active "read" 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>
Ian Abbott [Fri, 9 Oct 2015 11:26:49 +0000 (12:26 +0100)]
staging: comedi: add new comedi_buf_write_n_available()
Add a new function `comedi_buf_write_n_available()` to return the amount
of buffer space available for writing, including space already allocated
by `comedi_buf_write_alloc()` plus any unallocated space available.
This is currently just for internal use by the comedi core, so is not
exported.
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 local function `comedi_buf_write_n_available()` to
`comedi_buf_write_n_unalloc()`. It is the amount of unallocated space
available in the buffer that is available to be allocated for writing
and does not include the space that has already been allocated for
writing. This is unlike the exported function
`comedi_buf_read_n_available()` which includes the space available to be
allocated for reading plus the space already allocated for reading. The
new name breaks the unintentional naming symmetry (and also clears the
way for the old name to be reused for a new function).
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>
Ian Abbott [Fri, 9 Oct 2015 11:26:47 +0000 (12:26 +0100)]
staging: comedi: don't poll_wait on same subdevice twice
Comedi subdevices that support asynchronous acquisition commands have a
wait queue head used for blocking reads or writes and for the poll file
operation. The comedi device may have several subdevices that support
"read" and/or "write" commands, but each open file object has at most
one "read" subdevice and one "write" subdevice. It's possible (though
rare) for those to be the same subdevice if the subdevice supports
commands in either direction. In that case, the "poll" file operation
doesn't really need to do a `poll_wait()` on the same subdevice twice.
Although harmless, it wastes a poll table entry. Check for that, and
avoid it.
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>
staging: comedi: cb_das16_cs: the DAC16/16-AO only has 4 digital I/O
The PC-CARD DAS16/16-AO board only has 4 digital I/O channels. The other
boards supported by this driver have 8. Add the boardinfo to correctly
initialize the subdevice.
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>
Only one of the boards supported by this driver has analog outputs.
For aesthetics, change the 'n_ao_chans' member of the boardinfo into
a bit-field flag 'has_ao'.
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>
staging: comedi: cb_das16_cs: fix ai mux register programming
The ai mux register is used program the hi/lo channels in a scan.
According to the user manual, the hi and lo channels should be
the same to sample one channel.
Introduce some macros to set the appropriate bits in the ai mux
register and fix the ai (*insn_read).
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 driver supports three board types with these differences:
104-AIO12-8 - eight 12-bit analog in, four 12-bit analog out
104-AI12-8 - eight 12-bit analog in
104-AO12-4 - four 12-bit analog out
Convert the boardinfo 'ai_nchan' and 'ao_nchan' into bit-field
flags 'has_ai' and 'has_ao' so save a bit of space.
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>
According to the user manual, analog input bipolar data is 2's
complement and unipolar is straight binry. Use the core helpers
to munge the data appropriately.
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>