]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.4.56/staging-comedi-comedi_cancel-ioctl-should-wake-up-read-write.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.4.56 / staging-comedi-comedi_cancel-ioctl-should-wake-up-read-write.patch
1 From 69acbaac303e8cb948801a9ddd0ac24e86cc4a1b Mon Sep 17 00:00:00 2001
2 From: Ian Abbott <abbotti@mev.co.uk>
3 Date: Mon, 8 Jul 2013 13:36:19 +0100
4 Subject: staging: comedi: COMEDI_CANCEL ioctl should wake up read/write
5
6 From: Ian Abbott <abbotti@mev.co.uk>
7
8 commit 69acbaac303e8cb948801a9ddd0ac24e86cc4a1b upstream.
9
10 Comedi devices can do blocking read() or write() (or poll()) if an
11 asynchronous command has been set up, blocking for data (for read()) or
12 buffer space (for write()). Various events associated with the
13 asynchronous command will wake up the blocked reader or writer (or
14 poller). It is also possible to force the asynchronous command to
15 terminate by issuing a `COMEDI_CANCEL` ioctl. That shuts down the
16 asynchronous command, but does not currently wake up the blocked reader
17 or writer (or poller). If the blocked task could be woken up, it would
18 see that the command is no longer active and return. The caller of the
19 `COMEDI_CANCEL` ioctl could attempt to wake up the blocked task by
20 sending a signal, but that's a nasty workaround.
21
22 Change `do_cancel_ioctl()` to wake up the wait queue after it returns
23 from `do_cancel()`. `do_cancel()` can propagate an error return value
24 from the low-level comedi driver's cancel routine, but it always shuts
25 the command down regardless, so `do_cancel_ioctl()` can wake up he wait
26 queue regardless of the return value from `do_cancel()`.
27
28 Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
29 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
30
31 ---
32 drivers/staging/comedi/comedi_fops.c | 7 ++++++-
33 1 file changed, 6 insertions(+), 1 deletion(-)
34
35 --- a/drivers/staging/comedi/comedi_fops.c
36 +++ b/drivers/staging/comedi/comedi_fops.c
37 @@ -1370,6 +1370,7 @@ static int do_cancel_ioctl(struct comedi
38 void *file)
39 {
40 struct comedi_subdevice *s;
41 + int ret;
42
43 if (arg >= dev->n_subdevices)
44 return -EINVAL;
45 @@ -1386,7 +1387,11 @@ static int do_cancel_ioctl(struct comedi
46 if (s->busy != file)
47 return -EBUSY;
48
49 - return do_cancel(dev, s);
50 + ret = do_cancel(dev, s);
51 + if (comedi_get_subdevice_runflags(s) & SRF_USER)
52 + wake_up_interruptible(&s->async->wait_head);
53 +
54 + return ret;
55 }
56
57 /*