summaryrefslogtreecommitdiffstats
path: root/drivers/staging/comedi/comedi_fops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r--drivers/staging/comedi/comedi_fops.c67
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;