diff options
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 152 |
1 files changed, 73 insertions, 79 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e82126407e95..c2a32cf95a82 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -370,7 +370,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev, return -ENOMEM; if (copy_from_user(aux_data, - comedi_aux_data(it.options, 0), aux_len)) { + (unsigned char __user * + )comedi_aux_data(it.options, 0), aux_len)) { vfree(aux_data); return -EFAULT; } @@ -426,7 +427,7 @@ static int do_bufconfig_ioctl(struct comedi_device *dev, if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0) return -EINVAL; - s = dev->subdevices + bc.subdevice; + s = &dev->subdevices[bc.subdevice]; async = s->async; if (!async) { @@ -539,7 +540,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, /* fill subdinfo structs */ for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; us = tmp + i; us->type = s->type; @@ -617,7 +618,7 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, if (it.subdev >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + it.subdev; + s = &dev->subdevices[it.subdev]; if (it.maxdata_list) { if (s->maxdata || !s->maxdata_list) @@ -685,7 +686,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0) return -EINVAL; - s = dev->subdevices + bi.subdevice; + s = &dev->subdevices[bi.subdevice]; if (s->lock && s->lock != file) return -EACCES; @@ -882,14 +883,12 @@ static int check_insn_config_length(struct comedi_insn *insn, /* by default we allow the insn since we don't have checks for * all possible cases yet */ default: - printk(KERN_WARNING - "comedi: no check for data length of config insn id " - "%i is implemented.\n" - " Add a check to %s in %s.\n" - " Assuming n=%i is correct.\n", data[0], __func__, - __FILE__, insn->n); + pr_warn("comedi: No check for data length of config insn id %i is implemented.\n", + data[0]); + pr_warn("comedi: Add a check to %s in %s.\n", + __func__, __FILE__); + pr_warn("comedi: Assuming n=%i is correct.\n", insn->n); return 0; - break; } return -EINVAL; } @@ -940,7 +939,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EINVAL; break; } - s = dev->subdevices + insn->subdev; + s = &dev->subdevices[insn->subdev]; if (!s->async) { DPRINTK("no async\n"); ret = -EINVAL; @@ -951,7 +950,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EAGAIN; break; } - ret = s->async->inttrig(dev, s, insn->data[0]); + ret = s->async->inttrig(dev, s, data[0]); if (ret >= 0) ret = 1; break; @@ -969,7 +968,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, ret = -EINVAL; goto out; } - s = dev->subdevices + insn->subdev; + s = &dev->subdevices[insn->subdev]; if (s->type == COMEDI_SUBD_UNUSED) { DPRINTK("%d not usable subdevice\n", insn->subdev); @@ -1133,37 +1132,37 @@ static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, } static int do_cmd_ioctl(struct comedi_device *dev, - struct comedi_cmd __user *cmd, void *file) + struct comedi_cmd __user *arg, void *file) { - struct comedi_cmd user_cmd; + struct comedi_cmd cmd; struct comedi_subdevice *s; struct comedi_async *async; int ret = 0; - unsigned int __user *chanlist_saver = NULL; + unsigned int __user *user_chanlist; - if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) { + if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = user_cmd.chanlist; + user_chanlist = (unsigned int __user *)cmd.chanlist; - if (user_cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", user_cmd.subdev); + if (cmd.subdev >= dev->n_subdevices) { + DPRINTK("%d no such subdevice\n", cmd.subdev); return -ENODEV; } - s = dev->subdevices + user_cmd.subdev; + s = &dev->subdevices[cmd.subdev]; async = s->async; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", user_cmd.subdev); + DPRINTK("%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest || !s->async) { DPRINTK("subdevice %i does not support commands\n", - user_cmd.subdev); + cmd.subdev); return -EIO; } @@ -1181,23 +1180,22 @@ static int do_cmd_ioctl(struct comedi_device *dev, s->busy = file; /* make sure channel/gain list isn't too long */ - if (user_cmd.chanlist_len > s->len_chanlist) { + if (cmd.chanlist_len > s->len_chanlist) { DPRINTK("channel/gain list too long %u > %d\n", - user_cmd.chanlist_len, s->len_chanlist); + cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; } /* make sure channel/gain list isn't too short */ - if (user_cmd.chanlist_len < 1) { + if (cmd.chanlist_len < 1) { DPRINTK("channel/gain list too short %u < 1\n", - user_cmd.chanlist_len); + cmd.chanlist_len); ret = -EINVAL; goto cleanup; } - kfree(async->cmd.chanlist); - async->cmd = user_cmd; + async->cmd = cmd; async->cmd.data = NULL; /* load channel/gain list */ async->cmd.chanlist = @@ -1208,7 +1206,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, goto cleanup; } - if (copy_from_user(async->cmd.chanlist, user_cmd.chanlist, + if (copy_from_user(async->cmd.chanlist, user_chanlist, async->cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; @@ -1228,11 +1226,11 @@ static int do_cmd_ioctl(struct comedi_device *dev, if (async->cmd.flags & TRIG_BOGUS || ret) { DPRINTK("test returned %d\n", ret); - user_cmd = async->cmd; + cmd = async->cmd; /* restore chanlist pointer before copying back */ - user_cmd.chanlist = chanlist_saver; - user_cmd.data = NULL; - if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) { + cmd.chanlist = (unsigned int __force *)user_chanlist; + cmd.data = NULL; + if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); ret = -EFAULT; goto cleanup; @@ -1285,77 +1283,77 @@ cleanup: static int do_cmdtest_ioctl(struct comedi_device *dev, struct comedi_cmd __user *arg, void *file) { - struct comedi_cmd user_cmd; + struct comedi_cmd cmd; struct comedi_subdevice *s; int ret = 0; unsigned int *chanlist = NULL; - unsigned int __user *chanlist_saver = NULL; + unsigned int __user *user_chanlist; - if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { + if (copy_from_user(&cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } /* save user's chanlist pointer so it can be restored later */ - chanlist_saver = user_cmd.chanlist; + user_chanlist = (unsigned int __user *)cmd.chanlist; - if (user_cmd.subdev >= dev->n_subdevices) { - DPRINTK("%d no such subdevice\n", user_cmd.subdev); + if (cmd.subdev >= dev->n_subdevices) { + DPRINTK("%d no such subdevice\n", cmd.subdev); return -ENODEV; } - s = dev->subdevices + user_cmd.subdev; + s = &dev->subdevices[cmd.subdev]; if (s->type == COMEDI_SUBD_UNUSED) { - DPRINTK("%d not valid subdevice\n", user_cmd.subdev); + DPRINTK("%d not valid subdevice\n", cmd.subdev); return -EIO; } if (!s->do_cmd || !s->do_cmdtest) { DPRINTK("subdevice %i does not support commands\n", - user_cmd.subdev); + cmd.subdev); return -EIO; } /* make sure channel/gain list isn't too long */ - if (user_cmd.chanlist_len > s->len_chanlist) { + if (cmd.chanlist_len > s->len_chanlist) { DPRINTK("channel/gain list too long %d > %d\n", - user_cmd.chanlist_len, s->len_chanlist); + cmd.chanlist_len, s->len_chanlist); ret = -EINVAL; goto cleanup; } /* load channel/gain list */ - if (user_cmd.chanlist) { + if (cmd.chanlist) { chanlist = - kmalloc(user_cmd.chanlist_len * sizeof(int), GFP_KERNEL); + kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL); if (!chanlist) { DPRINTK("allocation failed\n"); ret = -ENOMEM; goto cleanup; } - if (copy_from_user(chanlist, user_cmd.chanlist, - user_cmd.chanlist_len * sizeof(int))) { + if (copy_from_user(chanlist, user_chanlist, + cmd.chanlist_len * sizeof(int))) { DPRINTK("fault reading chanlist\n"); ret = -EFAULT; goto cleanup; } /* make sure each element in channel/gain list is valid */ - ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist); + ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; } - user_cmd.chanlist = chanlist; + cmd.chanlist = chanlist; } - ret = s->do_cmdtest(dev, s, &user_cmd); + ret = s->do_cmdtest(dev, s, &cmd); /* restore chanlist pointer before copying back */ - user_cmd.chanlist = chanlist_saver; + cmd.chanlist = (unsigned int __force *)user_chanlist; - if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { + if (copy_to_user(arg, &cmd, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); ret = -EFAULT; goto cleanup; @@ -1390,7 +1388,7 @@ static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; spin_lock_irqsave(&s->spin_lock, flags); if (s->busy || s->lock) @@ -1433,7 +1431,7 @@ static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->busy) return -EBUSY; @@ -1474,7 +1472,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->async == NULL) return -EINVAL; @@ -1511,7 +1509,7 @@ static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, if (arg >= dev->n_subdevices) return -EINVAL; - s = dev->subdevices + arg; + s = &dev->subdevices[arg]; if (s->lock && s->lock != file) return -EACCES; @@ -2025,7 +2023,8 @@ done: /* This function restores a subdevice to an idle state. */ -void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) +static void do_become_nonbusy(struct comedi_device *dev, + struct comedi_subdevice *s) { struct comedi_async *async = s->async; @@ -2033,9 +2032,11 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s) if (async) { comedi_reset_async_buf(async); async->inttrig = NULL; + kfree(async->cmd.chanlist); + async->cmd.chanlist = NULL; } else { - printk(KERN_ERR - "BUG: (?) do_become_nonbusy called with async=0\n"); + dev_err(dev->class_dev, + "BUG: (?) do_become_nonbusy called with async=NULL\n"); } s->busy = NULL; @@ -2140,7 +2141,7 @@ static int comedi_close(struct inode *inode, struct file *file) if (dev->subdevices) { for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->busy == file) do_cancel(dev, s); @@ -2211,14 +2212,12 @@ static int __init comedi_init(void) int i; int retval; - printk(KERN_INFO "comedi: version " COMEDI_RELEASE - " - http://www.comedi.org\n"); + pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n"); if (comedi_num_legacy_minors < 0 || comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) { - printk(KERN_ERR "comedi: error: invalid value for module " - "parameter \"comedi_num_legacy_minors\". Valid values " - "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS); + pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\". Valid values are 0 through %i.\n", + COMEDI_NUM_BOARD_MINORS); return -EINVAL; } @@ -2247,7 +2246,7 @@ static int __init comedi_init(void) } comedi_class = class_create(THIS_MODULE, "comedi"); if (IS_ERR(comedi_class)) { - printk(KERN_ERR "comedi: failed to create class"); + pr_err("comedi: failed to create class\n"); cdev_del(&comedi_cdev); unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); @@ -2295,8 +2294,7 @@ module_exit(comedi_cleanup); void comedi_error(const struct comedi_device *dev, const char *s) { - printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, - dev->driver->driver_name, s); + dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s); } EXPORT_SYMBOL(comedi_error); @@ -2364,7 +2362,7 @@ static int is_device_busy(struct comedi_device *dev) return 0; for (i = 0; i < dev->n_subdevices; i++) { - s = dev->subdevices + i; + s = &dev->subdevices[i]; if (s->busy) return 1; if (s->async && s->async->mmap_count) @@ -2420,9 +2418,7 @@ int comedi_alloc_board_minor(struct device *hardware_device) comedi_device_cleanup(info->device); kfree(info->device); kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); + pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return -EBUSY; } info->device->minor = i; @@ -2499,9 +2495,7 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, spin_unlock(&comedi_file_info_table_lock); if (i == COMEDI_NUM_MINORS) { kfree(info); - printk(KERN_ERR - "comedi: error: " - "ran out of minor numbers for board device files.\n"); + pr_err("comedi: error: ran out of minor numbers for board device files.\n"); return -EBUSY; } s->minor = i; |