]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/staging/comedi/comedi_fops.c
Staging: comedi: Remove comedi_devconfig typedef
[linux-2.6-omap-h63xx.git] / drivers / staging / comedi / comedi_fops.c
index 018c964396dfdd941e66070393b1bdfe059b6341..0e9ad62c6ec9680736f606aaeb79955234a6ab05 100644 (file)
@@ -59,33 +59,39 @@ int comedi_debug;
 module_param(comedi_debug, int, 0644);
 #endif
 
+int comedi_autoconfig = 1;
+module_param(comedi_autoconfig, bool, 0444);
+
+int comedi_num_legacy_minors = 0;
+module_param(comedi_num_legacy_minors, int, 0444);
+
 static DEFINE_SPINLOCK(comedi_file_info_table_lock);
 static struct comedi_device_file_info
     *comedi_file_info_table[COMEDI_NUM_MINORS];
 
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg);
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg);
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
                            struct file *file);
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
                             void *file);
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
-
-extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
-static int do_cancel(comedi_device *dev, comedi_subdevice *s);
+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);
+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_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file);
+
+extern void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s);
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
 
 static int comedi_fasync(int fd, struct file *file, int on);
 
-static int is_device_busy(comedi_device *dev);
+static int is_device_busy(struct comedi_device *dev);
 
 #ifdef HAVE_UNLOCKED_IOCTL
 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
@@ -98,9 +104,13 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
+       struct comedi_device *dev;
        int rc;
 
+       if (dev_file_info == NULL || dev_file_info->device == NULL)
+               return -ENODEV;
+       dev = dev_file_info->device;
+
        mutex_lock(&dev->mutex);
 
        /* Device config is special, because it must work on
@@ -182,9 +192,9 @@ done:
        writes:
                none
 */
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
 {
-       comedi_devconfig it;
+       struct comedi_devconfig it;
        int ret;
        unsigned char *aux_data = NULL;
        int aux_len;
@@ -203,7 +213,7 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
                return 0;
        }
 
-       if (copy_from_user(&it, arg, sizeof(comedi_devconfig)))
+       if (copy_from_user(&it, arg, sizeof(struct comedi_devconfig)))
                return -EFAULT;
 
        it.board_name[COMEDI_NAMELEN - 1] = 0;
@@ -262,11 +272,11 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
                modified bufconfig at arg
 
 */
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
 {
        comedi_bufconfig bc;
-       comedi_async *async;
-       comedi_subdevice *s;
+       struct comedi_async *async;
+       struct comedi_subdevice *s;
        int ret = 0;
 
        if (copy_from_user(&bc, arg, sizeof(comedi_bufconfig)))
@@ -350,16 +360,16 @@ copyback:
                devinfo structure
 
 */
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
                            struct file *file)
 {
-       comedi_devinfo devinfo;
+       struct comedi_devinfo devinfo;
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_subdevice *read_subdev =
+       struct comedi_subdevice *read_subdev =
            comedi_get_read_subdevice(dev_file_info);
-       comedi_subdevice *write_subdev =
+       struct comedi_subdevice *write_subdev =
            comedi_get_write_subdevice(dev_file_info);
 
        memset(&devinfo, 0, sizeof(devinfo));
@@ -380,7 +390,7 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
        else
                devinfo.write_subdevice = -1;
 
-       if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
+       if (copy_to_user(arg, &devinfo, sizeof(struct comedi_devinfo)))
                return -EFAULT;
 
        return 0;
@@ -400,14 +410,14 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
                array of subdevice info structures at arg
 
 */
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
                             void *file)
 {
        int ret, i;
-       comedi_subdinfo *tmp, *us;
-       comedi_subdevice *s;
+       struct comedi_subdinfo *tmp, *us;
+       struct comedi_subdevice *s;
 
-       tmp = kcalloc(dev->n_subdevices, sizeof(comedi_subdinfo), GFP_KERNEL);
+       tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
        if (!tmp)
                return -ENOMEM;
 
@@ -459,7 +469,7 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
        }
 
        ret = copy_to_user(arg, tmp,
-                          dev->n_subdevices * sizeof(comedi_subdinfo));
+                          dev->n_subdevices * sizeof(struct comedi_subdinfo));
 
        kfree(tmp);
 
