diff options
Diffstat (limited to 'drivers/staging/comedi/comedi_fops.c')
-rw-r--r-- | drivers/staging/comedi/comedi_fops.c | 242 |
1 files changed, 136 insertions, 106 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index aca96747e5e2..aced00e5cd10 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -49,7 +49,7 @@ #include <linux/io.h> #include <linux/uaccess.h> -/* #include "kvmem.h" */ +#include "internal.h" MODULE_AUTHOR("http://www.comedi.org"); MODULE_DESCRIPTION("Comedi core module"); @@ -57,13 +57,14 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; +EXPORT_SYMBOL(comedi_debug); module_param(comedi_debug, int, 0644); #endif int comedi_autoconfig = 1; module_param(comedi_autoconfig, bool, 0444); -int comedi_num_legacy_minors; +static int comedi_num_legacy_minors; module_param(comedi_num_legacy_minors, int, 0444); static DEFINE_SPINLOCK(comedi_file_info_table_lock); @@ -71,25 +72,32 @@ static struct comedi_device_file_info *comedi_file_info_table[COMEDI_NUM_MINORS]; static int do_devconfig_ioctl(struct comedi_device *dev, - struct comedi_devconfig *arg); -static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg); + struct comedi_devconfig __user *arg); +static int do_bufconfig_ioctl(struct comedi_device *dev, + struct comedi_bufconfig __user *arg); static int do_devinfo_ioctl(struct comedi_device *dev, - struct comedi_devinfo *arg, struct file *file); + struct comedi_devinfo __user *arg, + struct file *file); static int do_subdinfo_ioctl(struct comedi_device *dev, - struct comedi_subdinfo *arg, void *file); + struct comedi_subdinfo __user *arg, void *file); static int do_chaninfo_ioctl(struct comedi_device *dev, - struct comedi_chaninfo *arg); -static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg); -static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file); + struct comedi_chaninfo __user *arg); +static int do_bufinfo_ioctl(struct comedi_device *dev, + struct comedi_bufinfo __user *arg); +static int do_cmd_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file); static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file); static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file); static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file); -static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file); -static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file); -static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file); +static int do_cmdtest_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file); +static int do_insnlist_ioctl(struct comedi_device *dev, + struct comedi_insnlist __user *arg, void *file); +static int do_insn_ioctl(struct comedi_device *dev, + struct comedi_insn __user *arg, void *file); static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file); @@ -128,7 +136,8 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, /* Device config is special, because it must work on * an unconfigured device. */ if (cmd == COMEDI_DEVCONFIG) { - rc = do_devconfig_ioctl(dev, (void *)arg); + rc = do_devconfig_ioctl(dev, + (struct comedi_devconfig __user *)arg); goto done; } @@ -140,22 +149,27 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case COMEDI_BUFCONFIG: - rc = do_bufconfig_ioctl(dev, (void *)arg); + rc = do_bufconfig_ioctl(dev, + (struct comedi_bufconfig __user *)arg); break; case COMEDI_DEVINFO: - rc = do_devinfo_ioctl(dev, (void *)arg, file); + rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg, + file); break; case COMEDI_SUBDINFO: - rc = do_subdinfo_ioctl(dev, (void *)arg, file); + rc = do_subdinfo_ioctl(dev, + (struct comedi_subdinfo __user *)arg, + file); break; case COMEDI_CHANINFO: - rc = do_chaninfo_ioctl(dev, (void *)arg); + rc = do_chaninfo_ioctl(dev, (void __user *)arg); break; case COMEDI_RANGEINFO: - rc = do_rangeinfo_ioctl(dev, (void *)arg); + rc = do_rangeinfo_ioctl(dev, (void __user *)arg); break; case COMEDI_BUFINFO: - rc = do_bufinfo_ioctl(dev, (void *)arg); + rc = do_bufinfo_ioctl(dev, + (struct comedi_bufinfo __user *)arg); break; case COMEDI_LOCK: rc = do_lock_ioctl(dev, arg, file); @@ -167,16 +181,20 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, rc = do_cancel_ioctl(dev, arg, file); break; case COMEDI_CMD: - rc = do_cmd_ioctl(dev, (void *)arg, file); + rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file); break; case COMEDI_CMDTEST: - rc = do_cmdtest_ioctl(dev, (void *)arg, file); + rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg, + file); break; case COMEDI_INSNLIST: - rc = do_insnlist_ioctl(dev, (void *)arg, file); + rc = do_insnlist_ioctl(dev, + (struct comedi_insnlist __user *)arg, + file); break; case COMEDI_INSN: - rc = do_insn_ioctl(dev, (void *)arg, file); + rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg, + file); break; case COMEDI_POLL: rc = do_poll_ioctl(dev, arg, file); @@ -205,7 +223,7 @@ done: none */ static int do_devconfig_ioctl(struct comedi_device *dev, - struct comedi_devconfig *arg) + struct comedi_devconfig __user *arg) { struct comedi_devconfig it; int ret; @@ -285,7 +303,8 @@ static int do_devconfig_ioctl(struct comedi_device *dev, modified bufconfig at arg */ -static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg) +static int do_bufconfig_ioctl(struct comedi_device *dev, + struct comedi_bufconfig __user *arg) { struct comedi_bufconfig bc; struct comedi_async *async; @@ -346,7 +365,8 @@ copyback: */ static int do_devinfo_ioctl(struct comedi_device *dev, - struct comedi_devinfo *arg, struct file *file) + struct comedi_devinfo __user *arg, + struct file *file) { struct comedi_devinfo devinfo; const unsigned minor = iminor(file->f_dentry->d_inode); @@ -396,7 +416,7 @@ static int do_devinfo_ioctl(struct comedi_device *dev, */ static int do_subdinfo_ioctl(struct comedi_device *dev, - struct comedi_subdinfo *arg, void *file) + struct comedi_subdinfo __user *arg, void *file) { int ret, i; struct comedi_subdinfo *tmp, *us; @@ -478,7 +498,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, */ static int do_chaninfo_ioctl(struct comedi_device *dev, - struct comedi_chaninfo *arg) + struct comedi_chaninfo __user *arg) { struct comedi_subdevice *s; struct comedi_chaninfo it; @@ -542,7 +562,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, modified bufinfo at arg */ -static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg) +static int do_bufinfo_ioctl(struct comedi_device *dev, + struct comedi_bufinfo __user *arg) { struct comedi_bufinfo bi; struct comedi_subdevice *s; @@ -598,23 +619,24 @@ copyback: static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data, void *file); /* - * COMEDI_INSNLIST - * synchronous instructions + * COMEDI_INSNLIST + * synchronous instructions * - * arg: - * pointer to sync cmd structure + * arg: + * pointer to sync cmd structure * - * reads: - * sync cmd struct at arg - * instruction list - * data (for writes) + * reads: + * sync cmd struct at arg + * instruction list + * data (for writes) * - * writes: - * data (for reads) + * writes: + * data (for reads) */ /* arbitrary limits */ #define MAX_SAMPLES 256 -static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_insnlist_ioctl(struct comedi_device *dev, + struct comedi_insnlist __user *arg, void *file) { struct comedi_insnlist insnlist; struct comedi_insn *insns = NULL; @@ -736,7 +758,8 @@ 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("comedi: no check for data length of config insn id " + 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__, @@ -837,7 +860,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, goto out; } - ret = check_chanlist(s, 1, &insn->chanspec); + ret = comedi_check_chanlist(s, 1, &insn->chanspec); if (ret < 0) { ret = -EINVAL; DPRINTK("bad chanspec\n"); @@ -894,20 +917,21 @@ out: } /* - * COMEDI_INSN - * synchronous instructions + * COMEDI_INSN + * synchronous instructions * - * arg: - * pointer to insn + * arg: + * pointer to insn * - * reads: - * struct comedi_insn struct at arg - * data (for writes) + * reads: + * struct comedi_insn struct at arg + * data (for writes) * - * writes: - * data (for reads) + * writes: + * data (for reads) */ -static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_insn_ioctl(struct comedi_device *dev, + struct comedi_insn __user *arg, void *file) { struct comedi_insn insn; unsigned int *data = NULL; @@ -928,8 +952,9 @@ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) if (insn.n > MAX_SAMPLES) insn.n = MAX_SAMPLES; if (insn.insn & INSN_MASK_WRITE) { - if (copy_from_user - (data, insn.data, insn.n * sizeof(unsigned int))) { + if (copy_from_user(data, + insn.data, + insn.n * sizeof(unsigned int))) { ret = -EFAULT; goto error; } @@ -938,8 +963,9 @@ static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file) if (ret < 0) goto error; if (insn.insn & INSN_MASK_READ) { - if (copy_to_user - (insn.data, data, insn.n * sizeof(unsigned int))) { + if (copy_to_user(insn.data, + data, + insn.n * sizeof(unsigned int))) { ret = -EFAULT; goto error; } @@ -952,30 +978,27 @@ error: return ret; } -/* - COMEDI_CMD - command ioctl - - arg: - pointer to cmd structure - - reads: - cmd structure at arg - channel/range list +static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, + unsigned mask, unsigned bits) +{ + unsigned long flags; - writes: - modified cmd structure at arg + spin_lock_irqsave(&s->spin_lock, flags); + s->runflags &= ~mask; + s->runflags |= (bits & mask); + spin_unlock_irqrestore(&s->spin_lock, flags); +} -*/ -static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_cmd_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *cmd, void *file) { struct comedi_cmd user_cmd; struct comedi_subdevice *s; struct comedi_async *async; int ret = 0; - unsigned int *chanlist_saver = NULL; + unsigned int __user *chanlist_saver = NULL; - if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { + if (copy_from_user(&user_cmd, cmd, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); return -EFAULT; } @@ -1050,7 +1073,9 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) } /* make sure each element in channel/gain list is valid */ - ret = check_chanlist(s, async->cmd.chanlist_len, async->cmd.chanlist); + ret = comedi_check_chanlist(s, + async->cmd.chanlist_len, + async->cmd.chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; @@ -1064,7 +1089,7 @@ static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file) /* restore chanlist pointer before copying back */ user_cmd.chanlist = chanlist_saver; user_cmd.data = NULL; - if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) { + if (copy_to_user(cmd, &user_cmd, sizeof(struct comedi_cmd))) { DPRINTK("fault writing cmd\n"); ret = -EFAULT; goto cleanup; @@ -1114,13 +1139,14 @@ cleanup: modified cmd structure at arg */ -static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file) +static int do_cmdtest_ioctl(struct comedi_device *dev, + struct comedi_cmd __user *arg, void *file) { struct comedi_cmd user_cmd; struct comedi_subdevice *s; int ret = 0; unsigned int *chanlist = NULL; - unsigned int *chanlist_saver = NULL; + unsigned int __user *chanlist_saver = NULL; if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) { DPRINTK("bad cmd address\n"); @@ -1172,7 +1198,7 @@ static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file) } /* make sure each element in channel/gain list is valid */ - ret = check_chanlist(s, user_cmd.chanlist_len, chanlist); + ret = comedi_check_chanlist(s, user_cmd.chanlist_len, chanlist); if (ret < 0) { DPRINTK("bad chanlist\n"); goto cleanup; @@ -1371,7 +1397,7 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return ret; } -void comedi_unmap(struct vm_area_struct *area) +static void comedi_unmap(struct vm_area_struct *area) { struct comedi_async *async; struct comedi_device *dev; @@ -1509,8 +1535,8 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) return mask; } -static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes, - loff_t *offset) +static ssize_t comedi_write(struct file *file, const char __user *buf, + size_t nbytes, loff_t *offset) { struct comedi_subdevice *s; struct comedi_async *async; @@ -1611,7 +1637,7 @@ done: return count ? count : retval; } -static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes, +static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, loff_t *offset) { struct comedi_subdevice *s; @@ -1925,7 +1951,7 @@ static int __init comedi_init(void) } comedi_class = class_create(THIS_MODULE, "comedi"); if (IS_ERR(comedi_class)) { - printk("comedi: failed to create class"); + printk(KERN_ERR "comedi: failed to create class"); cdev_del(&comedi_cdev); unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); @@ -1971,8 +1997,10 @@ module_exit(comedi_cleanup); void comedi_error(const struct comedi_device *dev, const char *s) { - printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, s); + printk(KERN_ERR "comedi%d: %s: %s\n", dev->minor, + dev->driver->driver_name, s); } +EXPORT_SYMBOL(comedi_error); void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -2015,17 +2043,7 @@ void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s) } s->async->events = 0; } - -void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask, - unsigned bits) -{ - unsigned long flags; - - spin_lock_irqsave(&s->spin_lock, flags); - s->runflags &= ~mask; - s->runflags |= (bits & mask); - spin_unlock_irqrestore(&s->spin_lock, flags); -} +EXPORT_SYMBOL(comedi_event); unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) { @@ -2037,6 +2055,7 @@ unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s) spin_unlock_irqrestore(&s->spin_lock, flags); return runflags; } +EXPORT_SYMBOL(comedi_get_subdevice_runflags); static int is_device_busy(struct comedi_device *dev) { @@ -2057,7 +2076,7 @@ static int is_device_busy(struct comedi_device *dev) return 0; } -void comedi_device_init(struct comedi_device *dev) +static void comedi_device_init(struct comedi_device *dev) { memset(dev, 0, sizeof(struct comedi_device)); spin_lock_init(&dev->spinlock); @@ -2065,7 +2084,7 @@ void comedi_device_init(struct comedi_device *dev) dev->minor = -1; } -void comedi_device_cleanup(struct comedi_device *dev) +static void comedi_device_cleanup(struct comedi_device *dev) { if (dev == NULL) return; @@ -2105,7 +2124,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) kfree(info->device); kfree(info); printk(KERN_ERR - "comedi: error: ran out of minor numbers for board device files.\n"); + "comedi: error: " + "ran out of minor numbers for board device files.\n"); return -EBUSY; } info->device->minor = i; @@ -2118,7 +2138,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2126,7 +2147,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2134,7 +2156,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2142,7 +2165,8 @@ int comedi_alloc_board_minor(struct device *hardware_device) retval = device_create_file(csdev, &dev_attr_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name); comedi_free_board_minor(i); return retval; @@ -2201,7 +2225,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, if (i == COMEDI_NUM_MINORS) { kfree(info); printk(KERN_ERR - "comedi: error: ran out of minor numbers for board device files.\n"); + "comedi: error: " + "ran out of minor numbers for board device files.\n"); return -EBUSY; } s->minor = i; @@ -2215,7 +2240,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2223,7 +2249,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_read_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2231,7 +2258,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2239,7 +2267,8 @@ int comedi_alloc_subdevice_minor(struct comedi_device *dev, retval = device_create_file(csdev, &dev_attr_write_buffer_kb); if (retval) { printk(KERN_ERR - "comedi: failed to create sysfs attribute file \"%s\".\n", + "comedi: " + "failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name); comedi_free_subdevice_minor(s); return retval; @@ -2283,6 +2312,7 @@ struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor) spin_unlock_irqrestore(&comedi_file_info_table_lock, flags); return info; } +EXPORT_SYMBOL_GPL(comedi_get_device_file_info); static int resize_async_buffer(struct comedi_device *dev, struct comedi_subdevice *s, |