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