@@ -480,12 +490,12 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
                arrays at elements of chaninfo structure
 
 */
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
 {
-       comedi_subdevice *s;
-       comedi_chaninfo it;
+       struct comedi_subdevice *s;
+       struct comedi_chaninfo it;
 
-       if (copy_from_user(&it, arg, sizeof(comedi_chaninfo)))
+       if (copy_from_user(&it, arg, sizeof(struct comedi_chaninfo)))
                return -EFAULT;
 
        if (it.subdev >= dev->n_subdevices)
@@ -496,7 +506,7 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
                if (s->maxdata || !s->maxdata_list)
                        return -EINVAL;
                if (copy_to_user(it.maxdata_list, s->maxdata_list,
-                                s->n_chan * sizeof(lsampl_t)))
+                                s->n_chan * sizeof(unsigned int)))
                        return -EFAULT;
        }
 
@@ -544,11 +554,11 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
     modified bufinfo at arg
 
   */
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
 {
        comedi_bufinfo bi;
-       comedi_subdevice *s;
-       comedi_async *async;
+       struct comedi_subdevice *s;
+       struct comedi_async *async;
 
        if (copy_from_user(&bi, arg, sizeof(comedi_bufinfo)))
                return -EFAULT;
@@ -597,7 +607,7 @@ copyback:
        return 0;
 }
 
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
                      void *file);
 /*
  *     COMEDI_INSNLIST
@@ -616,25 +626,25 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
  */
 /* arbitrary limits */
 #define MAX_SAMPLES 256
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-       comedi_insnlist insnlist;
-       comedi_insn *insns = NULL;
-       lsampl_t *data = NULL;
+       struct comedi_insnlist insnlist;
+       struct comedi_insn *insns = NULL;
+       unsigned int *data = NULL;
        int i = 0;
        int ret = 0;
 
-       if (copy_from_user(&insnlist, arg, sizeof(comedi_insnlist)))
+       if (copy_from_user(&insnlist, arg, sizeof(struct comedi_insnlist)))
                return -EFAULT;
 
-       data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+       data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
        if (!data) {
                DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
                goto error;
        }
 
