Add function `struct comedi_device *comedi_dev_get_from_minor(unsigned minor)`. This behaves like the existing `comedi_dev_from_minor()` except that it also increments the `struct kref refcount` member (via new helper function `comedi_dev_get()`) to prevent it being freed. If it returns a valid pointer, the caller is responsible for calling `comedi_dev_put()` to decrement the reference count. Export `comedi_dev_get_from_minor()` and `comedi_dev_put()` as they will be used by the "kcomedilib" module in addition to the "comedi" module itself. Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx> --- drivers/staging/comedi/comedi_fops.c | 42 ++++++++++++++++++++++++++++++++++++ drivers/staging/comedi/comedidev.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 403324c..5e5ddbd 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -111,6 +111,14 @@ int comedi_dev_put(struct comedi_device *dev) return kref_put(&dev->refcount, comedi_dev_kref_release); return 1; } +EXPORT_SYMBOL_GPL(comedi_dev_put); + +static struct comedi_device *comedi_dev_get(struct comedi_device *dev) +{ + if (dev) + kref_get(&dev->refcount); + return dev; +} static void comedi_device_cleanup(struct comedi_device *dev) { @@ -209,6 +217,40 @@ struct comedi_device *comedi_dev_from_minor(unsigned minor) } EXPORT_SYMBOL_GPL(comedi_dev_from_minor); +static struct comedi_device *comedi_dev_get_from_board_minor(unsigned minor) +{ + struct comedi_device *dev; + + BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS); + mutex_lock(&comedi_board_minor_table_lock); + dev = comedi_dev_get(comedi_board_minor_table[minor]); + mutex_unlock(&comedi_board_minor_table_lock); + return dev; +} + +static struct comedi_device *comedi_dev_get_from_subdevice_minor(unsigned minor) +{ + struct comedi_device *dev; + 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); + s = comedi_subdevice_minor_table[i]; + dev = comedi_dev_get(s ? s->device : NULL); + mutex_unlock(&comedi_subdevice_minor_table_lock); + return dev; +} + +struct comedi_device *comedi_dev_get_from_minor(unsigned minor) +{ + if (minor < COMEDI_NUM_BOARD_MINORS) + return comedi_dev_get_from_board_minor(minor); + else + return comedi_dev_get_from_subdevice_minor(minor); +} +EXPORT_SYMBOL_GPL(comedi_dev_get_from_minor); + static struct comedi_subdevice * comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) { diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h index 08652df..a9b1468 100644 --- a/drivers/staging/comedi/comedidev.h +++ b/drivers/staging/comedi/comedidev.h @@ -236,6 +236,8 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4; static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; struct comedi_device *comedi_dev_from_minor(unsigned minor); +struct comedi_device *comedi_dev_get_from_minor(unsigned minor); +int comedi_dev_put(struct comedi_device *dev); void init_polling(void); void cleanup_polling(void); -- 1.8.4.2 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel