staging: comedi: wake up async waiters when become non-busy
authorIan Abbott <abbotti@mev.co.uk>
Fri, 8 Nov 2013 15:03:27 +0000 (15:03 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Nov 2013 00:16:44 +0000 (16:16 -0800)
Wake up all waiters on the comedi subdevice's async wait queue whenever
the subdevice is marked "non-busy".  This happens when an asynchronous
command is cancelled or when a command is terminated and all data has
been read or written.  Note: use `wake_up_interruptible_all()` as we
only use interruptible waits.

Remove the call to `wake_up_interruptible()` from `do_cancel_ioctl()` as
it will call `wake_up_interruptible_all()` indirectly via `do_cancel()`
and `do_become_nonbusy()`.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/comedi_fops.c

index a1705ed0b844f5ef613be5cd63a8c1fb66be3fb8..9c85f01e847bc244ec5c6755bf45c9c9765fb2ae 100644 (file)
@@ -563,12 +563,13 @@ static void do_become_nonbusy(struct comedi_device *dev,
                async->inttrig = NULL;
                kfree(async->cmd.chanlist);
                async->cmd.chanlist = NULL;
+               s->busy = NULL;
+               wake_up_interruptible_all(&s->async->wait_head);
        } else {
                dev_err(dev->class_dev,
                        "BUG: (?) do_become_nonbusy called with async=NULL\n");
+               s->busy = NULL;
        }
-
-       s->busy = NULL;
 }
 
 static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
@@ -1700,7 +1701,6 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
                return -EBUSY;
 
        ret = do_cancel(dev, s);
-       wake_up_interruptible(&s->async->wait_head);
 
        return ret;
 }