Fixed some module reference counting problems due to comedi_device_attach
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 20 Oct 2008 20:35:40 +0000 (20:35 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 20 Oct 2008 20:35:40 +0000 (20:35 +0000)
and detach assuming the caller needs them to call module_get/module_put
for them.

comedi/comedi_fops.c
comedi/drivers.c

index c1fbcb26cc1889ed0f738b26b2c9a08692bb653a..1634fdad42fcc08bcfd8886a6f1220066896cdb5 100644 (file)
@@ -193,7 +193,12 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
        if (arg == NULL) {
                if (is_device_busy(dev))
                        return -EBUSY;
-               comedi_device_detach(dev);
+               if(dev->attached)
+               {
+                       struct module *driver_module = dev->driver->module;
+                       comedi_device_detach(dev);
+                       module_put(driver_module);
+               }
                return 0;
        }
 
@@ -229,6 +234,13 @@ static int do_devconfig_ioctl(comedi_device * dev, comedi_devconfig * arg)
        }
 
        ret = comedi_device_attach(dev, &it);
+       if(ret == 0)
+       {
+               if(!try_module_get(dev->driver->module)) {
+                       comedi_device_detach(dev);
+                       return -ENOSYS;
+               }
+       }
 
        if (aux_data)
                vfree(aux_data);
@@ -1782,7 +1794,7 @@ static int comedi_open(struct inode *inode, struct file *file)
                mutex_unlock(&dev->mutex);
                return -ENODEV;
        }
-      ok:
+ok:
        __module_get(THIS_MODULE);
 
        if (dev->attached) {
@@ -2084,8 +2096,7 @@ void comedi_device_cleanup(comedi_device *dev)
 {
        if(dev == NULL) return;
        mutex_lock(&dev->mutex);
-       if (dev->attached)
-               comedi_device_detach(dev);
+       comedi_device_detach(dev);
        mutex_unlock(&dev->mutex);
        mutex_destroy(&dev->mutex);
 }
index 53987db3eaf2a2e0cc510c96b307c93ec9e0fbb7..f6636beecd946c3566ec4e94fc6ab659dbf17cfb 100644 (file)
@@ -143,6 +143,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
                dev->driver = driv;
                ret = driv->attach(dev, it);
                if (ret < 0) {
+                       module_put(dev->driver->module);
                        __comedi_device_detach(dev);
                        return ret;
                }
@@ -164,6 +165,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
 attached:
        /* do a little post-config cleanup */
        ret = postconfig(dev);
+       module_put(dev->driver->module);
        if (ret < 0) {
                __comedi_device_detach(dev);
                return ret;
@@ -175,7 +177,6 @@ attached:
        }
        smp_wmb();
        dev->attached = 1;
-       module_put(dev->driver->module);
 
        return 0;
 }