diff options
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 95a418b3fa00..269284812c61 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -211,23 +211,33 @@ struct comedi_device *comedi_dev_from_minor(unsigned minor) EXPORT_SYMBOL_GPL(comedi_dev_from_minor); static struct comedi_subdevice * -comedi_read_subdevice(const struct comedi_file_info *info) +comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor) { - if (info->read_subdevice) - return info->read_subdevice; - if (info->device) - return info->device->read_subdev; - return NULL; + struct comedi_file_info *info; + + if (minor >= COMEDI_NUM_BOARD_MINORS) { + info = comedi_file_info_from_subdevice_minor(minor); + if (!info || info->device != dev) + return NULL; + if (info->read_subdevice) + return info->read_subdevice; + } + return dev->read_subdev; } static struct comedi_subdevice * -comedi_write_subdevice(const struct comedi_file_info *info) +comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor) { - if (info->write_subdevice) - return info->write_subdevice; - if (info->device) - return info->device->write_subdev; - return NULL; + struct comedi_file_info *info; + + if (minor >= COMEDI_NUM_BOARD_MINORS) { + info = comedi_file_info_from_subdevice_minor(minor); + if (!info || info->device != dev) + return NULL; + if (info->write_subdevice) + return info->write_subdevice; + } + return dev->write_subdev; } static int resize_async_buffer(struct comedi_device *dev, @@ -287,7 +297,7 @@ static ssize_t show_max_read_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); @@ -319,7 +329,7 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) s->async->max_bufsize = size; else @@ -344,7 +354,7 @@ static ssize_t show_read_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); @@ -376,7 +386,7 @@ static ssize_t store_read_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_READ) && s->async) err = resize_async_buffer(dev, s, s->async, size); else @@ -402,7 +412,7 @@ static ssize_t show_max_write_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) size = s->async->max_bufsize / 1024; mutex_unlock(&dev->mutex); @@ -434,7 +444,7 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) s->async->max_bufsize = size; else @@ -459,7 +469,7 @@ static ssize_t show_write_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) size = s->async->prealloc_bufsz / 1024; mutex_unlock(&dev->mutex); @@ -491,7 +501,7 @@ static ssize_t store_write_buffer_kb(struct device *csdev, dev = info->device; mutex_lock(&dev->mutex); - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async) err = resize_async_buffer(dev, s, s->async, size); else @@ -741,7 +751,6 @@ static int do_devinfo_ioctl(struct comedi_device *dev, struct file *file) { const unsigned minor = iminor(file_inode(file)); - struct comedi_file_info *info = comedi_file_info_from_minor(minor); struct comedi_subdevice *s; struct comedi_devinfo devinfo; @@ -753,13 +762,13 @@ static int do_devinfo_ioctl(struct comedi_device *dev, strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s) devinfo.read_subdevice = s->index; else devinfo.read_subdevice = -1; - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s) devinfo.write_subdevice = s->index; else @@ -1936,9 +1945,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } if (vma->vm_flags & VM_WRITE) - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); else - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (!s) { retval = -EINVAL; goto done; @@ -2008,7 +2017,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) goto done; } - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (s && s->async) { poll_wait(file, &s->async->wait_head, wait); if (!s->busy || !comedi_is_subdevice_running(s) || @@ -2016,7 +2025,7 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait) mask |= POLLIN | POLLRDNORM; } - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (s && s->async) { unsigned int bps = bytes_per_sample(s->async->subdevice); @@ -2051,7 +2060,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, return -ENODEV; } - s = comedi_write_subdevice(info); + s = comedi_write_subdevice(dev, minor); if (!s || !s->async) return -EIO; @@ -2146,7 +2155,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, return -ENODEV; } - s = comedi_read_subdevice(info); + s = comedi_read_subdevice(dev, minor); if (!s || !s->async) return -EIO; |