-       insns = kmalloc(sizeof(comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+       insns = kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
        if (!insns) {
                DPRINTK("kmalloc failed\n");
                ret = -ENOMEM;
@@ -642,7 +652,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
        }
 
        if (copy_from_user(insns, insnlist.insns,
-                          sizeof(comedi_insn) * insnlist.n_insns)) {
+                          sizeof(struct comedi_insn) * insnlist.n_insns)) {
                DPRINTK("copy_from_user failed\n");
                ret = -EFAULT;
                goto error;
@@ -656,7 +666,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
                }
                if (insns[i].insn & INSN_MASK_WRITE) {
                        if (copy_from_user(data, insns[i].data,
-                                          insns[i].n * sizeof(lsampl_t))) {
+                                          insns[i].n * sizeof(unsigned int))) {
                                DPRINTK("copy_from_user failed\n");
                                ret = -EFAULT;
                                goto error;
@@ -667,7 +677,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
                        goto error;
                if (insns[i].insn & INSN_MASK_READ) {
                        if (copy_to_user(insns[i].data, data,
-                                        insns[i].n * sizeof(lsampl_t))) {
+                                        insns[i].n * sizeof(unsigned int))) {
                                DPRINTK("copy_to_user failed\n");
                                ret = -EFAULT;
                                goto error;
@@ -686,7 +696,7 @@ error:
        return i;
 }
 
-static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
+static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
 {
        if (insn->n < 1)
                return -EINVAL;
@@ -747,10 +757,10 @@ static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
        return -EINVAL;
 }
 
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
                      void *file)
 {
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
        int ret = 0;
        int i;
 
@@ -815,7 +825,7 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
                }
        } else {
                /* a subdevice instruction */
-               lsampl_t maxdata;
+               unsigned int maxdata;
 
                if (insn->subdev >= dev->n_subdevices) {
                        DPRINTK("subdevice %d out of range\n", insn->subdev);
@@ -901,25 +911,25 @@ out:
  *             pointer to insn
  *
  *     reads:
- *             comedi_insn struct at arg
+ *             struct comedi_insn struct at arg
  *             data (for writes)
  *
  *     writes:
  *             data (for reads)
  */
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-       comedi_insn insn;
-       lsampl_t *data = NULL;
+       struct comedi_insn insn;
+       unsigned int *data = NULL;
        int ret = 0;
 
-       data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+       data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
        if (!data) {
                ret = -ENOMEM;
                goto error;
        }
 
-       if (copy_from_user(&insn, arg, sizeof(comedi_insn))) {
+       if (copy_from_user(&insn, arg, sizeof(struct comedi_insn))) {
                ret = -EFAULT;
                goto error;
        }
@@ -928,7 +938,7 @@ static int do_insn_ioctl(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(lsampl_t))) {
+               if (copy_from_user(data, insn.data, insn.n * sizeof(unsigned int))) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -937,7 +947,7 @@ static int do_insn_ioctl(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(lsampl_t))) {
+               if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
                        ret = -EFAULT;
                        goto error;
                }
@@ -965,15 +975,15 @@ error:
                modified cmd structure at arg
 
 */
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-       comedi_cmd user_cmd;
-       comedi_subdevice *s;
-       comedi_async *async;
+       struct comedi_cmd user_cmd;
+       struct comedi_subdevice *s;
+       struct comedi_async *async;
        int ret = 0;
        unsigned int *chanlist_saver = NULL;
 
-       if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+       if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                return -EFAULT;
        }
@@ -1062,7 +1072,7 @@ static int do_cmd_ioctl(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(comedi_cmd))) {
+               if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
                        DPRINTK("fault writing cmd\n");
                        ret = -EFAULT;
                        goto cleanup;
@@ -1119,15 +1129,15 @@ cleanup:
                modified cmd structure at arg
 
 */
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file)
 {
-       comedi_cmd user_cmd;
-       comedi_subdevice *s;
+       struct comedi_cmd user_cmd;
+       struct comedi_subdevice *s;
        int ret = 0;
        unsigned int *chanlist = NULL;
        unsigned int *chanlist_saver = NULL;
 
-       if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+       if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                return -EFAULT;
        }
@@ -1191,7 +1201,7 @@ static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
        /* restore chanlist pointer before copying back */
        user_cmd.chanlist = chanlist_saver;
 
-       if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+       if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
                DPRINTK("bad cmd address\n");
                ret = -EFAULT;
                goto cleanup;
@@ -1217,11 +1227,11 @@ cleanup:
 
 */
 
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
        int ret = 0;
        unsigned long flags;
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        if (arg >= dev->n_subdevices)
                return -EINVAL;
@@ -1261,9 +1271,9 @@ static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
        This function isn't protected by the semaphore, since
        we already own the lock.
 */
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        if (arg >= dev->n_subdevices)
                return -EINVAL;
@@ -1301,9 +1311,9 @@ static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
                nothing
 
 */
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        if (arg >= dev->n_subdevices)
                return -EINVAL;
@@ -1337,9 +1347,9 @@ static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
                nothing
 
 */
-static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
 {
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        if (arg >= dev->n_subdevices)
                return -EINVAL;
@@ -1360,7 +1370,7 @@ static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
        return -EINVAL;
 }
 
-static int do_cancel(comedi_device *dev, comedi_subdevice *s)
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        int ret = 0;
 
