[PATCH 07/22] staging: comedi: cancel commands before detaching device

Ian Abbott abbotti at mev.co.uk
Fri Nov 8 15:03:28 UTC 2013


The comedi core module's handling of the `COMEDI_DEVCONFIG` ioctl will
not allow a device to be detached if it is busy.  However, comedi
devices can also be auto-detached due to a removal of a hardware device.
One of the things we should do in that case is cancel any asynchronous
commands that are running.  Add a new function
`comedi_device_cancel_all()` to do that and call it from
`comedi_device_detach()`.

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
 drivers/staging/comedi/comedi_fops.c     | 15 +++++++++++++++
 drivers/staging/comedi/comedi_internal.h |  1 +
 drivers/staging/comedi/drivers.c         |  1 +
 3 files changed, 17 insertions(+)

diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 9c85f01..eafa18e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -584,6 +584,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 	return ret;
 }
 
+void comedi_device_cancel_all(struct comedi_device *dev)
+{
+	struct comedi_subdevice *s;
+	int i;
+
+	if (!dev->attached)
+		return;
+
+	for (i = 0; i < dev->n_subdevices; i++) {
+		s = &dev->subdevices[i];
+		if (s->async)
+			do_cancel(dev, s);
+	}
+}
+
 static int is_device_busy(struct comedi_device *dev)
 {
 	struct comedi_subdevice *s;
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index fda1a7b..151693b 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -17,6 +17,7 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 		     unsigned long new_size);
 void comedi_buf_reset(struct comedi_async *async);
 unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
+void comedi_device_cancel_all(struct comedi_device *dev);
 
 extern unsigned int comedi_default_buf_size_kb;
 extern unsigned int comedi_default_buf_maxsize_kb;
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 1f44f29..4f72773 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -133,6 +133,7 @@ static void comedi_device_detach_cleanup(struct comedi_device *dev)
 
 void comedi_device_detach(struct comedi_device *dev)
 {
+	comedi_device_cancel_all(dev);
 	down_write(&dev->attach_lock);
 	dev->attached = false;
 	if (dev->driver)
-- 
1.8.4.2



More information about the devel mailing list