[PATCH 10/37] staging: comedi: pre-lock mutex on creation of comedi device

Ian Abbott abbotti at mev.co.uk
Thu Apr 4 13:58:51 UTC 2013


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 <abbotti at 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




More information about the devel mailing list