summaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
authorIan Abbott2013-04-04 15:59:18 +0200
committerGreg Kroah-Hartman2013-04-05 23:33:29 +0200
commitdb210da268ec537f8944ea5bc490184a6707c8a2 (patch)
tree5a5ed884253e3c9c582484a5b4c77c282ab2220e /drivers/staging/comedi/comedi_fops.c
parentstaging: comedi: remove struct comedi_file_info (diff)
downloadkernel-qcow2-linux-db210da268ec537f8944ea5bc490184a6707c8a2.tar.gz
kernel-qcow2-linux-db210da268ec537f8944ea5bc490184a6707c8a2.tar.xz
kernel-qcow2-linux-db210da268ec537f8944ea5bc490184a6707c8a2.zip
staging: comedi: add comedi_clear_board_dev()
Add local function `comedi_clear_board_dev()` as a safer alternative to `comedi_clear_board_minor()` when we already have a pointer to a `struct comedi_device`. It uses the board minor device number stored in the `struct comedi_device` (which must have already been initialized) and only clears the entry in `comedi_board_minor_table[]` if it points to the specified `struct comedi_device`. Rather than returning the old table entry, it returns `true` if the entry matched (and so has just been cleared) and returns `false` otherwise. Call `comedi_clear_board_dev()` instead of `comedi_clear_board_minor()` in `comedi_unlocked_ioctl()` (in the code that frees a dynamically allocated comedi device detached by the `COMEDI_DEVCONFIG` ioctl). That ought to return `true` but check it just in case before freeing the device. There is still a race condition here which needs to be dealt with once we've implemented reference counting for `struct comedi_device`s. 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>
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index b5e4bf1373e2..dec04b9b025e 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -120,6 +120,20 @@ static void comedi_device_cleanup(struct comedi_device *dev)
mutex_destroy(&dev->mutex);
}
+static bool comedi_clear_board_dev(struct comedi_device *dev)
+{
+ unsigned int i = dev->minor;
+ bool cleared = false;
+
+ mutex_lock(&comedi_board_minor_table_lock);
+ if (dev == comedi_board_minor_table[i]) {
+ comedi_board_minor_table[i] = NULL;
+ cleared = true;
+ }
+ mutex_unlock(&comedi_board_minor_table_lock);
+ return cleared;
+}
+
static struct comedi_device *comedi_clear_board_minor(unsigned minor)
{
struct comedi_device *dev;
@@ -1766,9 +1780,7 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
dev->minor >= comedi_num_legacy_minors) {
/* Successfully unconfigured a dynamically
* allocated device. Try and remove it. */
- struct comedi_device *devr;
- devr = comedi_clear_board_minor(dev->minor);
- if (dev == devr) {
+ if (comedi_clear_board_dev(dev)) {
mutex_unlock(&dev->mutex);
comedi_free_board_dev(dev);
return rc;