]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/staging/comedi/comedi_fops.c
Staging: comedi: For COMEDI_BUFINFO, check access to command
[net-next-2.6.git] / drivers / staging / comedi / comedi_fops.c
index aca96747e5e2da1a24964f6bb5789aec1ad9b47b..aeb2c00875cd2110117afae796edb95748134e39 100644 (file)
@@ -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, void *file);
+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,28 @@ 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,
+                                     file);
                break;
        case COMEDI_LOCK:
                rc = do_lock_ioctl(dev, arg, file);
@@ -167,16 +182,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 +224,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 +304,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 +366,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 +417,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 +499,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 +563,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, void *file)
 {
        struct comedi_bufinfo bi;
        struct comedi_subdevice *s;
@@ -555,6 +577,10 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
                return -EINVAL;
 
        s = dev->subdevices + bi.subdevice;
+
+       if (s->lock && s->lock != file)
+               return -EACCES;
+
        async = s->async;
 
        if (!async) {
@@ -563,8 +589,17 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
                bi.buf_read_ptr = 0;
                bi.buf_write_count = 0;
                bi.buf_read_count = 0;
+               bi.bytes_read = 0;
+               bi.bytes_written = 0;
                goto copyback;
        }
+       if (!s->busy) {
+               bi.bytes_read = 0;
+               bi.bytes_written = 0;
+               goto copyback_position;
+       }
+       if (s->busy != file)
+               return -EACCES;
 
        if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
                bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
@@ -583,6 +618,7 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
                comedi_buf_write_free(async, bi.bytes_written);
        }
 
+copyback_position:
        bi.buf_write_count = async->buf_write_count;
        bi.buf_write_ptr = async->buf_write_ptr;
        bi.buf_read_count = async->buf_read_count;
@@ -598,23 +634,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 +773,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 +875,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 +932,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 +967,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 +978,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 +993,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 +1088,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 +1104,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 +1154,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 +1213,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 +1412,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 +1550,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;
@@ -1550,6 +1591,19 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
        while (nbytes > 0 && !retval) {
                set_current_state(TASK_INTERRUPTIBLE);
 
+               if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
+                       if (count == 0) {
+                               if (comedi_get_subdevice_runflags(s) &
+                                       SRF_ERROR) {
+                                       retval = -EPIPE;
+                               } else {
+                                       retval = 0;
+                               }
+                               do_become_nonbusy(dev, s);
+                       }
+                       break;
+               }
+
                n = nbytes;
 
                m = n;
@@ -1562,16 +1616,6 @@ static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
                        n = m;
 
                if (n == 0) {
-                       if (!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)) {
-                               if (comedi_get_subdevice_runflags(s) &
-                                   SRF_ERROR) {
-                                       retval = -EPIPE;
-                               } else {
-                                       retval = 0;
-                               }
-                               do_become_nonbusy(dev, s);
-                               break;
-                       }
                        if (file->f_flags & O_NONBLOCK) {
                                retval = -EAGAIN;
                                break;
@@ -1611,7 +1655,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 +1969,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 +2015,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 +2061,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 +2073,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 +2094,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 +2102,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 +2142,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 +2156,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 +2165,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 +2174,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 +2183,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 +2243,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 +2258,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 +2267,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 +2276,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 +2285,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 +2330,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,