staging: comedi: remove unused 'channel flags' support
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / comedi_fops.c
1 /*
2     comedi/comedi_fops.c
3     comedi kernel module
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 */
18
19 #undef DEBUG
20
21 #include "comedi_compat32.h"
22
23 #include <linux/module.h>
24 #include <linux/errno.h>
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/fcntl.h>
28 #include <linux/delay.h>
29 #include <linux/mm.h>
30 #include <linux/slab.h>
31 #include <linux/kmod.h>
32 #include <linux/poll.h>
33 #include <linux/init.h>
34 #include <linux/device.h>
35 #include <linux/vmalloc.h>
36 #include <linux/fs.h>
37 #include "comedidev.h"
38 #include <linux/cdev.h>
39 #include <linux/stat.h>
40
41 #include <linux/io.h>
42 #include <linux/uaccess.h>
43
44 #include "comedi_internal.h"
45
46 #define COMEDI_NUM_MINORS 0x100
47 #define COMEDI_NUM_SUBDEVICE_MINORS     \
48         (COMEDI_NUM_MINORS - COMEDI_NUM_BOARD_MINORS)
49
50 #ifdef CONFIG_COMEDI_DEBUG
51 int comedi_debug;
52 EXPORT_SYMBOL_GPL(comedi_debug);
53 module_param(comedi_debug, int, S_IRUGO | S_IWUSR);
54 MODULE_PARM_DESC(comedi_debug,
55                  "enable comedi core and driver debugging if non-zero (default 0)"
56                 );
57 #endif
58
59 static int comedi_num_legacy_minors;
60 module_param(comedi_num_legacy_minors, int, S_IRUGO);
61 MODULE_PARM_DESC(comedi_num_legacy_minors,
62                  "number of comedi minor devices to reserve for non-auto-configured devices (default 0)"
63                 );
64
65 unsigned int comedi_default_buf_size_kb = CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB;
66 module_param(comedi_default_buf_size_kb, uint, S_IRUGO | S_IWUSR);
67 MODULE_PARM_DESC(comedi_default_buf_size_kb,
68                  "default asynchronous buffer size in KiB (default "
69                  __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB) ")");
70
71 unsigned int comedi_default_buf_maxsize_kb
72         = CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB;
73 module_param(comedi_default_buf_maxsize_kb, uint, S_IRUGO | S_IWUSR);
74 MODULE_PARM_DESC(comedi_default_buf_maxsize_kb,
75                  "default maximum size of asynchronous buffer in KiB (default "
76                  __MODULE_STRING(CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB) ")");
77
78 static DEFINE_MUTEX(comedi_board_minor_table_lock);
79 static struct comedi_device
80 *comedi_board_minor_table[COMEDI_NUM_BOARD_MINORS];
81
82 static DEFINE_MUTEX(comedi_subdevice_minor_table_lock);
83 /* Note: indexed by minor - COMEDI_NUM_BOARD_MINORS. */
84 static struct comedi_subdevice
85 *comedi_subdevice_minor_table[COMEDI_NUM_SUBDEVICE_MINORS];
86
87 static struct class *comedi_class;
88 static struct cdev comedi_cdev;
89
90 static void comedi_device_init(struct comedi_device *dev)
91 {
92         spin_lock_init(&dev->spinlock);
93         mutex_init(&dev->mutex);
94         dev->minor = -1;
95 }
96
97 static void comedi_device_cleanup(struct comedi_device *dev)
98 {
99         struct module *driver_module = NULL;
100
101         if (dev == NULL)
102                 return;
103         mutex_lock(&dev->mutex);
104         if (dev->attached)
105                 driver_module = dev->driver->module;
106         comedi_device_detach(dev);
107         while (dev->use_count > 0) {
108                 if (driver_module)
109                         module_put(driver_module);
110                 module_put(THIS_MODULE);
111                 dev->use_count--;
112         }
113         mutex_unlock(&dev->mutex);
114         mutex_destroy(&dev->mutex);
115 }
116
117 static bool comedi_clear_board_dev(struct comedi_device *dev)
118 {
119         unsigned int i = dev->minor;
120         bool cleared = false;
121
122         mutex_lock(&comedi_board_minor_table_lock);
123         if (dev == comedi_board_minor_table[i]) {
124                 comedi_board_minor_table[i] = NULL;
125                 cleared = true;
126         }
127         mutex_unlock(&comedi_board_minor_table_lock);
128         return cleared;
129 }
130
131 static struct comedi_device *comedi_clear_board_minor(unsigned minor)
132 {
133         struct comedi_device *dev;
134
135         mutex_lock(&comedi_board_minor_table_lock);
136         dev = comedi_board_minor_table[minor];
137         comedi_board_minor_table[minor] = NULL;
138         mutex_unlock(&comedi_board_minor_table_lock);
139         return dev;
140 }
141
142 static void comedi_free_board_dev(struct comedi_device *dev)
143 {
144         if (dev) {
145                 if (dev->class_dev) {
146                         device_destroy(comedi_class,
147                                        MKDEV(COMEDI_MAJOR, dev->minor));
148                 }
149                 comedi_device_cleanup(dev);
150                 kfree(dev);
151         }
152 }
153
154 static struct comedi_subdevice
155 *comedi_subdevice_from_minor(unsigned minor)
156 {
157         struct comedi_subdevice *s;
158         unsigned int i = minor - COMEDI_NUM_BOARD_MINORS;
159
160         BUG_ON(i >= COMEDI_NUM_SUBDEVICE_MINORS);
161         mutex_lock(&comedi_subdevice_minor_table_lock);
162         s = comedi_subdevice_minor_table[i];
163         mutex_unlock(&comedi_subdevice_minor_table_lock);
164         return s;
165 }
166
167 static struct comedi_device *comedi_dev_from_board_minor(unsigned minor)
168 {
169         struct comedi_device *dev;
170
171         BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
172         mutex_lock(&comedi_board_minor_table_lock);
173         dev = comedi_board_minor_table[minor];
174         mutex_unlock(&comedi_board_minor_table_lock);
175         return dev;
176 }
177
178 static struct comedi_device *comedi_dev_from_subdevice_minor(unsigned minor)
179 {
180         struct comedi_subdevice *s;
181
182         s = comedi_subdevice_from_minor(minor);
183         return s ? s->device : NULL;
184 }
185
186 struct comedi_device *comedi_dev_from_minor(unsigned minor)
187 {
188         if (minor < COMEDI_NUM_BOARD_MINORS)
189                 return comedi_dev_from_board_minor(minor);
190         else
191                 return comedi_dev_from_subdevice_minor(minor);
192 }
193 EXPORT_SYMBOL_GPL(comedi_dev_from_minor);
194
195 static struct comedi_subdevice *
196 comedi_read_subdevice(const struct comedi_device *dev, unsigned int minor)
197 {
198         struct comedi_subdevice *s;
199
200         if (minor >= COMEDI_NUM_BOARD_MINORS) {
201                 s = comedi_subdevice_from_minor(minor);
202                 if (!s || s->device != dev)
203                         return NULL;
204                 if (s->subdev_flags & SDF_CMD_READ)
205                         return s;
206         }
207         return dev->read_subdev;
208 }
209
210 static struct comedi_subdevice *
211 comedi_write_subdevice(const struct comedi_device *dev, unsigned int minor)
212 {
213         struct comedi_subdevice *s;
214
215         if (minor >= COMEDI_NUM_BOARD_MINORS) {
216                 s = comedi_subdevice_from_minor(minor);
217                 if (!s || s->device != dev)
218                         return NULL;
219                 if (s->subdev_flags & SDF_CMD_WRITE)
220                         return s;
221         }
222         return dev->write_subdev;
223 }
224
225 static int resize_async_buffer(struct comedi_device *dev,
226                                struct comedi_subdevice *s,
227                                struct comedi_async *async, unsigned new_size)
228 {
229         int retval;
230
231         if (new_size > async->max_bufsize)
232                 return -EPERM;
233
234         if (s->busy) {
235                 DPRINTK("subdevice is busy, cannot resize buffer\n");
236                 return -EBUSY;
237         }
238         if (async->mmap_count) {
239                 DPRINTK("subdevice is mmapped, cannot resize buffer\n");
240                 return -EBUSY;
241         }
242
243         /* make sure buffer is an integral number of pages
244          * (we round up) */
245         new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
246
247         retval = comedi_buf_alloc(dev, s, new_size);
248         if (retval < 0)
249                 return retval;
250
251         if (s->buf_change) {
252                 retval = s->buf_change(dev, s, new_size);
253                 if (retval < 0)
254                         return retval;
255         }
256
257         DPRINTK("comedi%i subd %d buffer resized to %i bytes\n",
258                 dev->minor, s->index, async->prealloc_bufsz);
259         return 0;
260 }
261
262 /* sysfs attribute files */
263
264 static ssize_t max_read_buffer_kb_show(struct device *csdev,
265                                        struct device_attribute *attr, char *buf)
266 {
267         unsigned int minor = MINOR(csdev->devt);
268         struct comedi_device *dev;
269         struct comedi_subdevice *s;
270         unsigned int size = 0;
271
272         dev = comedi_dev_from_minor(minor);
273         if (!dev)
274                 return -ENODEV;
275
276         mutex_lock(&dev->mutex);
277         s = comedi_read_subdevice(dev, minor);
278         if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
279                 size = s->async->max_bufsize / 1024;
280         mutex_unlock(&dev->mutex);
281
282         return snprintf(buf, PAGE_SIZE, "%i\n", size);
283 }
284
285 static ssize_t max_read_buffer_kb_store(struct device *csdev,
286                                         struct device_attribute *attr,
287                                         const char *buf, size_t count)
288 {
289         unsigned int minor = MINOR(csdev->devt);
290         struct comedi_device *dev;
291         struct comedi_subdevice *s;
292         unsigned int size;
293         int err;
294
295         err = kstrtouint(buf, 10, &size);
296         if (err)
297                 return err;
298         if (size > (UINT_MAX / 1024))
299                 return -EINVAL;
300         size *= 1024;
301
302         dev = comedi_dev_from_minor(minor);
303         if (!dev)
304                 return -ENODEV;
305
306         mutex_lock(&dev->mutex);
307         s = comedi_read_subdevice(dev, minor);
308         if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
309                 s->async->max_bufsize = size;
310         else
311                 err = -EINVAL;
312         mutex_unlock(&dev->mutex);
313
314         return err ? err : count;
315 }
316 static DEVICE_ATTR_RW(max_read_buffer_kb);
317
318 static ssize_t read_buffer_kb_show(struct device *csdev,
319                                    struct device_attribute *attr, char *buf)
320 {
321         unsigned int minor = MINOR(csdev->devt);
322         struct comedi_device *dev;
323         struct comedi_subdevice *s;
324         unsigned int size = 0;
325
326         dev = comedi_dev_from_minor(minor);
327         if (!dev)
328                 return -ENODEV;
329
330         mutex_lock(&dev->mutex);
331         s = comedi_read_subdevice(dev, minor);
332         if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
333                 size = s->async->prealloc_bufsz / 1024;
334         mutex_unlock(&dev->mutex);
335
336         return snprintf(buf, PAGE_SIZE, "%i\n", size);
337 }
338
339 static ssize_t read_buffer_kb_store(struct device *csdev,
340                                     struct device_attribute *attr,
341                                     const char *buf, size_t count)
342 {
343         unsigned int minor = MINOR(csdev->devt);
344         struct comedi_device *dev;
345         struct comedi_subdevice *s;
346         unsigned int size;
347         int err;
348
349         err = kstrtouint(buf, 10, &size);
350         if (err)
351                 return err;
352         if (size > (UINT_MAX / 1024))
353                 return -EINVAL;
354         size *= 1024;
355
356         dev = comedi_dev_from_minor(minor);
357         if (!dev)
358                 return -ENODEV;
359
360         mutex_lock(&dev->mutex);
361         s = comedi_read_subdevice(dev, minor);
362         if (s && (s->subdev_flags & SDF_CMD_READ) && s->async)
363                 err = resize_async_buffer(dev, s, s->async, size);
364         else
365                 err = -EINVAL;
366         mutex_unlock(&dev->mutex);
367
368         return err ? err : count;
369 }
370 static DEVICE_ATTR_RW(read_buffer_kb);
371
372 static ssize_t max_write_buffer_kb_show(struct device *csdev,
373                                         struct device_attribute *attr,
374                                         char *buf)
375 {
376         unsigned int minor = MINOR(csdev->devt);
377         struct comedi_device *dev;
378         struct comedi_subdevice *s;
379         unsigned int size = 0;
380
381         dev = comedi_dev_from_minor(minor);
382         if (!dev)
383                 return -ENODEV;
384
385         mutex_lock(&dev->mutex);
386         s = comedi_write_subdevice(dev, minor);
387         if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
388                 size = s->async->max_bufsize / 1024;
389         mutex_unlock(&dev->mutex);
390
391         return snprintf(buf, PAGE_SIZE, "%i\n", size);
392 }
393
394 static ssize_t max_write_buffer_kb_store(struct device *csdev,
395                                          struct device_attribute *attr,
396                                          const char *buf, size_t count)
397 {
398         unsigned int minor = MINOR(csdev->devt);
399         struct comedi_device *dev;
400         struct comedi_subdevice *s;
401         unsigned int size;
402         int err;
403
404         err = kstrtouint(buf, 10, &size);
405         if (err)
406                 return err;
407         if (size > (UINT_MAX / 1024))
408                 return -EINVAL;
409         size *= 1024;
410
411         dev = comedi_dev_from_minor(minor);
412         if (!dev)
413                 return -ENODEV;
414
415         mutex_lock(&dev->mutex);
416         s = comedi_write_subdevice(dev, minor);
417         if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
418                 s->async->max_bufsize = size;
419         else
420                 err = -EINVAL;
421         mutex_unlock(&dev->mutex);
422
423         return err ? err : count;
424 }
425 static DEVICE_ATTR_RW(max_write_buffer_kb);
426
427 static ssize_t write_buffer_kb_show(struct device *csdev,
428                                     struct device_attribute *attr, char *buf)
429 {
430         unsigned int minor = MINOR(csdev->devt);
431         struct comedi_device *dev;
432         struct comedi_subdevice *s;
433         unsigned int size = 0;
434
435         dev = comedi_dev_from_minor(minor);
436         if (!dev)
437                 return -ENODEV;
438
439         mutex_lock(&dev->mutex);
440         s = comedi_write_subdevice(dev, minor);
441         if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
442                 size = s->async->prealloc_bufsz / 1024;
443         mutex_unlock(&dev->mutex);
444
445         return snprintf(buf, PAGE_SIZE, "%i\n", size);
446 }
447
448 static ssize_t write_buffer_kb_store(struct device *csdev,
449                                      struct device_attribute *attr,
450                                      const char *buf, size_t count)
451 {
452         unsigned int minor = MINOR(csdev->devt);
453         struct comedi_device *dev;
454         struct comedi_subdevice *s;
455         unsigned int size;
456         int err;
457
458         err = kstrtouint(buf, 10, &size);
459         if (err)
460                 return err;
461         if (size > (UINT_MAX / 1024))
462                 return -EINVAL;
463         size *= 1024;
464
465         dev = comedi_dev_from_minor(minor);
466         if (!dev)
467                 return -ENODEV;
468
469         mutex_lock(&dev->mutex);
470         s = comedi_write_subdevice(dev, minor);
471         if (s && (s->subdev_flags & SDF_CMD_WRITE) && s->async)
472                 err = resize_async_buffer(dev, s, s->async, size);
473         else
474                 err = -EINVAL;
475         mutex_unlock(&dev->mutex);
476
477         return err ? err : count;
478 }
479 static DEVICE_ATTR_RW(write_buffer_kb);
480
481 static struct attribute *comedi_dev_attrs[] = {
482         &dev_attr_max_read_buffer_kb.attr,
483         &dev_attr_read_buffer_kb.attr,
484         &dev_attr_max_write_buffer_kb.attr,
485         &dev_attr_write_buffer_kb.attr,
486         NULL,
487 };
488 ATTRIBUTE_GROUPS(comedi_dev);
489
490 static void comedi_set_subdevice_runflags(struct comedi_subdevice *s,
491                                           unsigned mask, unsigned bits)
492 {
493         unsigned long flags;
494
495         spin_lock_irqsave(&s->spin_lock, flags);
496         s->runflags &= ~mask;
497         s->runflags |= (bits & mask);
498         spin_unlock_irqrestore(&s->spin_lock, flags);
499 }
500
501 static unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
502 {
503         unsigned long flags;
504         unsigned runflags;
505
506         spin_lock_irqsave(&s->spin_lock, flags);
507         runflags = s->runflags;
508         spin_unlock_irqrestore(&s->spin_lock, flags);
509         return runflags;
510 }
511
512 bool comedi_is_subdevice_running(struct comedi_subdevice *s)
513 {
514         unsigned runflags = comedi_get_subdevice_runflags(s);
515
516         return (runflags & SRF_RUNNING) ? true : false;
517 }
518 EXPORT_SYMBOL_GPL(comedi_is_subdevice_running);
519
520 static bool comedi_is_subdevice_in_error(struct comedi_subdevice *s)
521 {
522         unsigned runflags = comedi_get_subdevice_runflags(s);
523
524         return (runflags & SRF_ERROR) ? true : false;
525 }
526
527 static bool comedi_is_subdevice_idle(struct comedi_subdevice *s)
528 {
529         unsigned runflags = comedi_get_subdevice_runflags(s);
530
531         return (runflags & (SRF_ERROR | SRF_RUNNING)) ? false : true;
532 }
533
534 /**
535  * comedi_alloc_spriv() - Allocate memory for the subdevice private data.
536  * @s: comedi_subdevice struct
537  * @size: size of the memory to allocate
538  *
539  * This also sets the subdevice runflags to allow the core to automatically
540  * free the private data during the detach.
541  */
542 void *comedi_alloc_spriv(struct comedi_subdevice *s, size_t size)
543 {
544         s->private = kzalloc(size, GFP_KERNEL);
545         if (s->private)
546                 comedi_set_subdevice_runflags(s, ~0, SRF_FREE_SPRIV);
547         return s->private;
548 }
549 EXPORT_SYMBOL_GPL(comedi_alloc_spriv);
550
551 /*
552    This function restores a subdevice to an idle state.
553  */
554 static void do_become_nonbusy(struct comedi_device *dev,
555                               struct comedi_subdevice *s)
556 {
557         struct comedi_async *async = s->async;
558
559         comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
560         if (async) {
561                 comedi_buf_reset(async);
562                 async->inttrig = NULL;
563                 kfree(async->cmd.chanlist);
564                 async->cmd.chanlist = NULL;
565         } else {
566                 dev_err(dev->class_dev,
567                         "BUG: (?) do_become_nonbusy called with async=NULL\n");
568         }
569
570         s->busy = NULL;
571 }
572
573 static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
574 {
575         int ret = 0;
576
577         if (comedi_is_subdevice_running(s) && s->cancel)
578                 ret = s->cancel(dev, s);
579
580         do_become_nonbusy(dev, s);
581
582         return ret;
583 }
584
585 static int is_device_busy(struct comedi_device *dev)
586 {
587         struct comedi_subdevice *s;
588         int i;
589
590         if (!dev->attached)
591                 return 0;
592
593         for (i = 0; i < dev->n_subdevices; i++) {
594                 s = &dev->subdevices[i];
595                 if (s->busy)
596                         return 1;
597                 if (s->async && s->async->mmap_count)
598                         return 1;
599         }
600
601         return 0;
602 }
603
604 /*
605         COMEDI_DEVCONFIG
606         device config ioctl
607
608         arg:
609                 pointer to devconfig structure
610
611         reads:
612                 devconfig structure at arg
613
614         writes:
615                 none
616 */
617 static int do_devconfig_ioctl(struct comedi_device *dev,
618                               struct comedi_devconfig __user *arg)
619 {
620         struct comedi_devconfig it;
621
622         if (!capable(CAP_SYS_ADMIN))
623                 return -EPERM;
624
625         if (arg == NULL) {
626                 if (is_device_busy(dev))
627                         return -EBUSY;
628                 if (dev->attached) {
629                         struct module *driver_module = dev->driver->module;
630                         comedi_device_detach(dev);
631                         module_put(driver_module);
632                 }
633                 return 0;
634         }
635
636         if (copy_from_user(&it, arg, sizeof(it)))
637                 return -EFAULT;
638
639         it.board_name[COMEDI_NAMELEN - 1] = 0;
640
641         if (it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
642                 dev_warn(dev->class_dev,
643                          "comedi_config --init_data is deprecated\n");
644                 return -EINVAL;
645         }
646
647         if (dev->minor >= comedi_num_legacy_minors)
648                 /* don't re-use dynamically allocated comedi devices */
649                 return -EBUSY;
650
651         /* This increments the driver module count on success. */
652         return comedi_device_attach(dev, &it);
653 }
654
655 /*
656         COMEDI_BUFCONFIG
657         buffer configuration ioctl
658
659         arg:
660                 pointer to bufconfig structure
661
662         reads:
663                 bufconfig at arg
664
665         writes:
666                 modified bufconfig at arg
667
668 */
669 static int do_bufconfig_ioctl(struct comedi_device *dev,
670                               struct comedi_bufconfig __user *arg)
671 {
672         struct comedi_bufconfig bc;
673         struct comedi_async *async;
674         struct comedi_subdevice *s;
675         int retval = 0;
676
677         if (copy_from_user(&bc, arg, sizeof(bc)))
678                 return -EFAULT;
679
680         if (bc.subdevice >= dev->n_subdevices)
681                 return -EINVAL;
682
683         s = &dev->subdevices[bc.subdevice];
684         async = s->async;
685
686         if (!async) {
687                 DPRINTK("subdevice does not have async capability\n");
688                 bc.size = 0;
689                 bc.maximum_size = 0;
690                 goto copyback;
691         }
692
693         if (bc.maximum_size) {
694                 if (!capable(CAP_SYS_ADMIN))
695                         return -EPERM;
696
697                 async->max_bufsize = bc.maximum_size;
698         }
699
700         if (bc.size) {
701                 retval = resize_async_buffer(dev, s, async, bc.size);
702                 if (retval < 0)
703                         return retval;
704         }
705
706         bc.size = async->prealloc_bufsz;
707         bc.maximum_size = async->max_bufsize;
708
709 copyback:
710         if (copy_to_user(arg, &bc, sizeof(bc)))
711                 return -EFAULT;
712
713         return 0;
714 }
715
716 /*
717         COMEDI_DEVINFO
718         device info ioctl
719
720         arg:
721                 pointer to devinfo structure
722
723         reads:
724                 none
725
726         writes:
727                 devinfo structure
728
729 */
730 static int do_devinfo_ioctl(struct comedi_device *dev,
731                             struct comedi_devinfo __user *arg,
732                             struct file *file)
733 {
734         const unsigned minor = iminor(file_inode(file));
735         struct comedi_subdevice *s;
736         struct comedi_devinfo devinfo;
737
738         memset(&devinfo, 0, sizeof(devinfo));
739
740         /* fill devinfo structure */
741         devinfo.version_code = COMEDI_VERSION_CODE;
742         devinfo.n_subdevs = dev->n_subdevices;
743         strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
744         strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
745
746         s = comedi_read_subdevice(dev, minor);
747         if (s)
748                 devinfo.read_subdevice = s->index;
749         else
750                 devinfo.read_subdevice = -1;
751
752         s = comedi_write_subdevice(dev, minor);
753         if (s)
754                 devinfo.write_subdevice = s->index;
755         else
756                 devinfo.write_subdevice = -1;
757
758         if (copy_to_user(arg, &devinfo, sizeof(devinfo)))
759                 return -EFAULT;
760
761         return 0;
762 }
763
764 /*
765         COMEDI_SUBDINFO
766         subdevice info ioctl
767
768         arg:
769                 pointer to array of subdevice info structures
770
771         reads:
772                 none
773
774         writes:
775                 array of subdevice info structures at arg
776
777 */
778 static int do_subdinfo_ioctl(struct comedi_device *dev,
779                              struct comedi_subdinfo __user *arg, void *file)
780 {
781         int ret, i;
782         struct comedi_subdinfo *tmp, *us;
783         struct comedi_subdevice *s;
784
785         tmp = kcalloc(dev->n_subdevices, sizeof(*tmp), GFP_KERNEL);
786         if (!tmp)
787                 return -ENOMEM;
788
789         /* fill subdinfo structs */
790         for (i = 0; i < dev->n_subdevices; i++) {
791                 s = &dev->subdevices[i];
792                 us = tmp + i;
793
794                 us->type = s->type;
795                 us->n_chan = s->n_chan;
796                 us->subd_flags = s->subdev_flags;
797                 if (comedi_is_subdevice_running(s))
798                         us->subd_flags |= SDF_RUNNING;
799 #define TIMER_nanosec 5         /* backwards compatibility */
800                 us->timer_type = TIMER_nanosec;
801                 us->len_chanlist = s->len_chanlist;
802                 us->maxdata = s->maxdata;
803                 if (s->range_table) {
804                         us->range_type =
805                             (i << 24) | (0 << 16) | (s->range_table->length);
806                 } else {
807                         us->range_type = 0;     /* XXX */
808                 }
809
810                 if (s->busy)
811                         us->subd_flags |= SDF_BUSY;
812                 if (s->busy == file)
813                         us->subd_flags |= SDF_BUSY_OWNER;
814                 if (s->lock)
815                         us->subd_flags |= SDF_LOCKED;
816                 if (s->lock == file)
817                         us->subd_flags |= SDF_LOCK_OWNER;
818                 if (!s->maxdata && s->maxdata_list)
819                         us->subd_flags |= SDF_MAXDATA;
820                 if (s->range_table_list)
821                         us->subd_flags |= SDF_RANGETYPE;
822                 if (s->do_cmd)
823                         us->subd_flags |= SDF_CMD;
824
825                 if (s->insn_bits != &insn_inval)
826                         us->insn_bits_support = COMEDI_SUPPORTED;
827                 else
828                         us->insn_bits_support = COMEDI_UNSUPPORTED;
829
830                 us->settling_time_0 = s->settling_time_0;
831         }
832
833         ret = copy_to_user(arg, tmp, dev->n_subdevices * sizeof(*tmp));
834
835         kfree(tmp);
836
837         return ret ? -EFAULT : 0;
838 }
839
840 /*
841         COMEDI_CHANINFO
842         subdevice info ioctl
843
844         arg:
845                 pointer to chaninfo structure
846
847         reads:
848                 chaninfo structure at arg
849
850         writes:
851                 arrays at elements of chaninfo structure
852
853 */
854 static int do_chaninfo_ioctl(struct comedi_device *dev,
855                              struct comedi_chaninfo __user *arg)
856 {
857         struct comedi_subdevice *s;
858         struct comedi_chaninfo it;
859
860         if (copy_from_user(&it, arg, sizeof(it)))
861                 return -EFAULT;
862
863         if (it.subdev >= dev->n_subdevices)
864                 return -EINVAL;
865         s = &dev->subdevices[it.subdev];
866
867         if (it.maxdata_list) {
868                 if (s->maxdata || !s->maxdata_list)
869                         return -EINVAL;
870                 if (copy_to_user(it.maxdata_list, s->maxdata_list,
871                                  s->n_chan * sizeof(unsigned int)))
872                         return -EFAULT;
873         }
874
875         if (it.flaglist)
876                 return -EINVAL; /* flaglist not supported */
877
878         if (it.rangelist) {
879                 int i;
880
881                 if (!s->range_table_list)
882                         return -EINVAL;
883                 for (i = 0; i < s->n_chan; i++) {
884                         int x;
885
886                         x = (dev->minor << 28) | (it.subdev << 24) | (i << 16) |
887                             (s->range_table_list[i]->length);
888                         if (put_user(x, it.rangelist + i))
889                                 return -EFAULT;
890                 }
891 #if 0
892                 if (copy_to_user(it.rangelist, s->range_type_list,
893                                  s->n_chan * sizeof(unsigned int)))
894                         return -EFAULT;
895 #endif
896         }
897
898         return 0;
899 }
900
901  /*
902     COMEDI_BUFINFO
903     buffer information ioctl
904
905     arg:
906     pointer to bufinfo structure
907
908     reads:
909     bufinfo at arg
910
911     writes:
912     modified bufinfo at arg
913
914   */
915 static int do_bufinfo_ioctl(struct comedi_device *dev,
916                             struct comedi_bufinfo __user *arg, void *file)
917 {
918         struct comedi_bufinfo bi;
919         struct comedi_subdevice *s;
920         struct comedi_async *async;
921
922         if (copy_from_user(&bi, arg, sizeof(bi)))
923                 return -EFAULT;
924
925         if (bi.subdevice >= dev->n_subdevices)
926                 return -EINVAL;
927
928         s = &dev->subdevices[bi.subdevice];
929
930         if (s->lock && s->lock != file)
931                 return -EACCES;
932
933         async = s->async;
934
935         if (!async) {
936                 DPRINTK("subdevice does not have async capability\n");
937                 bi.buf_write_ptr = 0;
938                 bi.buf_read_ptr = 0;
939                 bi.buf_write_count = 0;
940                 bi.buf_read_count = 0;
941                 bi.bytes_read = 0;
942                 bi.bytes_written = 0;
943                 goto copyback;
944         }
945         if (!s->busy) {
946                 bi.bytes_read = 0;
947                 bi.bytes_written = 0;
948                 goto copyback_position;
949         }
950         if (s->busy != file)
951                 return -EACCES;
952
953         if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
954                 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
955                 comedi_buf_read_free(async, bi.bytes_read);
956
957                 if (comedi_is_subdevice_idle(s) &&
958                     async->buf_write_count == async->buf_read_count) {
959                         do_become_nonbusy(dev, s);
960                 }
961         }
962
963         if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) {
964                 bi.bytes_written =
965                     comedi_buf_write_alloc(async, bi.bytes_written);
966                 comedi_buf_write_free(async, bi.bytes_written);
967         }
968
969 copyback_position:
970         bi.buf_write_count = async->buf_write_count;
971         bi.buf_write_ptr = async->buf_write_ptr;
972         bi.buf_read_count = async->buf_read_count;
973         bi.buf_read_ptr = async->buf_read_ptr;
974
975 copyback:
976         if (copy_to_user(arg, &bi, sizeof(bi)))
977                 return -EFAULT;
978
979         return 0;
980 }
981
982 static int check_insn_config_length(struct comedi_insn *insn,
983                                     unsigned int *data)
984 {
985         if (insn->n < 1)
986                 return -EINVAL;
987
988         switch (data[0]) {
989         case INSN_CONFIG_DIO_OUTPUT:
990         case INSN_CONFIG_DIO_INPUT:
991         case INSN_CONFIG_DISARM:
992         case INSN_CONFIG_RESET:
993                 if (insn->n == 1)
994                         return 0;
995                 break;
996         case INSN_CONFIG_ARM:
997         case INSN_CONFIG_DIO_QUERY:
998         case INSN_CONFIG_BLOCK_SIZE:
999         case INSN_CONFIG_FILTER:
1000         case INSN_CONFIG_SERIAL_CLOCK:
1001         case INSN_CONFIG_BIDIRECTIONAL_DATA:
1002         case INSN_CONFIG_ALT_SOURCE:
1003         case INSN_CONFIG_SET_COUNTER_MODE:
1004         case INSN_CONFIG_8254_READ_STATUS:
1005         case INSN_CONFIG_SET_ROUTING:
1006         case INSN_CONFIG_GET_ROUTING:
1007         case INSN_CONFIG_GET_PWM_STATUS:
1008         case INSN_CONFIG_PWM_SET_PERIOD:
1009         case INSN_CONFIG_PWM_GET_PERIOD:
1010                 if (insn->n == 2)
1011                         return 0;
1012                 break;
1013         case INSN_CONFIG_SET_GATE_SRC:
1014         case INSN_CONFIG_GET_GATE_SRC:
1015         case INSN_CONFIG_SET_CLOCK_SRC:
1016         case INSN_CONFIG_GET_CLOCK_SRC:
1017         case INSN_CONFIG_SET_OTHER_SRC:
1018         case INSN_CONFIG_GET_COUNTER_STATUS:
1019         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1020         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1021         case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
1022                 if (insn->n == 3)
1023                         return 0;
1024                 break;
1025         case INSN_CONFIG_PWM_OUTPUT:
1026         case INSN_CONFIG_ANALOG_TRIG:
1027                 if (insn->n == 5)
1028                         return 0;
1029                 break;
1030         case INSN_CONFIG_DIGITAL_TRIG:
1031                 if (insn->n == 6)
1032                         return 0;
1033                 break;
1034                 /* by default we allow the insn since we don't have checks for
1035                  * all possible cases yet */
1036         default:
1037                 pr_warn("comedi: No check for data length of config insn id %i is implemented.\n",
1038                         data[0]);
1039                 pr_warn("comedi: Add a check to %s in %s.\n",
1040                         __func__, __FILE__);
1041                 pr_warn("comedi: Assuming n=%i is correct.\n", insn->n);
1042                 return 0;
1043         }
1044         return -EINVAL;
1045 }
1046
1047 static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
1048                       unsigned int *data, void *file)
1049 {
1050         struct comedi_subdevice *s;
1051         int ret = 0;
1052         int i;
1053
1054         if (insn->insn & INSN_MASK_SPECIAL) {
1055                 /* a non-subdevice instruction */
1056
1057                 switch (insn->insn) {
1058                 case INSN_GTOD:
1059                         {
1060                                 struct timeval tv;
1061
1062                                 if (insn->n != 2) {
1063                                         ret = -EINVAL;
1064                                         break;
1065                                 }
1066
1067                                 do_gettimeofday(&tv);
1068                                 data[0] = tv.tv_sec;
1069                                 data[1] = tv.tv_usec;
1070                                 ret = 2;
1071
1072                                 break;
1073                         }
1074                 case INSN_WAIT:
1075                         if (insn->n != 1 || data[0] >= 100000) {
1076                                 ret = -EINVAL;
1077                                 break;
1078                         }
1079                         udelay(data[0] / 1000);
1080                         ret = 1;
1081                         break;
1082                 case INSN_INTTRIG:
1083                         if (insn->n != 1) {
1084                                 ret = -EINVAL;
1085                                 break;
1086                         }
1087                         if (insn->subdev >= dev->n_subdevices) {
1088                                 DPRINTK("%d not usable subdevice\n",
1089                                         insn->subdev);
1090                                 ret = -EINVAL;
1091                                 break;
1092                         }
1093                         s = &dev->subdevices[insn->subdev];
1094                         if (!s->async) {
1095                                 DPRINTK("no async\n");
1096                                 ret = -EINVAL;
1097                                 break;
1098                         }
1099                         if (!s->async->inttrig) {
1100                                 DPRINTK("no inttrig\n");
1101                                 ret = -EAGAIN;
1102                                 break;
1103                         }
1104                         ret = s->async->inttrig(dev, s, data[0]);
1105                         if (ret >= 0)
1106                                 ret = 1;
1107                         break;
1108                 default:
1109                         DPRINTK("invalid insn\n");
1110                         ret = -EINVAL;
1111                         break;
1112                 }
1113         } else {
1114                 /* a subdevice instruction */
1115                 unsigned int maxdata;
1116
1117                 if (insn->subdev >= dev->n_subdevices) {
1118                         DPRINTK("subdevice %d out of range\n", insn->subdev);
1119                         ret = -EINVAL;
1120                         goto out;
1121                 }
1122                 s = &dev->subdevices[insn->subdev];
1123
1124                 if (s->type == COMEDI_SUBD_UNUSED) {
1125                         DPRINTK("%d not usable subdevice\n", insn->subdev);
1126                         ret = -EIO;
1127                         goto out;
1128                 }
1129
1130                 /* are we locked? (ioctl lock) */
1131                 if (s->lock && s->lock != file) {
1132                         DPRINTK("device locked\n");
1133                         ret = -EACCES;
1134                         goto out;
1135                 }
1136
1137                 ret = comedi_check_chanlist(s, 1, &insn->chanspec);
1138                 if (ret < 0) {
1139                         ret = -EINVAL;
1140                         DPRINTK("bad chanspec\n");
1141                         goto out;
1142                 }
1143
1144                 if (s->busy) {
1145                         ret = -EBUSY;
1146                         goto out;
1147                 }
1148                 /* This looks arbitrary.  It is. */
1149                 s->busy = &parse_insn;
1150                 switch (insn->insn) {
1151                 case INSN_READ:
1152                         ret = s->insn_read(dev, s, insn, data);
1153                         break;
1154                 case INSN_WRITE:
1155                         maxdata = s->maxdata_list
1156                             ? s->maxdata_list[CR_CHAN(insn->chanspec)]
1157                             : s->maxdata;
1158                         for (i = 0; i < insn->n; ++i) {
1159                                 if (data[i] > maxdata) {
1160                                         ret = -EINVAL;
1161                                         DPRINTK("bad data value(s)\n");
1162                                         break;
1163                                 }
1164                         }
1165                         if (ret == 0)
1166                                 ret = s->insn_write(dev, s, insn, data);
1167                         break;
1168                 case INSN_BITS:
1169                         if (insn->n != 2) {
1170                                 ret = -EINVAL;
1171                         } else {
1172                                 /* Most drivers ignore the base channel in
1173                                  * insn->chanspec.  Fix this here if
1174                                  * the subdevice has <= 32 channels.  */
1175                                 unsigned int shift;
1176                                 unsigned int orig_mask;
1177
1178                                 orig_mask = data[0];
1179                                 if (s->n_chan <= 32) {
1180                                         shift = CR_CHAN(insn->chanspec);
1181                                         if (shift > 0) {
1182                                                 insn->chanspec = 0;
1183                                                 data[0] <<= shift;
1184                                                 data[1] <<= shift;
1185                                         }
1186                                 } else
1187                                         shift = 0;
1188                                 ret = s->insn_bits(dev, s, insn, data);
1189                                 data[0] = orig_mask;
1190                                 if (shift > 0)
1191                                         data[1] >>= shift;
1192                         }
1193                         break;
1194                 case INSN_CONFIG:
1195                         ret = check_insn_config_length(insn, data);
1196                         if (ret)
1197                                 break;
1198                         ret = s->insn_config(dev, s, insn, data);
1199                         break;
1200                 default:
1201                         ret = -EINVAL;
1202                         break;
1203                 }
1204
1205                 s->busy = NULL;
1206         }
1207
1208 out:
1209         return ret;
1210 }
1211
1212 /*
1213  *      COMEDI_INSNLIST
1214  *      synchronous instructions
1215  *
1216  *      arg:
1217  *              pointer to sync cmd structure
1218  *
1219  *      reads:
1220  *              sync cmd struct at arg
1221  *              instruction list
1222  *              data (for writes)
1223  *
1224  *      writes:
1225  *              data (for reads)
1226  */
1227 /* arbitrary limits */
1228 #define MAX_SAMPLES 256
1229 static int do_insnlist_ioctl(struct comedi_device *dev,
1230                              struct comedi_insnlist __user *arg, void *file)
1231 {
1232         struct comedi_insnlist insnlist;
1233         struct comedi_insn *insns = NULL;
1234         unsigned int *data = NULL;
1235         int i = 0;
1236         int ret = 0;
1237
1238         if (copy_from_user(&insnlist, arg, sizeof(insnlist)))
1239                 return -EFAULT;
1240
1241         data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
1242         if (!data) {
1243                 DPRINTK("kmalloc failed\n");
1244                 ret = -ENOMEM;
1245                 goto error;
1246         }
1247
1248         insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL);
1249         if (!insns) {
1250                 DPRINTK("kmalloc failed\n");
1251                 ret = -ENOMEM;
1252                 goto error;
1253         }
1254
1255         if (copy_from_user(insns, insnlist.insns,
1256                            sizeof(*insns) * insnlist.n_insns)) {
1257                 DPRINTK("copy_from_user failed\n");
1258                 ret = -EFAULT;
1259                 goto error;
1260         }
1261
1262         for (i = 0; i < insnlist.n_insns; i++) {
1263                 if (insns[i].n > MAX_SAMPLES) {
1264                         DPRINTK("number of samples too large\n");
1265                         ret = -EINVAL;
1266                         goto error;
1267                 }
1268                 if (insns[i].insn & INSN_MASK_WRITE) {
1269                         if (copy_from_user(data, insns[i].data,
1270                                            insns[i].n * sizeof(unsigned int))) {
1271                                 DPRINTK("copy_from_user failed\n");
1272                                 ret = -EFAULT;
1273                                 goto error;
1274                         }
1275                 }
1276                 ret = parse_insn(dev, insns + i, data, file);
1277                 if (ret < 0)
1278                         goto error;
1279                 if (insns[i].insn & INSN_MASK_READ) {
1280                         if (copy_to_user(insns[i].data, data,
1281                                          insns[i].n * sizeof(unsigned int))) {
1282                                 DPRINTK("copy_to_user failed\n");
1283                                 ret = -EFAULT;
1284                                 goto error;
1285                         }
1286                 }
1287                 if (need_resched())
1288                         schedule();
1289         }
1290
1291 error:
1292         kfree(insns);
1293         kfree(data);
1294
1295         if (ret < 0)
1296                 return ret;
1297         return i;
1298 }
1299
1300 /*
1301  *      COMEDI_INSN
1302  *      synchronous instructions
1303  *
1304  *      arg:
1305  *              pointer to insn
1306  *
1307  *      reads:
1308  *              struct comedi_insn struct at arg
1309  *              data (for writes)
1310  *
1311  *      writes:
1312  *              data (for reads)
1313  */
1314 static int do_insn_ioctl(struct comedi_device *dev,
1315                          struct comedi_insn __user *arg, void *file)
1316 {
1317         struct comedi_insn insn;
1318         unsigned int *data = NULL;
1319         int ret = 0;
1320
1321         data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
1322         if (!data) {
1323                 ret = -ENOMEM;
1324                 goto error;
1325         }
1326
1327         if (copy_from_user(&insn, arg, sizeof(insn))) {
1328                 ret = -EFAULT;
1329                 goto error;
1330         }
1331
1332         /* This is where the behavior of insn and insnlist deviate. */
1333         if (insn.n > MAX_SAMPLES)
1334                 insn.n = MAX_SAMPLES;
1335         if (insn.insn & INSN_MASK_WRITE) {
1336                 if (copy_from_user(data,
1337                                    insn.data,
1338                                    insn.n * sizeof(unsigned int))) {
1339                         ret = -EFAULT;
1340                         goto error;
1341                 }
1342         }
1343         ret = parse_insn(dev, &insn, data, file);
1344         if (ret < 0)
1345                 goto error;
1346         if (insn.insn & INSN_MASK_READ) {
1347                 if (copy_to_user(insn.data,
1348                                  data,
1349                                  insn.n * sizeof(unsigned int))) {
1350                         ret = -EFAULT;
1351                         goto error;
1352                 }
1353         }
1354         ret = insn.n;
1355
1356 error:
1357         kfree(data);
1358
1359         return ret;
1360 }
1361
1362 static int do_cmd_ioctl(struct comedi_device *dev,
1363                         struct comedi_cmd __user *arg, void *file)
1364 {
1365         struct comedi_cmd cmd;
1366         struct comedi_subdevice *s;
1367         struct comedi_async *async;
1368         int ret = 0;
1369         unsigned int __user *user_chanlist;
1370
1371         if (copy_from_user(&cmd, arg, sizeof(cmd))) {
1372                 DPRINTK("bad cmd address\n");
1373                 return -EFAULT;
1374         }
1375         /* save user's chanlist pointer so it can be restored later */
1376         user_chanlist = (unsigned int __user *)cmd.chanlist;
1377
1378         if (cmd.subdev >= dev->n_subdevices) {
1379                 DPRINTK("%d no such subdevice\n", cmd.subdev);
1380                 return -ENODEV;
1381         }
1382
1383         s = &dev->subdevices[cmd.subdev];
1384         async = s->async;
1385
1386         if (s->type == COMEDI_SUBD_UNUSED) {
1387                 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1388                 return -EIO;
1389         }
1390
1391         if (!s->do_cmd || !s->do_cmdtest || !s->async) {
1392                 DPRINTK("subdevice %i does not support commands\n",
1393                         cmd.subdev);
1394                 return -EIO;
1395         }
1396
1397         /* are we locked? (ioctl lock) */
1398         if (s->lock && s->lock != file) {
1399                 DPRINTK("subdevice locked\n");
1400                 return -EACCES;
1401         }
1402
1403         /* are we busy? */
1404         if (s->busy) {
1405                 DPRINTK("subdevice busy\n");
1406                 return -EBUSY;
1407         }
1408
1409         /* make sure channel/gain list isn't too long */
1410         if (cmd.chanlist_len > s->len_chanlist) {
1411                 DPRINTK("channel/gain list too long %u > %d\n",
1412                         cmd.chanlist_len, s->len_chanlist);
1413                 return -EINVAL;
1414         }
1415
1416         /* make sure channel/gain list isn't too short */
1417         if (cmd.chanlist_len < 1) {
1418                 DPRINTK("channel/gain list too short %u < 1\n",
1419                         cmd.chanlist_len);
1420                 return -EINVAL;
1421         }
1422
1423         async->cmd = cmd;
1424         async->cmd.data = NULL;
1425         /* load channel/gain list */
1426         async->cmd.chanlist =
1427             kmalloc(async->cmd.chanlist_len * sizeof(int), GFP_KERNEL);
1428         if (!async->cmd.chanlist) {
1429                 DPRINTK("allocation failed\n");
1430                 return -ENOMEM;
1431         }
1432
1433         if (copy_from_user(async->cmd.chanlist, user_chanlist,
1434                            async->cmd.chanlist_len * sizeof(int))) {
1435                 DPRINTK("fault reading chanlist\n");
1436                 ret = -EFAULT;
1437                 goto cleanup;
1438         }
1439
1440         /* make sure each element in channel/gain list is valid */
1441         ret = comedi_check_chanlist(s,
1442                                     async->cmd.chanlist_len,
1443                                     async->cmd.chanlist);
1444         if (ret < 0) {
1445                 DPRINTK("bad chanlist\n");
1446                 goto cleanup;
1447         }
1448
1449         ret = s->do_cmdtest(dev, s, &async->cmd);
1450
1451         if (async->cmd.flags & TRIG_BOGUS || ret) {
1452                 DPRINTK("test returned %d\n", ret);
1453                 cmd = async->cmd;
1454                 /* restore chanlist pointer before copying back */
1455                 cmd.chanlist = (unsigned int __force *)user_chanlist;
1456                 cmd.data = NULL;
1457                 if (copy_to_user(arg, &cmd, sizeof(cmd))) {
1458                         DPRINTK("fault writing cmd\n");
1459                         ret = -EFAULT;
1460                         goto cleanup;
1461                 }
1462                 ret = -EAGAIN;
1463                 goto cleanup;
1464         }
1465
1466         if (!async->prealloc_bufsz) {
1467                 ret = -ENOMEM;
1468                 DPRINTK("no buffer (?)\n");
1469                 goto cleanup;
1470         }
1471
1472         comedi_buf_reset(async);
1473
1474         async->cb_mask =
1475             COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR |
1476             COMEDI_CB_OVERFLOW;
1477         if (async->cmd.flags & TRIG_WAKE_EOS)
1478                 async->cb_mask |= COMEDI_CB_EOS;
1479
1480         comedi_set_subdevice_runflags(s, ~0, SRF_USER | SRF_RUNNING);
1481
1482         /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
1483          * comedi_read() or comedi_write() */
1484         s->busy = file;
1485         ret = s->do_cmd(dev, s);
1486         if (ret == 0)
1487                 return 0;
1488
1489 cleanup:
1490         do_become_nonbusy(dev, s);
1491
1492         return ret;
1493 }
1494
1495 /*
1496         COMEDI_CMDTEST
1497         command testing ioctl
1498
1499         arg:
1500                 pointer to cmd structure
1501
1502         reads:
1503                 cmd structure at arg
1504                 channel/range list
1505
1506         writes:
1507                 modified cmd structure at arg
1508
1509 */
1510 static int do_cmdtest_ioctl(struct comedi_device *dev,
1511                             struct comedi_cmd __user *arg, void *file)
1512 {
1513         struct comedi_cmd cmd;
1514         struct comedi_subdevice *s;
1515         int ret = 0;
1516         unsigned int *chanlist = NULL;
1517         unsigned int __user *user_chanlist;
1518
1519         if (copy_from_user(&cmd, arg, sizeof(cmd))) {
1520                 DPRINTK("bad cmd address\n");
1521                 return -EFAULT;
1522         }
1523         /* save user's chanlist pointer so it can be restored later */
1524         user_chanlist = (unsigned int __user *)cmd.chanlist;
1525
1526         if (cmd.subdev >= dev->n_subdevices) {
1527                 DPRINTK("%d no such subdevice\n", cmd.subdev);
1528                 return -ENODEV;
1529         }
1530
1531         s = &dev->subdevices[cmd.subdev];
1532         if (s->type == COMEDI_SUBD_UNUSED) {
1533                 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1534                 return -EIO;
1535         }
1536
1537         if (!s->do_cmd || !s->do_cmdtest) {
1538                 DPRINTK("subdevice %i does not support commands\n",
1539                         cmd.subdev);
1540                 return -EIO;
1541         }
1542
1543         /* make sure channel/gain list isn't too long */
1544         if (cmd.chanlist_len > s->len_chanlist) {
1545                 DPRINTK("channel/gain list too long %d > %d\n",
1546                         cmd.chanlist_len, s->len_chanlist);
1547                 ret = -EINVAL;
1548                 goto cleanup;
1549         }
1550
1551         /* load channel/gain list */
1552         if (cmd.chanlist) {
1553                 chanlist =
1554                     kmalloc(cmd.chanlist_len * sizeof(int), GFP_KERNEL);
1555                 if (!chanlist) {
1556                         DPRINTK("allocation failed\n");
1557                         ret = -ENOMEM;
1558                         goto cleanup;
1559                 }
1560
1561                 if (copy_from_user(chanlist, user_chanlist,
1562                                    cmd.chanlist_len * sizeof(int))) {
1563                         DPRINTK("fault reading chanlist\n");
1564                         ret = -EFAULT;
1565                         goto cleanup;
1566                 }
1567
1568                 /* make sure each element in channel/gain list is valid */
1569                 ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist);
1570                 if (ret < 0) {
1571                         DPRINTK("bad chanlist\n");
1572                         goto cleanup;
1573                 }
1574
1575                 cmd.chanlist = chanlist;
1576         }
1577
1578         ret = s->do_cmdtest(dev, s, &cmd);
1579
1580         /* restore chanlist pointer before copying back */
1581         cmd.chanlist = (unsigned int __force *)user_chanlist;
1582
1583         if (copy_to_user(arg, &cmd, sizeof(cmd))) {
1584                 DPRINTK("bad cmd address\n");
1585                 ret = -EFAULT;
1586                 goto cleanup;
1587         }
1588 cleanup:
1589         kfree(chanlist);
1590
1591         return ret;
1592 }
1593
1594 /*
1595         COMEDI_LOCK
1596         lock subdevice
1597
1598         arg:
1599                 subdevice number
1600
1601         reads:
1602                 none
1603
1604         writes:
1605                 none
1606
1607 */
1608
1609 static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
1610                          void *file)
1611 {
1612         int ret = 0;
1613         unsigned long flags;
1614         struct comedi_subdevice *s;
1615
1616         if (arg >= dev->n_subdevices)
1617                 return -EINVAL;
1618         s = &dev->subdevices[arg];
1619
1620         spin_lock_irqsave(&s->spin_lock, flags);
1621         if (s->busy || s->lock)
1622                 ret = -EBUSY;
1623         else
1624                 s->lock = file;
1625         spin_unlock_irqrestore(&s->spin_lock, flags);
1626
1627 #if 0
1628         if (ret < 0)
1629                 return ret;
1630
1631         if (s->lock_f)
1632                 ret = s->lock_f(dev, s);
1633 #endif
1634
1635         return ret;
1636 }
1637
1638 /*
1639         COMEDI_UNLOCK
1640         unlock subdevice
1641
1642         arg:
1643                 subdevice number
1644
1645         reads:
1646                 none
1647
1648         writes:
1649                 none
1650
1651         This function isn't protected by the semaphore, since
1652         we already own the lock.
1653 */
1654 static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg,
1655                            void *file)
1656 {
1657         struct comedi_subdevice *s;
1658
1659         if (arg >= dev->n_subdevices)
1660                 return -EINVAL;
1661         s = &dev->subdevices[arg];
1662
1663         if (s->busy)
1664                 return -EBUSY;
1665
1666         if (s->lock && s->lock != file)
1667                 return -EACCES;
1668
1669         if (s->lock == file) {
1670 #if 0
1671                 if (s->unlock)
1672                         s->unlock(dev, s);
1673 #endif
1674
1675                 s->lock = NULL;
1676         }
1677
1678         return 0;
1679 }
1680
1681 /*
1682         COMEDI_CANCEL
1683         cancel acquisition ioctl
1684
1685         arg:
1686                 subdevice number
1687
1688         reads:
1689                 nothing
1690
1691         writes:
1692                 nothing
1693
1694 */
1695 static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
1696                            void *file)
1697 {
1698         struct comedi_subdevice *s;
1699         int ret;
1700
1701         if (arg >= dev->n_subdevices)
1702                 return -EINVAL;
1703         s = &dev->subdevices[arg];
1704         if (s->async == NULL)
1705                 return -EINVAL;
1706
1707         if (s->lock && s->lock != file)
1708                 return -EACCES;
1709
1710         if (!s->busy)
1711                 return 0;
1712
1713         if (s->busy != file)
1714                 return -EBUSY;
1715
1716         ret = do_cancel(dev, s);
1717         if (comedi_get_subdevice_runflags(s) & SRF_USER)
1718                 wake_up_interruptible(&s->async->wait_head);
1719
1720         return ret;
1721 }
1722
1723 /*
1724         COMEDI_POLL ioctl
1725         instructs driver to synchronize buffers
1726
1727         arg:
1728                 subdevice number
1729
1730         reads:
1731                 nothing
1732
1733         writes:
1734                 nothing
1735
1736 */
1737 static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
1738                          void *file)
1739 {
1740         struct comedi_subdevice *s;
1741
1742         if (arg >= dev->n_subdevices)
1743                 return -EINVAL;
1744         s = &dev->subdevices[arg];
1745
1746         if (s->lock && s->lock != file)
1747                 return -EACCES;
1748
1749         if (!s->busy)
1750                 return 0;
1751
1752         if (s->busy != file)
1753                 return -EBUSY;
1754
1755         if (s->poll)
1756                 return s->poll(dev, s);
1757
1758         return -EINVAL;
1759 }
1760
1761 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
1762                                   unsigned long arg)
1763 {
1764         const unsigned minor = iminor(file_inode(file));
1765         struct comedi_device *dev = comedi_dev_from_minor(minor);
1766         int rc;
1767
1768         if (!dev)
1769                 return -ENODEV;
1770
1771         mutex_lock(&dev->mutex);
1772
1773         /* Device config is special, because it must work on
1774          * an unconfigured device. */
1775         if (cmd == COMEDI_DEVCONFIG) {
1776                 if (minor >= COMEDI_NUM_BOARD_MINORS) {
1777                         /* Device config not appropriate on non-board minors. */
1778                         rc = -ENOTTY;
1779                         goto done;
1780                 }
1781                 rc = do_devconfig_ioctl(dev,
1782                                         (struct comedi_devconfig __user *)arg);
1783                 if (rc == 0) {
1784                         if (arg == 0 &&
1785                             dev->minor >= comedi_num_legacy_minors) {
1786                                 /* Successfully unconfigured a dynamically
1787                                  * allocated device.  Try and remove it. */
1788                                 if (comedi_clear_board_dev(dev)) {
1789                                         mutex_unlock(&dev->mutex);
1790                                         comedi_free_board_dev(dev);
1791                                         return rc;
1792                                 }
1793                         }
1794                 }
1795                 goto done;
1796         }
1797
1798         if (!dev->attached) {
1799                 DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor);
1800                 rc = -ENODEV;
1801                 goto done;
1802         }
1803
1804         switch (cmd) {
1805         case COMEDI_BUFCONFIG:
1806                 rc = do_bufconfig_ioctl(dev,
1807                                         (struct comedi_bufconfig __user *)arg);
1808                 break;
1809         case COMEDI_DEVINFO:
1810                 rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg,
1811                                       file);
1812                 break;
1813         case COMEDI_SUBDINFO:
1814                 rc = do_subdinfo_ioctl(dev,
1815                                        (struct comedi_subdinfo __user *)arg,
1816                                        file);
1817                 break;
1818         case COMEDI_CHANINFO:
1819                 rc = do_chaninfo_ioctl(dev, (void __user *)arg);
1820                 break;
1821         case COMEDI_RANGEINFO:
1822                 rc = do_rangeinfo_ioctl(dev, (void __user *)arg);
1823                 break;
1824         case COMEDI_BUFINFO:
1825                 rc = do_bufinfo_ioctl(dev,
1826                                       (struct comedi_bufinfo __user *)arg,
1827                                       file);
1828                 break;
1829         case COMEDI_LOCK:
1830                 rc = do_lock_ioctl(dev, arg, file);
1831                 break;
1832         case COMEDI_UNLOCK:
1833                 rc = do_unlock_ioctl(dev, arg, file);
1834                 break;
1835         case COMEDI_CANCEL:
1836                 rc = do_cancel_ioctl(dev, arg, file);
1837                 break;
1838         case COMEDI_CMD:
1839                 rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file);
1840                 break;
1841         case COMEDI_CMDTEST:
1842                 rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg,
1843                                       file);
1844                 break;
1845         case COMEDI_INSNLIST:
1846                 rc = do_insnlist_ioctl(dev,
1847                                        (struct comedi_insnlist __user *)arg,
1848                                        file);
1849                 break;
1850         case COMEDI_INSN:
1851                 rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg,
1852                                    file);
1853                 break;
1854         case COMEDI_POLL:
1855                 rc = do_poll_ioctl(dev, arg, file);
1856                 break;
1857         default:
1858                 rc = -ENOTTY;
1859                 break;
1860         }
1861
1862 done:
1863         mutex_unlock(&dev->mutex);
1864         return rc;
1865 }
1866
1867 static void comedi_vm_open(struct vm_area_struct *area)
1868 {
1869         struct comedi_async *async;
1870         struct comedi_device *dev;
1871
1872         async = area->vm_private_data;
1873         dev = async->subdevice->device;
1874
1875         mutex_lock(&dev->mutex);
1876         async->mmap_count++;
1877         mutex_unlock(&dev->mutex);
1878 }
1879
1880 static void comedi_vm_close(struct vm_area_struct *area)
1881 {
1882         struct comedi_async *async;
1883         struct comedi_device *dev;
1884
1885         async = area->vm_private_data;
1886         dev = async->subdevice->device;
1887
1888         mutex_lock(&dev->mutex);
1889         async->mmap_count--;
1890         mutex_unlock(&dev->mutex);
1891 }
1892
1893 static struct vm_operations_struct comedi_vm_ops = {
1894         .open = comedi_vm_open,
1895         .close = comedi_vm_close,
1896 };
1897
1898 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1899 {
1900         const unsigned minor = iminor(file_inode(file));
1901         struct comedi_device *dev = comedi_dev_from_minor(minor);
1902         struct comedi_subdevice *s;
1903         struct comedi_async *async;
1904         unsigned long start = vma->vm_start;
1905         unsigned long size;
1906         int n_pages;
1907         int i;
1908         int retval;
1909
1910         if (!dev)
1911                 return -ENODEV;
1912
1913         mutex_lock(&dev->mutex);
1914
1915         if (!dev->attached) {
1916                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
1917                 retval = -ENODEV;
1918                 goto done;
1919         }
1920
1921         if (vma->vm_flags & VM_WRITE)
1922                 s = comedi_write_subdevice(dev, minor);
1923         else
1924                 s = comedi_read_subdevice(dev, minor);
1925         if (!s) {
1926                 retval = -EINVAL;
1927                 goto done;
1928         }
1929
1930         async = s->async;
1931         if (!async) {
1932                 retval = -EINVAL;
1933                 goto done;
1934         }
1935
1936         if (vma->vm_pgoff != 0) {
1937                 DPRINTK("comedi: mmap() offset must be 0.\n");
1938                 retval = -EINVAL;
1939                 goto done;
1940         }
1941
1942         size = vma->vm_end - vma->vm_start;
1943         if (size > async->prealloc_bufsz) {
1944                 retval = -EFAULT;
1945                 goto done;
1946         }
1947         if (size & (~PAGE_MASK)) {
1948                 retval = -EFAULT;
1949                 goto done;
1950         }
1951
1952         n_pages = size >> PAGE_SHIFT;
1953         for (i = 0; i < n_pages; ++i) {
1954                 struct comedi_buf_page *buf = &async->buf_page_list[i];
1955
1956                 if (remap_pfn_range(vma, start,
1957                                     page_to_pfn(virt_to_page(buf->virt_addr)),
1958                                     PAGE_SIZE, PAGE_SHARED)) {
1959                         retval = -EAGAIN;
1960                         goto done;
1961                 }
1962                 start += PAGE_SIZE;
1963         }
1964
1965         vma->vm_ops = &comedi_vm_ops;
1966         vma->vm_private_data = async;
1967
1968         async->mmap_count++;
1969
1970         retval = 0;
1971 done:
1972         mutex_unlock(&dev->mutex);
1973         return retval;
1974 }
1975
1976 static unsigned int comedi_poll(struct file *file, poll_table *wait)
1977 {
1978         unsigned int mask = 0;
1979         const unsigned minor = iminor(file_inode(file));
1980         struct comedi_device *dev = comedi_dev_from_minor(minor);
1981         struct comedi_subdevice *s;
1982
1983         if (!dev)
1984                 return -ENODEV;
1985
1986         mutex_lock(&dev->mutex);
1987
1988         if (!dev->attached) {
1989                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
1990                 goto done;
1991         }
1992
1993         s = comedi_read_subdevice(dev, minor);
1994         if (s && s->async) {
1995                 poll_wait(file, &s->async->wait_head, wait);
1996                 if (!s->busy || !comedi_is_subdevice_running(s) ||
1997                     comedi_buf_read_n_available(s->async) > 0)
1998                         mask |= POLLIN | POLLRDNORM;
1999         }
2000
2001         s = comedi_write_subdevice(dev, minor);
2002         if (s && s->async) {
2003                 unsigned int bps = bytes_per_sample(s->async->subdevice);
2004
2005                 poll_wait(file, &s->async->wait_head, wait);
2006                 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
2007                 if (!s->busy || !comedi_is_subdevice_running(s) ||
2008                     comedi_buf_write_n_allocated(s->async) >= bps)
2009                         mask |= POLLOUT | POLLWRNORM;
2010         }
2011
2012 done:
2013         mutex_unlock(&dev->mutex);
2014         return mask;
2015 }
2016
2017 static ssize_t comedi_write(struct file *file, const char __user *buf,
2018                             size_t nbytes, loff_t *offset)
2019 {
2020         struct comedi_subdevice *s;
2021         struct comedi_async *async;
2022         int n, m, count = 0, retval = 0;
2023         DECLARE_WAITQUEUE(wait, current);
2024         const unsigned minor = iminor(file_inode(file));
2025         struct comedi_device *dev = comedi_dev_from_minor(minor);
2026
2027         if (!dev)
2028                 return -ENODEV;
2029
2030         if (!dev->attached) {
2031                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
2032                 return -ENODEV;
2033         }
2034
2035         s = comedi_write_subdevice(dev, minor);
2036         if (!s || !s->async)
2037                 return -EIO;
2038
2039         async = s->async;
2040
2041         if (!s->busy || !nbytes)
2042                 return 0;
2043         if (s->busy != file)
2044                 return -EACCES;
2045
2046         add_wait_queue(&async->wait_head, &wait);
2047         while (nbytes > 0 && !retval) {
2048                 set_current_state(TASK_INTERRUPTIBLE);
2049
2050                 if (!comedi_is_subdevice_running(s)) {
2051                         if (count == 0) {
2052                                 mutex_lock(&dev->mutex);
2053                                 if (comedi_is_subdevice_in_error(s))
2054                                         retval = -EPIPE;
2055                                 else
2056                                         retval = 0;
2057                                 do_become_nonbusy(dev, s);
2058                                 mutex_unlock(&dev->mutex);
2059                         }
2060                         break;
2061                 }
2062
2063                 n = nbytes;
2064
2065                 m = n;
2066                 if (async->buf_write_ptr + m > async->prealloc_bufsz)
2067                         m = async->prealloc_bufsz - async->buf_write_ptr;
2068                 comedi_buf_write_alloc(async, async->prealloc_bufsz);
2069                 if (m > comedi_buf_write_n_allocated(async))
2070                         m = comedi_buf_write_n_allocated(async);
2071                 if (m < n)
2072                         n = m;
2073
2074                 if (n == 0) {
2075                         if (file->f_flags & O_NONBLOCK) {
2076                                 retval = -EAGAIN;
2077                                 break;
2078                         }
2079                         schedule();
2080                         if (signal_pending(current)) {
2081                                 retval = -ERESTARTSYS;
2082                                 break;
2083                         }
2084                         if (!s->busy)
2085                                 break;
2086                         if (s->busy != file) {
2087                                 retval = -EACCES;
2088                                 break;
2089                         }
2090                         continue;
2091                 }
2092
2093                 m = copy_from_user(async->prealloc_buf + async->buf_write_ptr,
2094                                    buf, n);
2095                 if (m) {
2096                         n -= m;
2097                         retval = -EFAULT;
2098                 }
2099                 comedi_buf_write_free(async, n);
2100
2101                 count += n;
2102                 nbytes -= n;
2103
2104                 buf += n;
2105                 break;          /* makes device work like a pipe */
2106         }
2107         set_current_state(TASK_RUNNING);
2108         remove_wait_queue(&async->wait_head, &wait);
2109
2110         return count ? count : retval;
2111 }
2112
2113 static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
2114                                 loff_t *offset)
2115 {
2116         struct comedi_subdevice *s;
2117         struct comedi_async *async;
2118         int n, m, count = 0, retval = 0;
2119         DECLARE_WAITQUEUE(wait, current);
2120         const unsigned minor = iminor(file_inode(file));
2121         struct comedi_device *dev = comedi_dev_from_minor(minor);
2122
2123         if (!dev)
2124                 return -ENODEV;
2125
2126         if (!dev->attached) {
2127                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
2128                 return -ENODEV;
2129         }
2130
2131         s = comedi_read_subdevice(dev, minor);
2132         if (!s || !s->async)
2133                 return -EIO;
2134
2135         async = s->async;
2136         if (!s->busy || !nbytes)
2137                 return 0;
2138         if (s->busy != file)
2139                 return -EACCES;
2140
2141         add_wait_queue(&async->wait_head, &wait);
2142         while (nbytes > 0 && !retval) {
2143                 set_current_state(TASK_INTERRUPTIBLE);
2144
2145                 n = nbytes;
2146
2147                 m = comedi_buf_read_n_available(async);
2148                 /* printk("%d available\n",m); */
2149                 if (async->buf_read_ptr + m > async->prealloc_bufsz)
2150                         m = async->prealloc_bufsz - async->buf_read_ptr;
2151                 /* printk("%d contiguous\n",m); */
2152                 if (m < n)
2153                         n = m;
2154
2155                 if (n == 0) {
2156                         if (!comedi_is_subdevice_running(s)) {
2157                                 mutex_lock(&dev->mutex);
2158                                 do_become_nonbusy(dev, s);
2159                                 if (comedi_is_subdevice_in_error(s))
2160                                         retval = -EPIPE;
2161                                 else
2162                                         retval = 0;
2163                                 mutex_unlock(&dev->mutex);
2164                                 break;
2165                         }
2166                         if (file->f_flags & O_NONBLOCK) {
2167                                 retval = -EAGAIN;
2168                                 break;
2169                         }
2170                         schedule();
2171                         if (signal_pending(current)) {
2172                                 retval = -ERESTARTSYS;
2173                                 break;
2174                         }
2175                         if (!s->busy) {
2176                                 retval = 0;
2177                                 break;
2178                         }
2179                         if (s->busy != file) {
2180                                 retval = -EACCES;
2181                                 break;
2182                         }
2183                         continue;
2184                 }
2185                 m = copy_to_user(buf, async->prealloc_buf +
2186                                  async->buf_read_ptr, n);
2187                 if (m) {
2188                         n -= m;
2189                         retval = -EFAULT;
2190                 }
2191
2192                 comedi_buf_read_alloc(async, n);
2193                 comedi_buf_read_free(async, n);
2194
2195                 count += n;
2196                 nbytes -= n;
2197
2198                 buf += n;
2199                 break;          /* makes device work like a pipe */
2200         }
2201         if (comedi_is_subdevice_idle(s)) {
2202                 mutex_lock(&dev->mutex);
2203                 if (async->buf_read_count - async->buf_write_count == 0)
2204                         do_become_nonbusy(dev, s);
2205                 mutex_unlock(&dev->mutex);
2206         }
2207         set_current_state(TASK_RUNNING);
2208         remove_wait_queue(&async->wait_head, &wait);
2209
2210         return count ? count : retval;
2211 }
2212
2213 static int comedi_open(struct inode *inode, struct file *file)
2214 {
2215         const unsigned minor = iminor(inode);
2216         struct comedi_device *dev = comedi_dev_from_minor(minor);
2217
2218         if (!dev) {
2219                 DPRINTK("invalid minor number\n");
2220                 return -ENODEV;
2221         }
2222
2223         /* This is slightly hacky, but we want module autoloading
2224          * to work for root.
2225          * case: user opens device, attached -> ok
2226          * case: user opens device, unattached, !in_request_module -> autoload
2227          * case: user opens device, unattached, in_request_module -> fail
2228          * case: root opens device, attached -> ok
2229          * case: root opens device, unattached, in_request_module -> ok
2230          *   (typically called from modprobe)
2231          * case: root opens device, unattached, !in_request_module -> autoload
2232          *
2233          * The last could be changed to "-> ok", which would deny root
2234          * autoloading.
2235          */
2236         mutex_lock(&dev->mutex);
2237         if (dev->attached)
2238                 goto ok;
2239         if (!capable(CAP_NET_ADMIN) && dev->in_request_module) {
2240                 DPRINTK("in request module\n");
2241                 mutex_unlock(&dev->mutex);
2242                 return -ENODEV;
2243         }
2244         if (capable(CAP_NET_ADMIN) && dev->in_request_module)
2245                 goto ok;
2246
2247         dev->in_request_module = true;
2248
2249 #ifdef CONFIG_KMOD
2250         mutex_unlock(&dev->mutex);
2251         request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
2252         mutex_lock(&dev->mutex);
2253 #endif
2254
2255         dev->in_request_module = false;
2256
2257         if (!dev->attached && !capable(CAP_NET_ADMIN)) {
2258                 DPRINTK("not attached and not CAP_NET_ADMIN\n");
2259                 mutex_unlock(&dev->mutex);
2260                 return -ENODEV;
2261         }
2262 ok:
2263         __module_get(THIS_MODULE);
2264
2265         if (dev->attached) {
2266                 if (!try_module_get(dev->driver->module)) {
2267                         module_put(THIS_MODULE);
2268                         mutex_unlock(&dev->mutex);
2269                         return -ENOSYS;
2270                 }
2271         }
2272
2273         if (dev->attached && dev->use_count == 0 && dev->open) {
2274                 int rc = dev->open(dev);
2275                 if (rc < 0) {
2276                         module_put(dev->driver->module);
2277                         module_put(THIS_MODULE);
2278                         mutex_unlock(&dev->mutex);
2279                         return rc;
2280                 }
2281         }
2282
2283         dev->use_count++;
2284
2285         mutex_unlock(&dev->mutex);
2286
2287         return 0;
2288 }
2289
2290 static int comedi_fasync(int fd, struct file *file, int on)
2291 {
2292         const unsigned minor = iminor(file_inode(file));
2293         struct comedi_device *dev = comedi_dev_from_minor(minor);
2294
2295         if (!dev)
2296                 return -ENODEV;
2297
2298         return fasync_helper(fd, file, on, &dev->async_queue);
2299 }
2300
2301 static int comedi_close(struct inode *inode, struct file *file)
2302 {
2303         const unsigned minor = iminor(inode);
2304         struct comedi_device *dev = comedi_dev_from_minor(minor);
2305         struct comedi_subdevice *s = NULL;
2306         int i;
2307
2308         if (!dev)
2309                 return -ENODEV;
2310
2311         mutex_lock(&dev->mutex);
2312
2313         if (dev->subdevices) {
2314                 for (i = 0; i < dev->n_subdevices; i++) {
2315                         s = &dev->subdevices[i];
2316
2317                         if (s->busy == file)
2318                                 do_cancel(dev, s);
2319                         if (s->lock == file)
2320                                 s->lock = NULL;
2321                 }
2322         }
2323         if (dev->attached && dev->use_count == 1 && dev->close)
2324                 dev->close(dev);
2325
2326         module_put(THIS_MODULE);
2327         if (dev->attached)
2328                 module_put(dev->driver->module);
2329
2330         dev->use_count--;
2331
2332         mutex_unlock(&dev->mutex);
2333
2334         return 0;
2335 }
2336
2337 static const struct file_operations comedi_fops = {
2338         .owner = THIS_MODULE,
2339         .unlocked_ioctl = comedi_unlocked_ioctl,
2340         .compat_ioctl = comedi_compat_ioctl,
2341         .open = comedi_open,
2342         .release = comedi_close,
2343         .read = comedi_read,
2344         .write = comedi_write,
2345         .mmap = comedi_mmap,
2346         .poll = comedi_poll,
2347         .fasync = comedi_fasync,
2348         .llseek = noop_llseek,
2349 };
2350
2351 void comedi_error(const struct comedi_device *dev, const char *s)
2352 {
2353         dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
2354 }
2355 EXPORT_SYMBOL_GPL(comedi_error);
2356
2357 void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
2358 {
2359         struct comedi_async *async = s->async;
2360         unsigned runflags = 0;
2361         unsigned runflags_mask = 0;
2362
2363         /* DPRINTK("comedi_event 0x%x\n",mask); */
2364
2365         if (!comedi_is_subdevice_running(s))
2366                 return;
2367
2368         if (s->
2369             async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2370                              COMEDI_CB_OVERFLOW)) {
2371                 runflags_mask |= SRF_RUNNING;
2372         }
2373         /* remember if an error event has occurred, so an error
2374          * can be returned the next time the user does a read() */
2375         if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
2376                 runflags_mask |= SRF_ERROR;
2377                 runflags |= SRF_ERROR;
2378         }
2379         if (runflags_mask) {
2380                 /*sets SRF_ERROR and SRF_RUNNING together atomically */
2381                 comedi_set_subdevice_runflags(s, runflags_mask, runflags);
2382         }
2383
2384         if (async->cb_mask & s->async->events) {
2385                 if (comedi_get_subdevice_runflags(s) & SRF_USER) {
2386                         wake_up_interruptible(&async->wait_head);
2387                         if (s->subdev_flags & SDF_CMD_READ)
2388                                 kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
2389                         if (s->subdev_flags & SDF_CMD_WRITE)
2390                                 kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
2391                 } else {
2392                         if (async->cb_func)
2393                                 async->cb_func(s->async->events, async->cb_arg);
2394                 }
2395         }
2396         s->async->events = 0;
2397 }
2398 EXPORT_SYMBOL_GPL(comedi_event);
2399
2400 /* Note: the ->mutex is pre-locked on successful return */
2401 struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
2402 {
2403         struct comedi_device *dev;
2404         struct device *csdev;
2405         unsigned i;
2406
2407         dev = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
2408         if (dev == NULL)
2409                 return ERR_PTR(-ENOMEM);
2410         comedi_device_init(dev);
2411         comedi_set_hw_dev(dev, hardware_device);
2412         mutex_lock(&dev->mutex);
2413         mutex_lock(&comedi_board_minor_table_lock);
2414         for (i = hardware_device ? comedi_num_legacy_minors : 0;
2415              i < COMEDI_NUM_BOARD_MINORS; ++i) {
2416                 if (comedi_board_minor_table[i] == NULL) {
2417                         comedi_board_minor_table[i] = dev;
2418                         break;
2419                 }
2420         }
2421         mutex_unlock(&comedi_board_minor_table_lock);
2422         if (i == COMEDI_NUM_BOARD_MINORS) {
2423                 mutex_unlock(&dev->mutex);
2424                 comedi_device_cleanup(dev);
2425                 kfree(dev);
2426                 pr_err("comedi: error: ran out of minor numbers for board device files.\n");
2427                 return ERR_PTR(-EBUSY);
2428         }
2429         dev->minor = i;
2430         csdev = device_create(comedi_class, hardware_device,
2431                               MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
2432         if (!IS_ERR(csdev))
2433                 dev->class_dev = csdev;
2434
2435         /* Note: dev->mutex needs to be unlocked by the caller. */
2436         return dev;
2437 }
2438
2439 static void comedi_free_board_minor(unsigned minor)
2440 {
2441         BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
2442         comedi_free_board_dev(comedi_clear_board_minor(minor));
2443 }
2444
2445 void comedi_release_hardware_device(struct device *hardware_device)
2446 {
2447         int minor;
2448         struct comedi_device *dev;
2449
2450         for (minor = comedi_num_legacy_minors; minor < COMEDI_NUM_BOARD_MINORS;
2451              minor++) {
2452                 mutex_lock(&comedi_board_minor_table_lock);
2453                 dev = comedi_board_minor_table[minor];
2454                 if (dev && dev->hw_dev == hardware_device) {
2455                         comedi_board_minor_table[minor] = NULL;
2456                         mutex_unlock(&comedi_board_minor_table_lock);
2457                         comedi_free_board_dev(dev);
2458                         break;
2459                 }
2460                 mutex_unlock(&comedi_board_minor_table_lock);
2461         }
2462 }
2463
2464 int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
2465 {
2466         struct comedi_device *dev = s->device;
2467         struct device *csdev;
2468         unsigned i;
2469
2470         mutex_lock(&comedi_subdevice_minor_table_lock);
2471         for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
2472                 if (comedi_subdevice_minor_table[i] == NULL) {
2473                         comedi_subdevice_minor_table[i] = s;
2474                         break;
2475                 }
2476         }
2477         mutex_unlock(&comedi_subdevice_minor_table_lock);
2478         if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
2479                 pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
2480                 return -EBUSY;
2481         }
2482         i += COMEDI_NUM_BOARD_MINORS;
2483         s->minor = i;
2484         csdev = device_create(comedi_class, dev->class_dev,
2485                               MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i",
2486                               dev->minor, s->index);
2487         if (!IS_ERR(csdev))
2488                 s->class_dev = csdev;
2489
2490         return 0;
2491 }
2492
2493 void comedi_free_subdevice_minor(struct comedi_subdevice *s)
2494 {
2495         unsigned int i;
2496
2497         if (s == NULL)
2498                 return;
2499         if (s->minor < 0)
2500                 return;
2501
2502         BUG_ON(s->minor >= COMEDI_NUM_MINORS);
2503         BUG_ON(s->minor < COMEDI_NUM_BOARD_MINORS);
2504
2505         i = s->minor - COMEDI_NUM_BOARD_MINORS;
2506         mutex_lock(&comedi_subdevice_minor_table_lock);
2507         if (s == comedi_subdevice_minor_table[i])
2508                 comedi_subdevice_minor_table[i] = NULL;
2509         mutex_unlock(&comedi_subdevice_minor_table_lock);
2510         if (s->class_dev) {
2511                 device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
2512                 s->class_dev = NULL;
2513         }
2514 }
2515
2516 static void comedi_cleanup_board_minors(void)
2517 {
2518         unsigned i;
2519
2520         for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++)
2521                 comedi_free_board_minor(i);
2522 }
2523
2524 static int __init comedi_init(void)
2525 {
2526         int i;
2527         int retval;
2528
2529         pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
2530
2531         if (comedi_num_legacy_minors < 0 ||
2532             comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
2533                 pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\".  Valid values are 0 through %i.\n",
2534                        COMEDI_NUM_BOARD_MINORS);
2535                 return -EINVAL;
2536         }
2537
2538         retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2539                                         COMEDI_NUM_MINORS, "comedi");
2540         if (retval)
2541                 return -EIO;
2542         cdev_init(&comedi_cdev, &comedi_fops);
2543         comedi_cdev.owner = THIS_MODULE;
2544         kobject_set_name(&comedi_cdev.kobj, "comedi");
2545         if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
2546                 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2547                                          COMEDI_NUM_MINORS);
2548                 return -EIO;
2549         }
2550         comedi_class = class_create(THIS_MODULE, "comedi");
2551         if (IS_ERR(comedi_class)) {
2552                 pr_err("comedi: failed to create class\n");
2553                 cdev_del(&comedi_cdev);
2554                 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2555                                          COMEDI_NUM_MINORS);
2556                 return PTR_ERR(comedi_class);
2557         }
2558
2559         comedi_class->dev_groups = comedi_dev_groups;
2560
2561         /* XXX requires /proc interface */
2562         comedi_proc_init();
2563
2564         /* create devices files for legacy/manual use */
2565         for (i = 0; i < comedi_num_legacy_minors; i++) {
2566                 struct comedi_device *dev;
2567                 dev = comedi_alloc_board_minor(NULL);
2568                 if (IS_ERR(dev)) {
2569                         comedi_cleanup_board_minors();
2570                         cdev_del(&comedi_cdev);
2571                         unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2572                                                  COMEDI_NUM_MINORS);
2573                         return PTR_ERR(dev);
2574                 } else {
2575                         /* comedi_alloc_board_minor() locked the mutex */
2576                         mutex_unlock(&dev->mutex);
2577                 }
2578         }
2579
2580         return 0;
2581 }
2582 module_init(comedi_init);
2583
2584 static void __exit comedi_cleanup(void)
2585 {
2586         int i;
2587
2588         comedi_cleanup_board_minors();
2589         for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i)
2590                 BUG_ON(comedi_board_minor_table[i]);
2591         for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i)
2592                 BUG_ON(comedi_subdevice_minor_table[i]);
2593
2594         class_destroy(comedi_class);
2595         cdev_del(&comedi_cdev);
2596         unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
2597
2598         comedi_proc_cleanup();
2599 }
2600 module_exit(comedi_cleanup);
2601
2602 MODULE_AUTHOR("http://www.comedi.org");
2603 MODULE_DESCRIPTION("Comedi core module");
2604 MODULE_LICENSE("GPL");