staging: comedi: comedi_fops: always clear events
`comedi_event()` is called from low-level drivers to handle asynchronous command event flags that are stored in `s->async->events` for subdevice `s`. It normally clears the event flags as well. As a safety check, it does nothing if no asynchronous command is running, but it leaves `s->async->events` unchanged in this case. For additional safety, change it to always clear the event flags to avoid leaving stale event flags set when another asynchronous command is set up. 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:
parent
258c1dd76b
commit
922d9ced71
1 changed files with 5 additions and 4 deletions
|
@ -2648,18 +2648,20 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||||
struct comedi_async *async = s->async;
|
struct comedi_async *async = s->async;
|
||||||
unsigned runflags = 0;
|
unsigned runflags = 0;
|
||||||
unsigned runflags_mask = 0;
|
unsigned runflags_mask = 0;
|
||||||
|
unsigned int events = async->events;
|
||||||
|
|
||||||
|
async->events = 0;
|
||||||
if (!comedi_is_subdevice_running(s))
|
if (!comedi_is_subdevice_running(s))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (async->events & COMEDI_CB_CANCEL_MASK)
|
if (events & COMEDI_CB_CANCEL_MASK)
|
||||||
runflags_mask |= COMEDI_SRF_RUNNING;
|
runflags_mask |= COMEDI_SRF_RUNNING;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember if an error event has occurred, so an error
|
* Remember if an error event has occurred, so an error
|
||||||
* can be returned the next time the user does a read().
|
* can be returned the next time the user does a read().
|
||||||
*/
|
*/
|
||||||
if (async->events & COMEDI_CB_ERROR_MASK) {
|
if (events & COMEDI_CB_ERROR_MASK) {
|
||||||
runflags_mask |= COMEDI_SRF_ERROR;
|
runflags_mask |= COMEDI_SRF_ERROR;
|
||||||
runflags |= COMEDI_SRF_ERROR;
|
runflags |= COMEDI_SRF_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2671,14 +2673,13 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||||
comedi_update_subdevice_runflags(s, runflags_mask, runflags);
|
comedi_update_subdevice_runflags(s, runflags_mask, runflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (async->cb_mask & async->events) {
|
if (async->cb_mask & events) {
|
||||||
wake_up_interruptible(&async->wait_head);
|
wake_up_interruptible(&async->wait_head);
|
||||||
if (s->subdev_flags & SDF_CMD_READ)
|
if (s->subdev_flags & SDF_CMD_READ)
|
||||||
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
|
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
|
||||||
if (s->subdev_flags & SDF_CMD_WRITE)
|
if (s->subdev_flags & SDF_CMD_WRITE)
|
||||||
kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
|
kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
|
||||||
}
|
}
|
||||||
async->events = 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(comedi_event);
|
EXPORT_SYMBOL_GPL(comedi_event);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue