The comedi device attribute functions such as `show_max_read_buffer_kb()` call `dev_get_drvdata()` to get a pointer to a `struct comedi_file_info` from the private driver data field of class device. Change them to use the minor device number to look up this pointer value so they behave more like the file operation functions. Check the pointer is non-NULL as the entry in the minor device table could have been set to NULL. Note that there is still a race condition in the use of this pointer value after acquiring the mutex which needs to be dealt with once reference counting has been implemented for comedi devices. The calls to `dev_set_drvdata()` from `comedi_alloc_board_minor()` and `comedi_alloc_subdevice_minor()` are no longer needed so remove them. Signed-off-by: Ian Abbott <abbotti@xxxxxxxxx> --- drivers/staging/comedi/comedi_fops.c | 58 +++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index d06b13a..95a418b 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -275,11 +275,16 @@ static int resize_async_buffer(struct comedi_device *dev, static ssize_t show_max_read_buffer_kb(struct device *csdev, struct device_attribute *attr, char *buf) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size = 0; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_read_subdevice(info); @@ -294,7 +299,8 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev, struct device_attribute *attr, const char *buf, size_t count) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size; @@ -307,6 +313,10 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev, return -EINVAL; size *= 1024; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_read_subdevice(info); @@ -322,11 +332,16 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev, static ssize_t show_read_buffer_kb(struct device *csdev, struct device_attribute *attr, char *buf) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size = 0; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_read_subdevice(info); @@ -341,7 +356,8 @@ static ssize_t store_read_buffer_kb(struct device *csdev, struct device_attribute *attr, const char *buf, size_t count) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size; @@ -354,6 +370,10 @@ static ssize_t store_read_buffer_kb(struct device *csdev, return -EINVAL; size *= 1024; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_read_subdevice(info); @@ -370,11 +390,16 @@ static ssize_t show_max_write_buffer_kb(struct device *csdev, struct device_attribute *attr, char *buf) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size = 0; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_write_subdevice(info); @@ -389,7 +414,8 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev, struct device_attribute *attr, const char *buf, size_t count) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size; @@ -402,6 +428,10 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev, return -EINVAL; size *= 1024; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_write_subdevice(info); @@ -417,11 +447,16 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev, static ssize_t show_write_buffer_kb(struct device *csdev, struct device_attribute *attr, char *buf) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size = 0; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_write_subdevice(info); @@ -436,7 +471,8 @@ static ssize_t store_write_buffer_kb(struct device *csdev, struct device_attribute *attr, const char *buf, size_t count) { - struct comedi_file_info *info = dev_get_drvdata(csdev); + unsigned int minor = MINOR(csdev->devt); + struct comedi_file_info *info; struct comedi_device *dev; struct comedi_subdevice *s; unsigned int size; @@ -449,6 +485,10 @@ static ssize_t store_write_buffer_kb(struct device *csdev, return -EINVAL; size *= 1024; + info = comedi_file_info_from_minor(minor); + if (!info) + return -ENODEV; + dev = info->device; mutex_lock(&dev->mutex); s = comedi_write_subdevice(info); @@ -2416,7 +2456,6 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i); if (!IS_ERR(csdev)) dev->class_dev = csdev; - dev_set_drvdata(csdev, info); /* Note: dev->mutex needs to be unlocked by the caller. */ return dev; @@ -2482,7 +2521,6 @@ int comedi_alloc_subdevice_minor(struct comedi_subdevice *s) dev->minor, s->index); if (!IS_ERR(csdev)) s->class_dev = csdev; - dev_set_drvdata(csdev, info); return 0; } -- 1.8.1.5 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/devel