For COMEDI_DEVCONFIG ioctl, if argument is NULL, refuse to unconfigure the
authorIan Abbott <abbotti@mev.co.uk>
Wed, 2 Jan 2008 17:41:47 +0000 (17:41 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Wed, 2 Jan 2008 17:41:47 +0000 (17:41 +0000)
device if any subdevices are busy or have mmap'ed buffers.  The errno is
EBUSY in this case.

comedi/comedi_fops.c

index 5f593d9fd21c74857cfa3dd0d1b73a6cc0b4ccfe..181cd0320c2cc38c21ef4dba206af2dbc0e57e8b 100644 (file)
@@ -83,6 +83,8 @@ static int do_cancel(comedi_device * dev, comedi_subdevice * s);
 
 static int comedi_fasync(int fd, struct file *file, int on);
 
+static int is_device_busy(comedi_device * dev);
+
 #ifdef HAVE_UNLOCKED_IOCTL
 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
        unsigned long arg)
@@ -187,6 +189,8 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
                return -EPERM;
 
        if (arg == NULL) {
+               if (is_device_busy(dev))
+                       return -EBUSY;
                return comedi_device_detach(dev);
        }
 
@@ -2033,3 +2037,22 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice * s)
        comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
        return runflags;
 }
+
+static int is_device_busy(comedi_device * dev)
+{
+       comedi_subdevice *s;
+       int i;
+
+       if (!dev->attached)
+               return 0;
+
+       for (i = 0; i < dev->n_subdevices; i++) {
+               s = dev->subdevices + i;
+               if (s->busy)
+                       return 1;
+               if (s->async && s->async->mmap_count)
+                       return 1;
+       }
+
+       return 0;
+}