@@ -1374,8 +1384,8 @@ static int do_cancel(comedi_device *dev, comedi_subdevice *s)
 
 void comedi_unmap(struct vm_area_struct *area)
 {
-       comedi_async *async;
-       comedi_device *dev;
+       struct comedi_async *async;
+       struct comedi_device *dev;
 
        async = area->vm_private_data;
        dev = async->subdevice->device;
@@ -1394,14 +1404,14 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
-       comedi_async *async = NULL;
+       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_async *async = NULL;
        unsigned long start = vma->vm_start;
        unsigned long size;
        int n_pages;
        int i;
        int retval;
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1470,9 +1480,9 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
-       comedi_subdevice *read_subdev;
-       comedi_subdevice *write_subdev;
+       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_subdevice *read_subdev;
+       struct comedi_subdevice *write_subdev;
 
        mutex_lock(&dev->mutex);
        if (!dev->attached) {
@@ -1513,14 +1523,14 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
 static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
                            loff_t *offset)
 {
-       comedi_subdevice *s;
-       comedi_async *async;
+       struct comedi_subdevice *s;
+       struct comedi_async *async;
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
+       struct comedi_device *dev = dev_file_info->device;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1615,14 +1625,14 @@ done:
 static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
                           loff_t *offset)
 {
-       comedi_subdevice *s;
-       comedi_async *async;
+       struct comedi_subdevice *s;
+       struct comedi_async *async;
        int n, m, count = 0, retval = 0;
        DECLARE_WAITQUEUE(wait, current);
        const unsigned minor = iminor(file->f_dentry->d_inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
+       struct comedi_device *dev = dev_file_info->device;
 
        if (!dev->attached) {
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1723,9 +1733,9 @@ done:
 /*
    This function restores a subdevice to an idle state.
  */
-void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
+void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-       comedi_async *async = s->async;
+       struct comedi_async *async = s->async;
 
        comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
 #ifdef CONFIG_COMEDI_RT
@@ -1747,11 +1757,11 @@ void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
 
 static int comedi_open(struct inode *inode, struct file *file)
 {
-       char mod[32];
        const unsigned minor = iminor(inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
+       struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
+
        if (dev == NULL) {
                DPRINTK("invalid minor number\n");
                return -ENODEV;
@@ -1783,10 +1793,9 @@ static int comedi_open(struct inode *inode, struct file *file)
 
        dev->in_request_module = 1;
 
-       sprintf(mod, "char-major-%i-%i", COMEDI_MAJOR, dev->minor);
 #ifdef CONFIG_KMOD
        mutex_unlock(&dev->mutex);
-       request_module(mod);
+       request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
        mutex_lock(&dev->mutex);
 #endif
 
@@ -1823,8 +1832,8 @@ static int comedi_close(struct inode *inode, struct file *file)
        const unsigned minor = iminor(inode);
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
-       comedi_device *dev = dev_file_info->device;
-       comedi_subdevice *s = NULL;
+       struct comedi_device *dev = dev_file_info->device;
+       struct comedi_subdevice *s = NULL;
        int i;
 
        mutex_lock(&dev->mutex);
@@ -1862,7 +1871,7 @@ static int comedi_fasync(int fd, struct file *file, int on)
        struct comedi_device_file_info *dev_file_info =
            comedi_get_device_file_info(minor);
 
-       comedi_device *dev = dev_file_info->device;
+       struct comedi_device *dev = dev_file_info->device;
 
        return fasync_helper(fd, file, on, &dev->async_queue);
 }
@@ -1893,7 +1902,7 @@ static void comedi_cleanup_legacy_minors(void)
 {
        unsigned i;
 
-       for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
+       for (i = 0; i < comedi_num_legacy_minors; i++)
                comedi_free_board_minor(i);
 }
 
@@ -1905,6 +1914,22 @@ static int __init comedi_init(void)
        printk(KERN_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);
+               return -EINVAL;
+       }
+
+       /*
+        * comedi is unusable if both comedi_autoconfig and
+        * comedi_num_legacy_minors are zero, so we might as well adjust the
+        * defaults in that case
+        */
+       if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
+               comedi_num_legacy_minors = 16;
+
        memset(comedi_file_info_table, 0,
               sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
 
@@ -1933,7 +1958,7 @@ static int __init comedi_init(void)
        comedi_proc_init();
 
        /* create devices files for legacy/manual use */
-       for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
+       for (i = 0; i < comedi_num_legacy_minors; i++) {
                int minor;
                minor = comedi_alloc_board_minor(NULL);
                if (minor < 0) {
@@ -1975,15 +2000,15 @@ static void __exit comedi_cleanup(void)
 module_init(comedi_init);
 module_exit(comedi_cleanup);
 
-void comedi_error(const comedi_device *dev, const char *s)
+void comedi_error(const struct comedi_device *dev, const char *s)
 {
        rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
                  s);
 }
 
-void comedi_event(comedi_device *dev, comedi_subdevice *s)
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
 {
-       comedi_async *async = s->async;
+       struct comedi_async *async = s->async;
        unsigned runflags = 0;
        unsigned runflags_mask = 0;
 
@@ -2042,7 +2067,7 @@ void comedi_event(comedi_device *dev, comedi_subdevice *s)
        s->async->events = 0;
 }
 
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
                                   unsigned bits)
 {
        unsigned long flags;
@@ -2053,7 +2078,7 @@ void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
        comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
 }
 
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
 {
        unsigned long flags;
        unsigned runflags;
@@ -2064,9 +2089,9 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
        return runflags;
 }
 
-static int is_device_busy(comedi_device *dev)
+static int is_device_busy(struct comedi_device *dev)
 {
-       comedi_subdevice *s;
+       struct comedi_subdevice *s;
        int i;
 
        if (!dev->attached)
@@ -2083,15 +2108,15 @@ static int is_device_busy(comedi_device *dev)
        return 0;
 }
 
-void comedi_device_init(comedi_device *dev)
+void comedi_device_init(struct comedi_device *dev)
 {
-       memset(dev, 0, sizeof(comedi_device));
+       memset(dev, 0, sizeof(struct comedi_device));
        spin_lock_init(&dev->spinlock);
        mutex_init(&dev->mutex);
        dev->minor = -1;
 }
 
-void comedi_device_cleanup(comedi_device *dev)
+void comedi_device_cleanup(struct comedi_device *dev)
 {
        if (dev == NULL)
                return;
@@ -2105,13 +2130,13 @@ int comedi_alloc_board_minor(struct device *hardware_device)
 {
        unsigned long flags;
        struct comedi_device_file_info *info;
-       device_create_result_type *csdev;
+       struct device *csdev;
        unsigned i;
 
        info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
        if (info == NULL)
                return -ENOMEM;
-       info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
+       info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
        if (info->device == NULL) {
                kfree(info);
                return -ENOMEM;
@@ -2155,7 +2180,7 @@ void comedi_free_board_minor(unsigned minor)
        comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
 
        if (info) {
-               comedi_device *dev = info->device;
+               struct comedi_device *dev = info->device;
                if (dev) {
                        if (dev->class_dev) {
                                device_destroy(comedi_class,
@@ -2168,11 +2193,11 @@ void comedi_free_board_minor(unsigned minor)
        }
 }
 
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s)
 {
        unsigned long flags;
        struct comedi_device_file_info *info;
-       device_create_result_type *csdev;
+       struct device *csdev;
        unsigned i;
 
        info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
@@ -2182,7 +2207,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
        info->read_subdevice = s;
        info->write_subdevice = s;
        comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
-       for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
+       for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
                if (comedi_file_info_table[i] == NULL) {
                        comedi_file_info_table[i] = info;
                        break;
@@ -2206,7 +2231,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
        return i;
 }
 
-void comedi_free_subdevice_minor(comedi_subdevice *s)
+void comedi_free_subdevice_minor(struct comedi_subdevice *s)
 {
        unsigned long flags;
        struct comedi_device_file_info *info;