diff options
author | Ian Abbott | 2013-04-04 15:58:51 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2013-04-05 23:33:17 +0200 |
commit | 07778393d9a8dbc4b9306d20a8ecfe053771ba93 (patch) | |
tree | 85dfeee58a70d808b837a30e5112ccdaa7fe2b82 | |
parent | staging: comedi: change comedi_alloc_board_minor() to return pointer (diff) | |
download | kernel-qcow2-linux-07778393d9a8dbc4b9306d20a8ecfe053771ba93.tar.gz kernel-qcow2-linux-07778393d9a8dbc4b9306d20a8ecfe053771ba93.tar.xz kernel-qcow2-linux-07778393d9a8dbc4b9306d20a8ecfe053771ba93.zip |
staging: comedi: pre-lock mutex on creation of comedi device
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@mev.co.uk>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 7 | ||||
-rw-r--r-- | 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 f9d0a7242474..061b55b48383 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 0b72af8c4480..caadd3bd72ac 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); |