]> git.karo-electronics.de Git - linux-beck.git/commitdiff
staging: comedi: simplify comedi_subdevice_minor_table[]
authorIan Abbott <abbotti@mev.co.uk>
Thu, 4 Apr 2013 13:59:15 +0000 (14:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 5 Apr 2013 21:33:21 +0000 (14:33 -0700)
`comedi_alloc_subdevice_minor()` allocates and initializes a `struct
comedi_file_info` and assigns a subdevice minor device number (if there
are any available), storing a pointer to the allocated `struct
comedi_file_info` in `comedi_subdevice_minor_table[i]` where `i` is the
array index corresponding to the subdevice minor device number (indexed
by subdevice minor device number minus `COMEDI_NUM_BOARD_MINORS`).

The information stored in the `struct comedi_file_info` can be derived
from the subdevice structure (`struct comedi_subdevice`) itself, so the
`struct comedi_file_info` is superfluous.

Change `comedi_subdevice_minor_table[]` to hold pointers to the actual
`struct comedi_subdevice`'s.  `comedi_alloc_subdevice_minor()` no longer
needs to allocate a `struct comedi_file_info` and
`comedi_free_subdevice_info()` no longer has a `struct comedi_file_info`
to free.

Replace `comedi_file_info_from_minor()` with
`comedi_subdevice_from_minor()`, returning a (possibly NULL) pointer to
a `struct comedi_subdevice` from the table.  This has knock-on effects
for `comedi_dev_from_subdevice_minor()`, `comedi_read_subdevice()` and
`comedi_write_subdevice()`.  In particular, `comedi_read_subdevice()`
and `comedi_write_subdevice()` now need to check the subdevice flags to
see if the determine whether to override the comedi device's default
read/write subdevice.

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>
drivers/staging/comedi/comedi_fops.c

index 71156bdfcdc8a6fe851751c3b13d8edeb1e5bbbd..4e4ccc2f59b878d10982138b401f2878d4827496 100644 (file)
@@ -93,7 +93,7 @@ static struct comedi_file_info
 
 static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
 /* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
-static struct comedi_file_info
+static struct comedi_subdevice
 *comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
 
 static struct class *comedi_class;
@@ -153,17 +153,17 @@ static void comedi_free_board_file_info(struct comedi_file_info *info)
        }
 }
 
-static struct comedi_file_info
-*comedi_file_info_from_subdevice_minor(unsigned minor)
+static struct comedi_subdevice
+*comedi_subdevice_from_minor(unsigned minor)
 {
-       struct comedi_file_info *info;
+       struct comedi_subdevice *s;
        unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
 
        BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
        mutex_lock(&comedi_subdevice_minor_table_lock);
-       info = comedi_subdevice_minor_table[i];
+       s = comedi_subdevice_minor_table[i];
        mutex_unlock(&comedi_subdevice_minor_table_lock);
-       return info;
+       return s;
 }
 
 static struct comedi_device *
@@ -185,10 +185,10 @@ static struct comedi_device *comedi_dev_from_board_minor(unsigned minor)
 
 static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
 {
-       struct comedi_file_info *info;
+       struct comedi_subdevice *s;
 
-       info = comedi_file_info_from_subdevice_minor(minor);
-       return comedi_dev_from_file_info(info);
+       s = comedi_subdevice_from_minor(minor);
+       return s ? s->device : NULL;
 }
 
 struct comedi_device *comedi_dev_from_minor(unsigned minor)
@@ -203,14 +203,14 @@ EXPORT_SYMBOL_GPL(comedi_dev_from_minor);
 static struct comedi_subdevice *
 comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
 {
-       struct comedi_file_info *info;
+       struct comedi_subdevice *s;
 
        if (minor >= COMEDI_NUM_BOARD_MINORS) {
-               info = comedi_file_info_from_subdevice_minor(minor);
-               if (!info || info->device != dev)
+               s = comedi_subdevice_from_minor(minor);
+               if (!s || s->device != dev)
                        return NULL;
-               if (info->read_subdevice)
-                       return info->read_subdevice;
+               if (s->subdev_flags & SDF_CMD_READ)
+                       return s;
        }
        return dev->read_subdev;
 }
@@ -218,14 +218,14 @@ comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
 static struct comedi_subdevice *
 comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
 {
-       struct comedi_file_info *info;
+       struct comedi_subdevice *s;
 
        if (minor >= COMEDI_NUM_BOARD_MINORS) {
-               info = comedi_file_info_from_subdevice_minor(minor);
-               if (!info || info->device != dev)
+               s = comedi_subdevice_from_minor(minor);
+               if (!s || s->device != dev)
                        return NULL;
-               if (info->write_subdevice)
-                       return info->write_subdevice;
+               if (s->subdev_flags & SDF_CMD_WRITE)
+                       return s;
        }
        return dev->write_subdev;
 }
@@ -2468,28 +2468,18 @@ void comedi_release_hardware_device(struct device *hardware_device)
 int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
 {
        struct comedi_device *dev = s->device;
-       struct comedi_file_info *info;
        struct device *csdev;
        unsigned i;
 
-       info = kzalloc(sizeof(*info), GFP_KERNEL);
-       if (!info)
-               return -ENOMEM;
-       info->device = dev;
-       if (s->subdev_flags & SDF_CMD_READ)
-               info->read_subdevice = s;
-       if (s->subdev_flags & SDF_CMD_WRITE)
-               info->write_subdevice = s;
        mutex_lock(&comedi_subdevice_minor_table_lock);
        for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
                if (comedi_subdevice_minor_table[i] == NULL) {
-                       comedi_subdevice_minor_table[i] = info;
+                       comedi_subdevice_minor_table[i] = s;
                        break;
                }
        }
        mutex_unlock(&comedi_subdevice_minor_table_lock);
        if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
-               kfree(info);
                pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
                return -EBUSY;
        }
@@ -2506,7 +2496,6 @@ int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
 
 void comedi_free_subdevice_minor(struct comedi_subdevice *s)
 {
-       struct comedi_file_info *info;
        unsigned int i;
 
        if (s == NULL)
@@ -2519,14 +2508,13 @@ void comedi_free_subdevice_minor(struct comedi_subdevice *s)
 
        i = s->minor - COMEDI_NUM_BOARD_MINORS;
        mutex_lock(&comedi_subdevice_minor_table_lock);
-       info = comedi_subdevice_minor_table[i];
-       comedi_subdevice_minor_table[i] = NULL;
+       if (s == comedi_subdevice_minor_table[i])
+               comedi_subdevice_minor_table[i] = NULL;
        mutex_unlock(&comedi_subdevice_minor_table_lock);
        if (s->class_dev) {
                device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
                s->class_dev = NULL;
        }
-       kfree(info);
 }
 
 static void comedi_cleanup_board_minors(void)