Return from `comedi_alloc_board_minor()` with the mutex of the created
`struct comedi_device` pre-locked.  This allows further initialization
by the caller without the worry of something getting in there first.

`comedi_auto_config()` no longer needs to check if the device is already
"attached" since whatever was trying to attach the device would need to
have locked the mutex first.

Signed-off-by: Ian Abbott <abbo...@mev.co.uk>
---
 drivers/staging/comedi/comedi_fops.c | 7 +++++++
 drivers/staging/comedi/drivers.c     | 6 ++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/comedi/comedi_fops.c 
b/drivers/staging/comedi/comedi_fops.c
index f9d0a72..061b55b 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2274,6 +2274,7 @@ static void comedi_device_cleanup(struct comedi_device 
*dev)
        mutex_destroy(&dev->mutex);
 }
 
+/* Note: the ->mutex is pre-locked on successful return */
 struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
 {
        struct comedi_file_info *info;
@@ -2292,6 +2293,7 @@ struct comedi_device *comedi_alloc_board_minor(struct 
device *hardware_device)
        info->device = dev;
        info->hardware_device = hardware_device;
        comedi_device_init(dev);
+       mutex_lock(&dev->mutex);
        spin_lock(&comedi_file_info_table_lock);
        for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i) {
                if (comedi_file_info_table[i] == NULL) {
@@ -2301,6 +2303,7 @@ struct comedi_device *comedi_alloc_board_minor(struct 
device *hardware_device)
        }
        spin_unlock(&comedi_file_info_table_lock);
        if (i == COMEDI_NUM_BOARD_MINORS) {
+               mutex_unlock(&dev->mutex);
                comedi_device_cleanup(dev);
                kfree(dev);
                kfree(info);
@@ -2314,6 +2317,7 @@ struct comedi_device *comedi_alloc_board_minor(struct 
device *hardware_device)
                dev->class_dev = csdev;
        dev_set_drvdata(csdev, info);
 
+       /* Note: dev->mutex needs to be unlocked by the caller. */
        return dev;
 }
 
@@ -2485,6 +2489,9 @@ static int __init comedi_init(void)
                        unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
                                                 COMEDI_NUM_MINORS);
                        return PTR_ERR(dev);
+               } else {
+                       /* comedi_alloc_board_minor() locked the mutex */
+                       mutex_unlock(&dev->mutex);
                }
        }
 
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 0b72af8..caadd3b 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -429,11 +429,9 @@ int comedi_auto_config(struct device *hardware_device,
        comedi_dev = comedi_alloc_board_minor(hardware_device);
        if (IS_ERR(comedi_dev))
                return PTR_ERR(comedi_dev);
+       /* Note: comedi_alloc_board_minor() locked comedi_dev->mutex. */
 
-       mutex_lock(&comedi_dev->mutex);
-       if (comedi_dev->attached)
-               ret = -EBUSY;
-       else if (!try_module_get(driver->module))
+       if (!try_module_get(driver->module))
                ret = -EIO;
        else {
                comedi_set_hw_dev(comedi_dev, hardware_device);
-- 
1.8.1.5

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel

Reply via email to