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