staging: comedi: cancel commands before detaching device
[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                 s->busy = NULL;
567                 wake_up_interruptible_all(&s->async->wait_head);
568         } else {
569                 dev_err(dev->class_dev,
570                         "BUG: (?) do_become_nonbusy called with async=NULL\n");
571                 s->busy = NULL;
572         }
573 }
574
575 static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
576 {
577         int ret = 0;
578
579         if (comedi_is_subdevice_running(s) && s->cancel)
580                 ret = s->cancel(dev, s);
581
582         do_become_nonbusy(dev, s);
583
584         return ret;
585 }
586
587 void comedi_device_cancel_all(struct comedi_device *dev)
588 {
589         struct comedi_subdevice *s;
590         int i;
591
592         if (!dev->attached)
593                 return;
594
595         for (i = 0; i < dev->n_subdevices; i++) {
596                 s = &dev->subdevices[i];
597                 if (s->async)
598                         do_cancel(dev, s);
599         }
600 }
601
602 static int is_device_busy(struct comedi_device *dev)
603 {
604         struct comedi_subdevice *s;
605         int i;
606
607         if (!dev->attached)
608                 return 0;
609
610         for (i = 0; i < dev->n_subdevices; i++) {
611                 s = &dev->subdevices[i];
612                 if (s->busy)
613                         return 1;
614                 if (s->async && s->async->mmap_count)
615                         return 1;
616         }
617
618         return 0;
619 }
620
621 /*
622         COMEDI_DEVCONFIG
623         device config ioctl
624
625         arg:
626                 pointer to devconfig structure
627
628         reads:
629                 devconfig structure at arg
630
631         writes:
632                 none
633 */
634 static int do_devconfig_ioctl(struct comedi_device *dev,
635                               struct comedi_devconfig __user *arg)
636 {
637         struct comedi_devconfig it;
638
639         if (!capable(CAP_SYS_ADMIN))
640                 return -EPERM;
641
642         if (arg == NULL) {
643                 if (is_device_busy(dev))
644                         return -EBUSY;
645                 if (dev->attached) {
646                         struct module *driver_module = dev->driver->module;
647                         comedi_device_detach(dev);
648                         module_put(driver_module);
649                 }
650                 return 0;
651         }
652
653         if (copy_from_user(&it, arg, sizeof(it)))
654                 return -EFAULT;
655
656         it.board_name[COMEDI_NAMELEN - 1] = 0;
657
658         if (it.options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
659                 dev_warn(dev->class_dev,
660                          "comedi_config --init_data is deprecated\n");
661                 return -EINVAL;
662         }
663
664         if (dev->minor >= comedi_num_legacy_minors)
665                 /* don't re-use dynamically allocated comedi devices */
666                 return -EBUSY;
667
668         /* This increments the driver module count on success. */
669         return comedi_device_attach(dev, &it);
670 }
671
672 /*
673         COMEDI_BUFCONFIG
674         buffer configuration ioctl
675
676         arg:
677                 pointer to bufconfig structure
678
679         reads:
680                 bufconfig at arg
681
682         writes:
683                 modified bufconfig at arg
684
685 */
686 static int do_bufconfig_ioctl(struct comedi_device *dev,
687                               struct comedi_bufconfig __user *arg)
688 {
689         struct comedi_bufconfig bc;
690         struct comedi_async *async;
691         struct comedi_subdevice *s;
692         int retval = 0;
693
694         if (copy_from_user(&bc, arg, sizeof(bc)))
695                 return -EFAULT;
696
697         if (bc.subdevice >= dev->n_subdevices)
698                 return -EINVAL;
699
700         s = &dev->subdevices[bc.subdevice];
701         async = s->async;
702
703         if (!async) {
704                 DPRINTK("subdevice does not have async capability\n");
705                 bc.size = 0;
706                 bc.maximum_size = 0;
707                 goto copyback;
708         }
709
710         if (bc.maximum_size) {
711                 if (!capable(CAP_SYS_ADMIN))
712                         return -EPERM;
713
714                 async->max_bufsize = bc.maximum_size;
715         }
716
717         if (bc.size) {
718                 retval = resize_async_buffer(dev, s, async, bc.size);
719                 if (retval < 0)
720                         return retval;
721         }
722
723         bc.size = async->prealloc_bufsz;
724         bc.maximum_size = async->max_bufsize;
725
726 copyback:
727         if (copy_to_user(arg, &bc, sizeof(bc)))
728                 return -EFAULT;
729
730         return 0;
731 }
732
733 /*
734         COMEDI_DEVINFO
735         device info ioctl
736
737         arg:
738                 pointer to devinfo structure
739
740         reads:
741                 none
742
743         writes:
744                 devinfo structure
745
746 */
747 static int do_devinfo_ioctl(struct comedi_device *dev,
748                             struct comedi_devinfo __user *arg,
749                             struct file *file)
750 {
751         const unsigned minor = iminor(file_inode(file));
752         struct comedi_subdevice *s;
753         struct comedi_devinfo devinfo;
754
755         memset(&devinfo, 0, sizeof(devinfo));
756
757         /* fill devinfo structure */
758         devinfo.version_code = COMEDI_VERSION_CODE;
759         devinfo.n_subdevs = dev->n_subdevices;
760         strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
761         strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
762
763         s = comedi_read_subdevice(dev, minor);
764         if (s)
765                 devinfo.read_subdevice = s->index;
766         else
767                 devinfo.read_subdevice = -1;
768
769         s = comedi_write_subdevice(dev, minor);
770         if (s)
771                 devinfo.write_subdevice = s->index;
772         else
773                 devinfo.write_subdevice = -1;
774
775         if (copy_to_user(arg, &devinfo, sizeof(devinfo)))
776                 return -EFAULT;
777
778         return 0;
779 }
780
781 /*
782         COMEDI_SUBDINFO
783         subdevice info ioctl
784
785         arg:
786                 pointer to array of subdevice info structures
787
788         reads:
789                 none
790
791         writes:
792                 array of subdevice info structures at arg
793
794 */
795 static int do_subdinfo_ioctl(struct comedi_device *dev,
796                              struct comedi_subdinfo __user *arg, void *file)
797 {
798         int ret, i;
799         struct comedi_subdinfo *tmp, *us;
800         struct comedi_subdevice *s;
801
802         tmp = kcalloc(dev->n_subdevices, sizeof(*tmp), GFP_KERNEL);
803         if (!tmp)
804                 return -ENOMEM;
805
806         /* fill subdinfo structs */
807         for (i = 0; i < dev->n_subdevices; i++) {
808                 s = &dev->subdevices[i];
809                 us = tmp + i;
810
811                 us->type = s->type;
812                 us->n_chan = s->n_chan;
813                 us->subd_flags = s->subdev_flags;
814                 if (comedi_is_subdevice_running(s))
815                         us->subd_flags |= SDF_RUNNING;
816 #define TIMER_nanosec 5         /* backwards compatibility */
817                 us->timer_type = TIMER_nanosec;
818                 us->len_chanlist = s->len_chanlist;
819                 us->maxdata = s->maxdata;
820                 if (s->range_table) {
821                         us->range_type =
822                             (i << 24) | (0 << 16) | (s->range_table->length);
823                 } else {
824                         us->range_type = 0;     /* XXX */
825                 }
826
827                 if (s->busy)
828                         us->subd_flags |= SDF_BUSY;
829                 if (s->busy == file)
830                         us->subd_flags |= SDF_BUSY_OWNER;
831                 if (s->lock)
832                         us->subd_flags |= SDF_LOCKED;
833                 if (s->lock == file)
834                         us->subd_flags |= SDF_LOCK_OWNER;
835                 if (!s->maxdata && s->maxdata_list)
836                         us->subd_flags |= SDF_MAXDATA;
837                 if (s->range_table_list)
838                         us->subd_flags |= SDF_RANGETYPE;
839                 if (s->do_cmd)
840                         us->subd_flags |= SDF_CMD;
841
842                 if (s->insn_bits != &insn_inval)
843                         us->insn_bits_support = COMEDI_SUPPORTED;
844                 else
845                         us->insn_bits_support = COMEDI_UNSUPPORTED;
846         }
847
848         ret = copy_to_user(arg, tmp, dev->n_subdevices * sizeof(*tmp));
849
850         kfree(tmp);
851
852         return ret ? -EFAULT : 0;
853 }
854
855 /*
856         COMEDI_CHANINFO
857         subdevice info ioctl
858
859         arg:
860                 pointer to chaninfo structure
861
862         reads:
863                 chaninfo structure at arg
864
865         writes:
866                 arrays at elements of chaninfo structure
867
868 */
869 static int do_chaninfo_ioctl(struct comedi_device *dev,
870                              struct comedi_chaninfo __user *arg)
871 {
872         struct comedi_subdevice *s;
873         struct comedi_chaninfo it;
874
875         if (copy_from_user(&it, arg, sizeof(it)))
876                 return -EFAULT;
877
878         if (it.subdev >= dev->n_subdevices)
879                 return -EINVAL;
880         s = &dev->subdevices[it.subdev];
881
882         if (it.maxdata_list) {
883                 if (s->maxdata || !s->maxdata_list)
884                         return -EINVAL;
885                 if (copy_to_user(it.maxdata_list, s->maxdata_list,
886                                  s->n_chan * sizeof(unsigned int)))
887                         return -EFAULT;
888         }
889
890         if (it.flaglist)
891                 return -EINVAL; /* flaglist not supported */
892
893         if (it.rangelist) {
894                 int i;
895
896                 if (!s->range_table_list)
897                         return -EINVAL;
898                 for (i = 0; i < s->n_chan; i++) {
899                         int x;
900
901                         x = (dev->minor << 28) | (it.subdev << 24) | (i << 16) |
902                             (s->range_table_list[i]->length);
903                         if (put_user(x, it.rangelist + i))
904                                 return -EFAULT;
905                 }
906 #if 0
907                 if (copy_to_user(it.rangelist, s->range_type_list,
908                                  s->n_chan * sizeof(unsigned int)))
909                         return -EFAULT;
910 #endif
911         }
912
913         return 0;
914 }
915
916  /*
917     COMEDI_BUFINFO
918     buffer information ioctl
919
920     arg:
921     pointer to bufinfo structure
922
923     reads:
924     bufinfo at arg
925
926     writes:
927     modified bufinfo at arg
928
929   */
930 static int do_bufinfo_ioctl(struct comedi_device *dev,
931                             struct comedi_bufinfo __user *arg, void *file)
932 {
933         struct comedi_bufinfo bi;
934         struct comedi_subdevice *s;
935         struct comedi_async *async;
936
937         if (copy_from_user(&bi, arg, sizeof(bi)))
938                 return -EFAULT;
939
940         if (bi.subdevice >= dev->n_subdevices)
941                 return -EINVAL;
942
943         s = &dev->subdevices[bi.subdevice];
944
945         if (s->lock && s->lock != file)
946                 return -EACCES;
947
948         async = s->async;
949
950         if (!async) {
951                 DPRINTK("subdevice does not have async capability\n");
952                 bi.buf_write_ptr = 0;
953                 bi.buf_read_ptr = 0;
954                 bi.buf_write_count = 0;
955                 bi.buf_read_count = 0;
956                 bi.bytes_read = 0;
957                 bi.bytes_written = 0;
958                 goto copyback;
959         }
960         if (!s->busy) {
961                 bi.bytes_read = 0;
962                 bi.bytes_written = 0;
963                 goto copyback_position;
964         }
965         if (s->busy != file)
966                 return -EACCES;
967
968         if (bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)) {
969                 bi.bytes_read = comedi_buf_read_alloc(async, bi.bytes_read);
970                 comedi_buf_read_free(async, bi.bytes_read);
971
972                 if (comedi_is_subdevice_idle(s) &&
973                     async->buf_write_count == async->buf_read_count) {
974                         do_become_nonbusy(dev, s);
975                 }
976         }
977
978         if (bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)) {
979                 bi.bytes_written =
980                     comedi_buf_write_alloc(async, bi.bytes_written);
981                 comedi_buf_write_free(async, bi.bytes_written);
982         }
983
984 copyback_position:
985         bi.buf_write_count = async->buf_write_count;
986         bi.buf_write_ptr = async->buf_write_ptr;
987         bi.buf_read_count = async->buf_read_count;
988         bi.buf_read_ptr = async->buf_read_ptr;
989
990 copyback:
991         if (copy_to_user(arg, &bi, sizeof(bi)))
992                 return -EFAULT;
993
994         return 0;
995 }
996
997 static int check_insn_config_length(struct comedi_insn *insn,
998                                     unsigned int *data)
999 {
1000         if (insn->n < 1)
1001                 return -EINVAL;
1002
1003         switch (data[0]) {
1004         case INSN_CONFIG_DIO_OUTPUT:
1005         case INSN_CONFIG_DIO_INPUT:
1006         case INSN_CONFIG_DISARM:
1007         case INSN_CONFIG_RESET:
1008                 if (insn->n == 1)
1009                         return 0;
1010                 break;
1011         case INSN_CONFIG_ARM:
1012         case INSN_CONFIG_DIO_QUERY:
1013         case INSN_CONFIG_BLOCK_SIZE:
1014         case INSN_CONFIG_FILTER:
1015         case INSN_CONFIG_SERIAL_CLOCK:
1016         case INSN_CONFIG_BIDIRECTIONAL_DATA:
1017         case INSN_CONFIG_ALT_SOURCE:
1018         case INSN_CONFIG_SET_COUNTER_MODE:
1019         case INSN_CONFIG_8254_READ_STATUS:
1020         case INSN_CONFIG_SET_ROUTING:
1021         case INSN_CONFIG_GET_ROUTING:
1022         case INSN_CONFIG_GET_PWM_STATUS:
1023         case INSN_CONFIG_PWM_SET_PERIOD:
1024         case INSN_CONFIG_PWM_GET_PERIOD:
1025                 if (insn->n == 2)
1026                         return 0;
1027                 break;
1028         case INSN_CONFIG_SET_GATE_SRC:
1029         case INSN_CONFIG_GET_GATE_SRC:
1030         case INSN_CONFIG_SET_CLOCK_SRC:
1031         case INSN_CONFIG_GET_CLOCK_SRC:
1032         case INSN_CONFIG_SET_OTHER_SRC:
1033         case INSN_CONFIG_GET_COUNTER_STATUS:
1034         case INSN_CONFIG_PWM_SET_H_BRIDGE:
1035         case INSN_CONFIG_PWM_GET_H_BRIDGE:
1036         case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
1037                 if (insn->n == 3)
1038                         return 0;
1039                 break;
1040         case INSN_CONFIG_PWM_OUTPUT:
1041         case INSN_CONFIG_ANALOG_TRIG:
1042                 if (insn->n == 5)
1043                         return 0;
1044                 break;
1045         case INSN_CONFIG_DIGITAL_TRIG:
1046                 if (insn->n == 6)
1047                         return 0;
1048                 break;
1049                 /* by default we allow the insn since we don't have checks for
1050                  * all possible cases yet */
1051         default:
1052                 pr_warn("comedi: No check for data length of config insn id %i is implemented.\n",
1053                         data[0]);
1054                 pr_warn("comedi: Add a check to %s in %s.\n",
1055                         __func__, __FILE__);
1056                 pr_warn("comedi: Assuming n=%i is correct.\n", insn->n);
1057                 return 0;
1058         }
1059         return -EINVAL;
1060 }
1061
1062 static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
1063                       unsigned int *data, void *file)
1064 {
1065         struct comedi_subdevice *s;
1066         int ret = 0;
1067         int i;
1068
1069         if (insn->insn & INSN_MASK_SPECIAL) {
1070                 /* a non-subdevice instruction */
1071
1072                 switch (insn->insn) {
1073                 case INSN_GTOD:
1074                         {
1075                                 struct timeval tv;
1076
1077                                 if (insn->n != 2) {
1078                                         ret = -EINVAL;
1079                                         break;
1080                                 }
1081
1082                                 do_gettimeofday(&tv);
1083                                 data[0] = tv.tv_sec;
1084                                 data[1] = tv.tv_usec;
1085                                 ret = 2;
1086
1087                                 break;
1088                         }
1089                 case INSN_WAIT:
1090                         if (insn->n != 1 || data[0] >= 100000) {
1091                                 ret = -EINVAL;
1092                                 break;
1093                         }
1094                         udelay(data[0] / 1000);
1095                         ret = 1;
1096                         break;
1097                 case INSN_INTTRIG:
1098                         if (insn->n != 1) {
1099                                 ret = -EINVAL;
1100                                 break;
1101                         }
1102                         if (insn->subdev >= dev->n_subdevices) {
1103                                 DPRINTK("%d not usable subdevice\n",
1104                                         insn->subdev);
1105                                 ret = -EINVAL;
1106                                 break;
1107                         }
1108                         s = &dev->subdevices[insn->subdev];
1109                         if (!s->async) {
1110                                 DPRINTK("no async\n");
1111                                 ret = -EINVAL;
1112                                 break;
1113                         }
1114                         if (!s->async->inttrig) {
1115                                 DPRINTK("no inttrig\n");
1116                                 ret = -EAGAIN;
1117                                 break;
1118                         }
1119                         ret = s->async->inttrig(dev, s, data[0]);
1120                         if (ret >= 0)
1121                                 ret = 1;
1122                         break;
1123                 default:
1124                         DPRINTK("invalid insn\n");
1125                         ret = -EINVAL;
1126                         break;
1127                 }
1128         } else {
1129                 /* a subdevice instruction */
1130                 unsigned int maxdata;
1131
1132                 if (insn->subdev >= dev->n_subdevices) {
1133                         DPRINTK("subdevice %d out of range\n", insn->subdev);
1134                         ret = -EINVAL;
1135                         goto out;
1136                 }
1137                 s = &dev->subdevices[insn->subdev];
1138
1139                 if (s->type == COMEDI_SUBD_UNUSED) {
1140                         DPRINTK("%d not usable subdevice\n", insn->subdev);
1141                         ret = -EIO;
1142                         goto out;
1143                 }
1144
1145                 /* are we locked? (ioctl lock) */
1146                 if (s->lock && s->lock != file) {
1147                         DPRINTK("device locked\n");
1148                         ret = -EACCES;
1149                         goto out;
1150                 }
1151
1152                 ret = comedi_check_chanlist(s, 1, &insn->chanspec);
1153                 if (ret < 0) {
1154                         ret = -EINVAL;
1155                         DPRINTK("bad chanspec\n");
1156                         goto out;
1157                 }
1158
1159                 if (s->busy) {
1160                         ret = -EBUSY;
1161                         goto out;
1162                 }
1163                 /* This looks arbitrary.  It is. */
1164                 s->busy = &parse_insn;
1165                 switch (insn->insn) {
1166                 case INSN_READ:
1167                         ret = s->insn_read(dev, s, insn, data);
1168                         break;
1169                 case INSN_WRITE:
1170                         maxdata = s->maxdata_list
1171                             ? s->maxdata_list[CR_CHAN(insn->chanspec)]
1172                             : s->maxdata;
1173                         for (i = 0; i < insn->n; ++i) {
1174                                 if (data[i] > maxdata) {
1175                                         ret = -EINVAL;
1176                                         DPRINTK("bad data value(s)\n");
1177                                         break;
1178                                 }
1179                         }
1180                         if (ret == 0)
1181                                 ret = s->insn_write(dev, s, insn, data);
1182                         break;
1183                 case INSN_BITS:
1184                         if (insn->n != 2) {
1185                                 ret = -EINVAL;
1186                         } else {
1187                                 /* Most drivers ignore the base channel in
1188                                  * insn->chanspec.  Fix this here if
1189                                  * the subdevice has <= 32 channels.  */
1190                                 unsigned int shift;
1191                                 unsigned int orig_mask;
1192
1193                                 orig_mask = data[0];
1194                                 if (s->n_chan <= 32) {
1195                                         shift = CR_CHAN(insn->chanspec);
1196                                         if (shift > 0) {
1197                                                 insn->chanspec = 0;
1198                                                 data[0] <<= shift;
1199                                                 data[1] <<= shift;
1200                                         }
1201                                 } else
1202                                         shift = 0;
1203                                 ret = s->insn_bits(dev, s, insn, data);
1204                                 data[0] = orig_mask;
1205                                 if (shift > 0)
1206                                         data[1] >>= shift;
1207                         }
1208                         break;
1209                 case INSN_CONFIG:
1210                         ret = check_insn_config_length(insn, data);
1211                         if (ret)
1212                                 break;
1213                         ret = s->insn_config(dev, s, insn, data);
1214                         break;
1215                 default:
1216                         ret = -EINVAL;
1217                         break;
1218                 }
1219
1220                 s->busy = NULL;
1221         }
1222
1223 out:
1224         return ret;
1225 }
1226
1227 /*
1228  *      COMEDI_INSNLIST
1229  *      synchronous instructions
1230  *
1231  *      arg:
1232  *              pointer to sync cmd structure
1233  *
1234  *      reads:
1235  *              sync cmd struct at arg
1236  *              instruction list
1237  *              data (for writes)
1238  *
1239  *      writes:
1240  *              data (for reads)
1241  */
1242 /* arbitrary limits */
1243 #define MAX_SAMPLES 256
1244 static int do_insnlist_ioctl(struct comedi_device *dev,
1245                              struct comedi_insnlist __user *arg, void *file)
1246 {
1247         struct comedi_insnlist insnlist;
1248         struct comedi_insn *insns = NULL;
1249         unsigned int *data = NULL;
1250         int i = 0;
1251         int ret = 0;
1252
1253         if (copy_from_user(&insnlist, arg, sizeof(insnlist)))
1254                 return -EFAULT;
1255
1256         data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
1257         if (!data) {
1258                 DPRINTK("kmalloc failed\n");
1259                 ret = -ENOMEM;
1260                 goto error;
1261         }
1262
1263         insns = kcalloc(insnlist.n_insns, sizeof(*insns), GFP_KERNEL);
1264         if (!insns) {
1265                 DPRINTK("kmalloc failed\n");
1266                 ret = -ENOMEM;
1267                 goto error;
1268         }
1269
1270         if (copy_from_user(insns, insnlist.insns,
1271                            sizeof(*insns) * insnlist.n_insns)) {
1272                 DPRINTK("copy_from_user failed\n");
1273                 ret = -EFAULT;
1274                 goto error;
1275         }
1276
1277         for (i = 0; i < insnlist.n_insns; i++) {
1278                 if (insns[i].n > MAX_SAMPLES) {
1279                         DPRINTK("number of samples too large\n");
1280                         ret = -EINVAL;
1281                         goto error;
1282                 }
1283                 if (insns[i].insn & INSN_MASK_WRITE) {
1284                         if (copy_from_user(data, insns[i].data,
1285                                            insns[i].n * sizeof(unsigned int))) {
1286                                 DPRINTK("copy_from_user failed\n");
1287                                 ret = -EFAULT;
1288                                 goto error;
1289                         }
1290                 }
1291                 ret = parse_insn(dev, insns + i, data, file);
1292                 if (ret < 0)
1293                         goto error;
1294                 if (insns[i].insn & INSN_MASK_READ) {
1295                         if (copy_to_user(insns[i].data, data,
1296                                          insns[i].n * sizeof(unsigned int))) {
1297                                 DPRINTK("copy_to_user failed\n");
1298                                 ret = -EFAULT;
1299                                 goto error;
1300                         }
1301                 }
1302                 if (need_resched())
1303                         schedule();
1304         }
1305
1306 error:
1307         kfree(insns);
1308         kfree(data);
1309
1310         if (ret < 0)
1311                 return ret;
1312         return i;
1313 }
1314
1315 /*
1316  *      COMEDI_INSN
1317  *      synchronous instructions
1318  *
1319  *      arg:
1320  *              pointer to insn
1321  *
1322  *      reads:
1323  *              struct comedi_insn struct at arg
1324  *              data (for writes)
1325  *
1326  *      writes:
1327  *              data (for reads)
1328  */
1329 static int do_insn_ioctl(struct comedi_device *dev,
1330                          struct comedi_insn __user *arg, void *file)
1331 {
1332         struct comedi_insn insn;
1333         unsigned int *data = NULL;
1334         int ret = 0;
1335
1336         data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
1337         if (!data) {
1338                 ret = -ENOMEM;
1339                 goto error;
1340         }
1341
1342         if (copy_from_user(&insn, arg, sizeof(insn))) {
1343                 ret = -EFAULT;
1344                 goto error;
1345         }
1346
1347         /* This is where the behavior of insn and insnlist deviate. */
1348         if (insn.n > MAX_SAMPLES)
1349                 insn.n = MAX_SAMPLES;
1350         if (insn.insn & INSN_MASK_WRITE) {
1351                 if (copy_from_user(data,
1352                                    insn.data,
1353                                    insn.n * sizeof(unsigned int))) {
1354                         ret = -EFAULT;
1355                         goto error;
1356                 }
1357         }
1358         ret = parse_insn(dev, &insn, data, file);
1359         if (ret < 0)
1360                 goto error;
1361         if (insn.insn & INSN_MASK_READ) {
1362                 if (copy_to_user(insn.data,
1363                                  data,
1364                                  insn.n * sizeof(unsigned int))) {
1365                         ret = -EFAULT;
1366                         goto error;
1367                 }
1368         }
1369         ret = insn.n;
1370
1371 error:
1372         kfree(data);
1373
1374         return ret;
1375 }
1376
1377 static int do_cmd_ioctl(struct comedi_device *dev,
1378                         struct comedi_cmd __user *arg, void *file)
1379 {
1380         struct comedi_cmd cmd;
1381         struct comedi_subdevice *s;
1382         struct comedi_async *async;
1383         int ret = 0;
1384         unsigned int __user *user_chanlist;
1385
1386         if (copy_from_user(&cmd, arg, sizeof(cmd))) {
1387                 DPRINTK("bad cmd address\n");
1388                 return -EFAULT;
1389         }
1390         /* save user's chanlist pointer so it can be restored later */
1391         user_chanlist = (unsigned int __user *)cmd.chanlist;
1392
1393         if (cmd.subdev >= dev->n_subdevices) {
1394                 DPRINTK("%d no such subdevice\n", cmd.subdev);
1395                 return -ENODEV;
1396         }
1397
1398         s = &dev->subdevices[cmd.subdev];
1399         async = s->async;
1400
1401         if (s->type == COMEDI_SUBD_UNUSED) {
1402                 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1403                 return -EIO;
1404         }
1405
1406         if (!s->do_cmd || !s->do_cmdtest || !s->async) {
1407                 DPRINTK("subdevice %i does not support commands\n",
1408                         cmd.subdev);
1409                 return -EIO;
1410         }
1411
1412         /* are we locked? (ioctl lock) */
1413         if (s->lock && s->lock != file) {
1414                 DPRINTK("subdevice locked\n");
1415                 return -EACCES;
1416         }
1417
1418         /* are we busy? */
1419         if (s->busy) {
1420                 DPRINTK("subdevice busy\n");
1421                 return -EBUSY;
1422         }
1423
1424         /* make sure channel/gain list isn't too long */
1425         if (cmd.chanlist_len > s->len_chanlist) {
1426                 DPRINTK("channel/gain list too long %u > %d\n",
1427                         cmd.chanlist_len, s->len_chanlist);
1428                 return -EINVAL;
1429         }
1430
1431         /* make sure channel/gain list isn't too short */
1432         if (cmd.chanlist_len < 1) {
1433                 DPRINTK("channel/gain list too short %u < 1\n",
1434                         cmd.chanlist_len);
1435                 return -EINVAL;
1436         }
1437
1438         async->cmd = cmd;
1439         async->cmd.data = NULL;
1440         /* load channel/gain list */
1441         async->cmd.chanlist = memdup_user(user_chanlist,
1442                                           async->cmd.chanlist_len * sizeof(int));
1443         if (IS_ERR(async->cmd.chanlist)) {
1444                 ret = PTR_ERR(async->cmd.chanlist);
1445                 DPRINTK("memdup_user failed with code %d\n", ret);
1446                 goto cleanup;
1447         }
1448
1449         /* make sure each element in channel/gain list is valid */
1450         ret = comedi_check_chanlist(s,
1451                                     async->cmd.chanlist_len,
1452                                     async->cmd.chanlist);
1453         if (ret < 0) {
1454                 DPRINTK("bad chanlist\n");
1455                 goto cleanup;
1456         }
1457
1458         ret = s->do_cmdtest(dev, s, &async->cmd);
1459
1460         if (async->cmd.flags & TRIG_BOGUS || ret) {
1461                 DPRINTK("test returned %d\n", ret);
1462                 cmd = async->cmd;
1463                 /* restore chanlist pointer before copying back */
1464                 cmd.chanlist = (unsigned int __force *)user_chanlist;
1465                 cmd.data = NULL;
1466                 if (copy_to_user(arg, &cmd, sizeof(cmd))) {
1467                         DPRINTK("fault writing cmd\n");
1468                         ret = -EFAULT;
1469                         goto cleanup;
1470                 }
1471                 ret = -EAGAIN;
1472                 goto cleanup;
1473         }
1474
1475         if (!async->prealloc_bufsz) {
1476                 ret = -ENOMEM;
1477                 DPRINTK("no buffer (?)\n");
1478                 goto cleanup;
1479         }
1480
1481         comedi_buf_reset(async);
1482
1483         async->cb_mask =
1484             COMEDI_CB_EOA | COMEDI_CB_BLOCK | COMEDI_CB_ERROR |
1485             COMEDI_CB_OVERFLOW;
1486         if (async->cmd.flags & TRIG_WAKE_EOS)
1487                 async->cb_mask |= COMEDI_CB_EOS;
1488
1489         comedi_set_subdevice_runflags(s, SRF_ERROR | SRF_RUNNING, SRF_RUNNING);
1490
1491         /* set s->busy _after_ setting SRF_RUNNING flag to avoid race with
1492          * comedi_read() or comedi_write() */
1493         s->busy = file;
1494         ret = s->do_cmd(dev, s);
1495         if (ret == 0)
1496                 return 0;
1497
1498 cleanup:
1499         do_become_nonbusy(dev, s);
1500
1501         return ret;
1502 }
1503
1504 /*
1505         COMEDI_CMDTEST
1506         command testing ioctl
1507
1508         arg:
1509                 pointer to cmd structure
1510
1511         reads:
1512                 cmd structure at arg
1513                 channel/range list
1514
1515         writes:
1516                 modified cmd structure at arg
1517
1518 */
1519 static int do_cmdtest_ioctl(struct comedi_device *dev,
1520                             struct comedi_cmd __user *arg, void *file)
1521 {
1522         struct comedi_cmd cmd;
1523         struct comedi_subdevice *s;
1524         int ret = 0;
1525         unsigned int *chanlist = NULL;
1526         unsigned int __user *user_chanlist;
1527
1528         if (copy_from_user(&cmd, arg, sizeof(cmd))) {
1529                 DPRINTK("bad cmd address\n");
1530                 return -EFAULT;
1531         }
1532         /* save user's chanlist pointer so it can be restored later */
1533         user_chanlist = (unsigned int __user *)cmd.chanlist;
1534
1535         if (cmd.subdev >= dev->n_subdevices) {
1536                 DPRINTK("%d no such subdevice\n", cmd.subdev);
1537                 return -ENODEV;
1538         }
1539
1540         s = &dev->subdevices[cmd.subdev];
1541         if (s->type == COMEDI_SUBD_UNUSED) {
1542                 DPRINTK("%d not valid subdevice\n", cmd.subdev);
1543                 return -EIO;
1544         }
1545
1546         if (!s->do_cmd || !s->do_cmdtest) {
1547                 DPRINTK("subdevice %i does not support commands\n",
1548                         cmd.subdev);
1549                 return -EIO;
1550         }
1551
1552         /* make sure channel/gain list isn't too long */
1553         if (cmd.chanlist_len > s->len_chanlist) {
1554                 DPRINTK("channel/gain list too long %d > %d\n",
1555                         cmd.chanlist_len, s->len_chanlist);
1556                 ret = -EINVAL;
1557                 goto cleanup;
1558         }
1559
1560         /* load channel/gain list */
1561         if (cmd.chanlist) {
1562                 chanlist = memdup_user(user_chanlist,
1563                                        cmd.chanlist_len * sizeof(int));
1564                 if (IS_ERR(chanlist)) {
1565                         ret = PTR_ERR(chanlist);
1566                         DPRINTK("memdup_user exited with code %d", ret);
1567                         goto cleanup;
1568                 }
1569
1570                 /* make sure each element in channel/gain list is valid */
1571                 ret = comedi_check_chanlist(s, cmd.chanlist_len, chanlist);
1572                 if (ret < 0) {
1573                         DPRINTK("bad chanlist\n");
1574                         goto cleanup;
1575                 }
1576
1577                 cmd.chanlist = chanlist;
1578         }
1579
1580         ret = s->do_cmdtest(dev, s, &cmd);
1581
1582         /* restore chanlist pointer before copying back */
1583         cmd.chanlist = (unsigned int __force *)user_chanlist;
1584
1585         if (copy_to_user(arg, &cmd, sizeof(cmd))) {
1586                 DPRINTK("bad cmd address\n");
1587                 ret = -EFAULT;
1588                 goto cleanup;
1589         }
1590 cleanup:
1591         kfree(chanlist);
1592
1593         return ret;
1594 }
1595
1596 /*
1597         COMEDI_LOCK
1598         lock subdevice
1599
1600         arg:
1601                 subdevice number
1602
1603         reads:
1604                 none
1605
1606         writes:
1607                 none
1608
1609 */
1610
1611 static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg,
1612                          void *file)
1613 {
1614         int ret = 0;
1615         unsigned long flags;
1616         struct comedi_subdevice *s;
1617
1618         if (arg >= dev->n_subdevices)
1619                 return -EINVAL;
1620         s = &dev->subdevices[arg];
1621
1622         spin_lock_irqsave(&s->spin_lock, flags);
1623         if (s->busy || s->lock)
1624                 ret = -EBUSY;
1625         else
1626                 s->lock = file;
1627         spin_unlock_irqrestore(&s->spin_lock, flags);
1628
1629 #if 0
1630         if (ret < 0)
1631                 return ret;
1632
1633         if (s->lock_f)
1634                 ret = s->lock_f(dev, s);
1635 #endif
1636
1637         return ret;
1638 }
1639
1640 /*
1641         COMEDI_UNLOCK
1642         unlock subdevice
1643
1644         arg:
1645                 subdevice number
1646
1647         reads:
1648                 none
1649
1650         writes:
1651                 none
1652
1653         This function isn't protected by the semaphore, since
1654         we already own the lock.
1655 */
1656 static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg,
1657                            void *file)
1658 {
1659         struct comedi_subdevice *s;
1660
1661         if (arg >= dev->n_subdevices)
1662                 return -EINVAL;
1663         s = &dev->subdevices[arg];
1664
1665         if (s->busy)
1666                 return -EBUSY;
1667
1668         if (s->lock && s->lock != file)
1669                 return -EACCES;
1670
1671         if (s->lock == file) {
1672 #if 0
1673                 if (s->unlock)
1674                         s->unlock(dev, s);
1675 #endif
1676
1677                 s->lock = NULL;
1678         }
1679
1680         return 0;
1681 }
1682
1683 /*
1684         COMEDI_CANCEL
1685         cancel acquisition ioctl
1686
1687         arg:
1688                 subdevice number
1689
1690         reads:
1691                 nothing
1692
1693         writes:
1694                 nothing
1695
1696 */
1697 static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg,
1698                            void *file)
1699 {
1700         struct comedi_subdevice *s;
1701         int ret;
1702
1703         if (arg >= dev->n_subdevices)
1704                 return -EINVAL;
1705         s = &dev->subdevices[arg];
1706         if (s->async == NULL)
1707                 return -EINVAL;
1708
1709         if (s->lock && s->lock != file)
1710                 return -EACCES;
1711
1712         if (!s->busy)
1713                 return 0;
1714
1715         if (s->busy != file)
1716                 return -EBUSY;
1717
1718         ret = do_cancel(dev, s);
1719
1720         return ret;
1721 }
1722
1723 /*
1724         COMEDI_POLL ioctl
1725         instructs driver to synchronize buffers
1726
1727         arg:
1728                 subdevice number
1729
1730         reads:
1731                 nothing
1732
1733         writes:
1734                 nothing
1735
1736 */
1737 static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg,
1738                          void *file)
1739 {
1740         struct comedi_subdevice *s;
1741
1742         if (arg >= dev->n_subdevices)
1743                 return -EINVAL;
1744         s = &dev->subdevices[arg];
1745
1746         if (s->lock && s->lock != file)
1747                 return -EACCES;
1748
1749         if (!s->busy)
1750                 return 0;
1751
1752         if (s->busy != file)
1753                 return -EBUSY;
1754
1755         if (s->poll)
1756                 return s->poll(dev, s);
1757
1758         return -EINVAL;
1759 }
1760
1761 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
1762                                   unsigned long arg)
1763 {
1764         const unsigned minor = iminor(file_inode(file));
1765         struct comedi_device *dev = comedi_dev_from_minor(minor);
1766         int rc;
1767
1768         if (!dev)
1769                 return -ENODEV;
1770
1771         mutex_lock(&dev->mutex);
1772
1773         /* Device config is special, because it must work on
1774          * an unconfigured device. */
1775         if (cmd == COMEDI_DEVCONFIG) {
1776                 if (minor >= COMEDI_NUM_BOARD_MINORS) {
1777                         /* Device config not appropriate on non-board minors. */
1778                         rc = -ENOTTY;
1779                         goto done;
1780                 }
1781                 rc = do_devconfig_ioctl(dev,
1782                                         (struct comedi_devconfig __user *)arg);
1783                 if (rc == 0) {
1784                         if (arg == 0 &&
1785                             dev->minor >= comedi_num_legacy_minors) {
1786                                 /* Successfully unconfigured a dynamically
1787                                  * allocated device.  Try and remove it. */
1788                                 if (comedi_clear_board_dev(dev)) {
1789                                         mutex_unlock(&dev->mutex);
1790                                         comedi_free_board_dev(dev);
1791                                         return rc;
1792                                 }
1793                         }
1794                 }
1795                 goto done;
1796         }
1797
1798         if (!dev->attached) {
1799                 DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor);
1800                 rc = -ENODEV;
1801                 goto done;
1802         }
1803
1804         switch (cmd) {
1805         case COMEDI_BUFCONFIG:
1806                 rc = do_bufconfig_ioctl(dev,
1807                                         (struct comedi_bufconfig __user *)arg);
1808                 break;
1809         case COMEDI_DEVINFO:
1810                 rc = do_devinfo_ioctl(dev, (struct comedi_devinfo __user *)arg,
1811                                       file);
1812                 break;
1813         case COMEDI_SUBDINFO:
1814                 rc = do_subdinfo_ioctl(dev,
1815                                        (struct comedi_subdinfo __user *)arg,
1816                                        file);
1817                 break;
1818         case COMEDI_CHANINFO:
1819                 rc = do_chaninfo_ioctl(dev, (void __user *)arg);
1820                 break;
1821         case COMEDI_RANGEINFO:
1822                 rc = do_rangeinfo_ioctl(dev, (void __user *)arg);
1823                 break;
1824         case COMEDI_BUFINFO:
1825                 rc = do_bufinfo_ioctl(dev,
1826                                       (struct comedi_bufinfo __user *)arg,
1827                                       file);
1828                 break;
1829         case COMEDI_LOCK:
1830                 rc = do_lock_ioctl(dev, arg, file);
1831                 break;
1832         case COMEDI_UNLOCK:
1833                 rc = do_unlock_ioctl(dev, arg, file);
1834                 break;
1835         case COMEDI_CANCEL:
1836                 rc = do_cancel_ioctl(dev, arg, file);
1837                 break;
1838         case COMEDI_CMD:
1839                 rc = do_cmd_ioctl(dev, (struct comedi_cmd __user *)arg, file);
1840                 break;
1841         case COMEDI_CMDTEST:
1842                 rc = do_cmdtest_ioctl(dev, (struct comedi_cmd __user *)arg,
1843                                       file);
1844                 break;
1845         case COMEDI_INSNLIST:
1846                 rc = do_insnlist_ioctl(dev,
1847                                        (struct comedi_insnlist __user *)arg,
1848                                        file);
1849                 break;
1850         case COMEDI_INSN:
1851                 rc = do_insn_ioctl(dev, (struct comedi_insn __user *)arg,
1852                                    file);
1853                 break;
1854         case COMEDI_POLL:
1855                 rc = do_poll_ioctl(dev, arg, file);
1856                 break;
1857         default:
1858                 rc = -ENOTTY;
1859                 break;
1860         }
1861
1862 done:
1863         mutex_unlock(&dev->mutex);
1864         return rc;
1865 }
1866
1867 static void comedi_vm_open(struct vm_area_struct *area)
1868 {
1869         struct comedi_async *async;
1870         struct comedi_device *dev;
1871
1872         async = area->vm_private_data;
1873         dev = async->subdevice->device;
1874
1875         mutex_lock(&dev->mutex);
1876         async->mmap_count++;
1877         mutex_unlock(&dev->mutex);
1878 }
1879
1880 static void comedi_vm_close(struct vm_area_struct *area)
1881 {
1882         struct comedi_async *async;
1883         struct comedi_device *dev;
1884
1885         async = area->vm_private_data;
1886         dev = async->subdevice->device;
1887
1888         mutex_lock(&dev->mutex);
1889         async->mmap_count--;
1890         mutex_unlock(&dev->mutex);
1891 }
1892
1893 static struct vm_operations_struct comedi_vm_ops = {
1894         .open = comedi_vm_open,
1895         .close = comedi_vm_close,
1896 };
1897
1898 static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
1899 {
1900         const unsigned minor = iminor(file_inode(file));
1901         struct comedi_device *dev = comedi_dev_from_minor(minor);
1902         struct comedi_subdevice *s;
1903         struct comedi_async *async;
1904         unsigned long start = vma->vm_start;
1905         unsigned long size;
1906         int n_pages;
1907         int i;
1908         int retval;
1909
1910         if (!dev)
1911                 return -ENODEV;
1912
1913         mutex_lock(&dev->mutex);
1914
1915         if (!dev->attached) {
1916                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
1917                 retval = -ENODEV;
1918                 goto done;
1919         }
1920
1921         if (vma->vm_flags & VM_WRITE)
1922                 s = comedi_write_subdevice(dev, minor);
1923         else
1924                 s = comedi_read_subdevice(dev, minor);
1925         if (!s) {
1926                 retval = -EINVAL;
1927                 goto done;
1928         }
1929
1930         async = s->async;
1931         if (!async) {
1932                 retval = -EINVAL;
1933                 goto done;
1934         }
1935
1936         if (vma->vm_pgoff != 0) {
1937                 DPRINTK("comedi: mmap() offset must be 0.\n");
1938                 retval = -EINVAL;
1939                 goto done;
1940         }
1941
1942         size = vma->vm_end - vma->vm_start;
1943         if (size > async->prealloc_bufsz) {
1944                 retval = -EFAULT;
1945                 goto done;
1946         }
1947         if (size & (~PAGE_MASK)) {
1948                 retval = -EFAULT;
1949                 goto done;
1950         }
1951
1952         n_pages = size >> PAGE_SHIFT;
1953         for (i = 0; i < n_pages; ++i) {
1954                 struct comedi_buf_page *buf = &async->buf_page_list[i];
1955
1956                 if (remap_pfn_range(vma, start,
1957                                     page_to_pfn(virt_to_page(buf->virt_addr)),
1958                                     PAGE_SIZE, PAGE_SHARED)) {
1959                         retval = -EAGAIN;
1960                         goto done;
1961                 }
1962                 start += PAGE_SIZE;
1963         }
1964
1965         vma->vm_ops = &comedi_vm_ops;
1966         vma->vm_private_data = async;
1967
1968         async->mmap_count++;
1969
1970         retval = 0;
1971 done:
1972         mutex_unlock(&dev->mutex);
1973         return retval;
1974 }
1975
1976 static unsigned int comedi_poll(struct file *file, poll_table *wait)
1977 {
1978         unsigned int mask = 0;
1979         const unsigned minor = iminor(file_inode(file));
1980         struct comedi_device *dev = comedi_dev_from_minor(minor);
1981         struct comedi_subdevice *s;
1982
1983         if (!dev)
1984                 return -ENODEV;
1985
1986         mutex_lock(&dev->mutex);
1987
1988         if (!dev->attached) {
1989                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
1990                 goto done;
1991         }
1992
1993         s = comedi_read_subdevice(dev, minor);
1994         if (s && s->async) {
1995                 poll_wait(file, &s->async->wait_head, wait);
1996                 if (!s->busy || !comedi_is_subdevice_running(s) ||
1997                     comedi_buf_read_n_available(s->async) > 0)
1998                         mask |= POLLIN | POLLRDNORM;
1999         }
2000
2001         s = comedi_write_subdevice(dev, minor);
2002         if (s && s->async) {
2003                 unsigned int bps = bytes_per_sample(s->async->subdevice);
2004
2005                 poll_wait(file, &s->async->wait_head, wait);
2006                 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
2007                 if (!s->busy || !comedi_is_subdevice_running(s) ||
2008                     comedi_buf_write_n_allocated(s->async) >= bps)
2009                         mask |= POLLOUT | POLLWRNORM;
2010         }
2011
2012 done:
2013         mutex_unlock(&dev->mutex);
2014         return mask;
2015 }
2016
2017 static ssize_t comedi_write(struct file *file, const char __user *buf,
2018                             size_t nbytes, loff_t *offset)
2019 {
2020         struct comedi_subdevice *s;
2021         struct comedi_async *async;
2022         int n, m, count = 0, retval = 0;
2023         DECLARE_WAITQUEUE(wait, current);
2024         const unsigned minor = iminor(file_inode(file));
2025         struct comedi_device *dev = comedi_dev_from_minor(minor);
2026
2027         if (!dev)
2028                 return -ENODEV;
2029
2030         if (!dev->attached) {
2031                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
2032                 return -ENODEV;
2033         }
2034
2035         s = comedi_write_subdevice(dev, minor);
2036         if (!s || !s->async)
2037                 return -EIO;
2038
2039         async = s->async;
2040
2041         if (!s->busy || !nbytes)
2042                 return 0;
2043         if (s->busy != file)
2044                 return -EACCES;
2045
2046         add_wait_queue(&async->wait_head, &wait);
2047         while (nbytes > 0 && !retval) {
2048                 set_current_state(TASK_INTERRUPTIBLE);
2049
2050                 if (!comedi_is_subdevice_running(s)) {
2051                         if (count == 0) {
2052                                 mutex_lock(&dev->mutex);
2053                                 if (comedi_is_subdevice_in_error(s))
2054                                         retval = -EPIPE;
2055                                 else
2056                                         retval = 0;
2057                                 do_become_nonbusy(dev, s);
2058                                 mutex_unlock(&dev->mutex);
2059                         }
2060                         break;
2061                 }
2062
2063                 n = nbytes;
2064
2065                 m = n;
2066                 if (async->buf_write_ptr + m > async->prealloc_bufsz)
2067                         m = async->prealloc_bufsz - async->buf_write_ptr;
2068                 comedi_buf_write_alloc(async, async->prealloc_bufsz);
2069                 if (m > comedi_buf_write_n_allocated(async))
2070                         m = comedi_buf_write_n_allocated(async);
2071                 if (m < n)
2072                         n = m;
2073
2074                 if (n == 0) {
2075                         if (file->f_flags & O_NONBLOCK) {
2076                                 retval = -EAGAIN;
2077                                 break;
2078                         }
2079                         schedule();
2080                         if (signal_pending(current)) {
2081                                 retval = -ERESTARTSYS;
2082                                 break;
2083                         }
2084                         if (!s->busy)
2085                                 break;
2086                         if (s->busy != file) {
2087                                 retval = -EACCES;
2088                                 break;
2089                         }
2090                         continue;
2091                 }
2092
2093                 m = copy_from_user(async->prealloc_buf + async->buf_write_ptr,
2094                                    buf, n);
2095                 if (m) {
2096                         n -= m;
2097                         retval = -EFAULT;
2098                 }
2099                 comedi_buf_write_free(async, n);
2100
2101                 count += n;
2102                 nbytes -= n;
2103
2104                 buf += n;
2105                 break;          /* makes device work like a pipe */
2106         }
2107         set_current_state(TASK_RUNNING);
2108         remove_wait_queue(&async->wait_head, &wait);
2109
2110         return count ? count : retval;
2111 }
2112
2113 static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes,
2114                                 loff_t *offset)
2115 {
2116         struct comedi_subdevice *s;
2117         struct comedi_async *async;
2118         int n, m, count = 0, retval = 0;
2119         DECLARE_WAITQUEUE(wait, current);
2120         const unsigned minor = iminor(file_inode(file));
2121         struct comedi_device *dev = comedi_dev_from_minor(minor);
2122
2123         if (!dev)
2124                 return -ENODEV;
2125
2126         if (!dev->attached) {
2127                 DPRINTK("no driver configured on comedi%i\n", dev->minor);
2128                 return -ENODEV;
2129         }
2130
2131         s = comedi_read_subdevice(dev, minor);
2132         if (!s || !s->async)
2133                 return -EIO;
2134
2135         async = s->async;
2136         if (!s->busy || !nbytes)
2137                 return 0;
2138         if (s->busy != file)
2139                 return -EACCES;
2140
2141         add_wait_queue(&async->wait_head, &wait);
2142         while (nbytes > 0 && !retval) {
2143                 set_current_state(TASK_INTERRUPTIBLE);
2144
2145                 n = nbytes;
2146
2147                 m = comedi_buf_read_n_available(async);
2148                 /* printk("%d available\n",m); */
2149                 if (async->buf_read_ptr + m > async->prealloc_bufsz)
2150                         m = async->prealloc_bufsz - async->buf_read_ptr;
2151                 /* printk("%d contiguous\n",m); */
2152                 if (m < n)
2153                         n = m;
2154
2155                 if (n == 0) {
2156                         if (!comedi_is_subdevice_running(s)) {
2157                                 mutex_lock(&dev->mutex);
2158                                 do_become_nonbusy(dev, s);
2159                                 if (comedi_is_subdevice_in_error(s))
2160                                         retval = -EPIPE;
2161                                 else
2162                                         retval = 0;
2163                                 mutex_unlock(&dev->mutex);
2164                                 break;
2165                         }
2166                         if (file->f_flags & O_NONBLOCK) {
2167                                 retval = -EAGAIN;
2168                                 break;
2169                         }
2170                         schedule();
2171                         if (signal_pending(current)) {
2172                                 retval = -ERESTARTSYS;
2173                                 break;
2174                         }
2175                         if (!s->busy) {
2176                                 retval = 0;
2177                                 break;
2178                         }
2179                         if (s->busy != file) {
2180                                 retval = -EACCES;
2181                                 break;
2182                         }
2183                         continue;
2184                 }
2185                 m = copy_to_user(buf, async->prealloc_buf +
2186                                  async->buf_read_ptr, n);
2187                 if (m) {
2188                         n -= m;
2189                         retval = -EFAULT;
2190                 }
2191
2192                 comedi_buf_read_alloc(async, n);
2193                 comedi_buf_read_free(async, n);
2194
2195                 count += n;
2196                 nbytes -= n;
2197
2198                 buf += n;
2199                 break;          /* makes device work like a pipe */
2200         }
2201         if (comedi_is_subdevice_idle(s)) {
2202                 mutex_lock(&dev->mutex);
2203                 if (async->buf_read_count - async->buf_write_count == 0)
2204                         do_become_nonbusy(dev, s);
2205                 mutex_unlock(&dev->mutex);
2206         }
2207         set_current_state(TASK_RUNNING);
2208         remove_wait_queue(&async->wait_head, &wait);
2209
2210         return count ? count : retval;
2211 }
2212
2213 static int comedi_open(struct inode *inode, struct file *file)
2214 {
2215         const unsigned minor = iminor(inode);
2216         struct comedi_device *dev = comedi_dev_from_minor(minor);
2217
2218         if (!dev) {
2219                 DPRINTK("invalid minor number\n");
2220                 return -ENODEV;
2221         }
2222
2223         /* This is slightly hacky, but we want module autoloading
2224          * to work for root.
2225          * case: user opens device, attached -> ok
2226          * case: user opens device, unattached, !in_request_module -> autoload
2227          * case: user opens device, unattached, in_request_module -> fail
2228          * case: root opens device, attached -> ok
2229          * case: root opens device, unattached, in_request_module -> ok
2230          *   (typically called from modprobe)
2231          * case: root opens device, unattached, !in_request_module -> autoload
2232          *
2233          * The last could be changed to "-> ok", which would deny root
2234          * autoloading.
2235          */
2236         mutex_lock(&dev->mutex);
2237         if (dev->attached)
2238                 goto ok;
2239         if (!capable(CAP_NET_ADMIN) && dev->in_request_module) {
2240                 DPRINTK("in request module\n");
2241                 mutex_unlock(&dev->mutex);
2242                 return -ENODEV;
2243         }
2244         if (capable(CAP_NET_ADMIN) && dev->in_request_module)
2245                 goto ok;
2246
2247         dev->in_request_module = true;
2248
2249 #ifdef CONFIG_KMOD
2250         mutex_unlock(&dev->mutex);
2251         request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
2252         mutex_lock(&dev->mutex);
2253 #endif
2254
2255         dev->in_request_module = false;
2256
2257         if (!dev->attached && !capable(CAP_NET_ADMIN)) {
2258                 DPRINTK("not attached and not CAP_NET_ADMIN\n");
2259                 mutex_unlock(&dev->mutex);
2260                 return -ENODEV;
2261         }
2262 ok:
2263         __module_get(THIS_MODULE);
2264
2265         if (dev->attached) {
2266                 if (!try_module_get(dev->driver->module)) {
2267                         module_put(THIS_MODULE);
2268                         mutex_unlock(&dev->mutex);
2269                         return -ENOSYS;
2270                 }
2271         }
2272
2273         if (dev->attached && dev->use_count == 0 && dev->open) {
2274                 int rc = dev->open(dev);
2275                 if (rc < 0) {
2276                         module_put(dev->driver->module);
2277                         module_put(THIS_MODULE);
2278                         mutex_unlock(&dev->mutex);
2279                         return rc;
2280                 }
2281         }
2282
2283         dev->use_count++;
2284
2285         mutex_unlock(&dev->mutex);
2286
2287         return 0;
2288 }
2289
2290 static int comedi_fasync(int fd, struct file *file, int on)
2291 {
2292         const unsigned minor = iminor(file_inode(file));
2293         struct comedi_device *dev = comedi_dev_from_minor(minor);
2294
2295         if (!dev)
2296                 return -ENODEV;
2297
2298         return fasync_helper(fd, file, on, &dev->async_queue);
2299 }
2300
2301 static int comedi_close(struct inode *inode, struct file *file)
2302 {
2303         const unsigned minor = iminor(inode);
2304         struct comedi_device *dev = comedi_dev_from_minor(minor);
2305         struct comedi_subdevice *s = NULL;
2306         int i;
2307
2308         if (!dev)
2309                 return -ENODEV;
2310
2311         mutex_lock(&dev->mutex);
2312
2313         if (dev->subdevices) {
2314                 for (i = 0; i < dev->n_subdevices; i++) {
2315                         s = &dev->subdevices[i];
2316
2317                         if (s->busy == file)
2318                                 do_cancel(dev, s);
2319                         if (s->lock == file)
2320                                 s->lock = NULL;
2321                 }
2322         }
2323         if (dev->attached && dev->use_count == 1 && dev->close)
2324                 dev->close(dev);
2325
2326         module_put(THIS_MODULE);
2327         if (dev->attached)
2328                 module_put(dev->driver->module);
2329
2330         dev->use_count--;
2331
2332         mutex_unlock(&dev->mutex);
2333
2334         return 0;
2335 }
2336
2337 static const struct file_operations comedi_fops = {
2338         .owner = THIS_MODULE,
2339         .unlocked_ioctl = comedi_unlocked_ioctl,
2340         .compat_ioctl = comedi_compat_ioctl,
2341         .open = comedi_open,
2342         .release = comedi_close,
2343         .read = comedi_read,
2344         .write = comedi_write,
2345         .mmap = comedi_mmap,
2346         .poll = comedi_poll,
2347         .fasync = comedi_fasync,
2348         .llseek = noop_llseek,
2349 };
2350
2351 void comedi_error(const struct comedi_device *dev, const char *s)
2352 {
2353         dev_err(dev->class_dev, "%s: %s\n", dev->driver->driver_name, s);
2354 }
2355 EXPORT_SYMBOL_GPL(comedi_error);
2356
2357 void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
2358 {
2359         struct comedi_async *async = s->async;
2360         unsigned runflags = 0;
2361         unsigned runflags_mask = 0;
2362
2363         /* DPRINTK("comedi_event 0x%x\n",mask); */
2364
2365         if (!comedi_is_subdevice_running(s))
2366                 return;
2367
2368         if (s->
2369             async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
2370                              COMEDI_CB_OVERFLOW)) {
2371                 runflags_mask |= SRF_RUNNING;
2372         }
2373         /* remember if an error event has occurred, so an error
2374          * can be returned the next time the user does a read() */
2375         if (s->async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW)) {
2376                 runflags_mask |= SRF_ERROR;
2377                 runflags |= SRF_ERROR;
2378         }
2379         if (runflags_mask) {
2380                 /*sets SRF_ERROR and SRF_RUNNING together atomically */
2381                 comedi_set_subdevice_runflags(s, runflags_mask, runflags);
2382         }
2383
2384         if (async->cb_mask & s->async->events) {
2385                 wake_up_interruptible(&async->wait_head);
2386                 if (s->subdev_flags & SDF_CMD_READ)
2387                         kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
2388                 if (s->subdev_flags & SDF_CMD_WRITE)
2389                         kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
2390         }
2391         s->async->events = 0;
2392 }
2393 EXPORT_SYMBOL_GPL(comedi_event);
2394
2395 /* Note: the ->mutex is pre-locked on successful return */
2396 struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device)
2397 {
2398         struct comedi_device *dev;
2399         struct device *csdev;
2400         unsigned i;
2401
2402         dev = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
2403         if (dev == NULL)
2404                 return ERR_PTR(-ENOMEM);
2405         comedi_device_init(dev);
2406         comedi_set_hw_dev(dev, hardware_device);
2407         mutex_lock(&dev->mutex);
2408         mutex_lock(&comedi_board_minor_table_lock);
2409         for (i = hardware_device ? comedi_num_legacy_minors : 0;
2410              i < COMEDI_NUM_BOARD_MINORS; ++i) {
2411                 if (comedi_board_minor_table[i] == NULL) {
2412                         comedi_board_minor_table[i] = dev;
2413                         break;
2414                 }
2415         }
2416         mutex_unlock(&comedi_board_minor_table_lock);
2417         if (i == COMEDI_NUM_BOARD_MINORS) {
2418                 mutex_unlock(&dev->mutex);
2419                 comedi_device_cleanup(dev);
2420                 kfree(dev);
2421                 pr_err("comedi: error: ran out of minor numbers for board device files.\n");
2422                 return ERR_PTR(-EBUSY);
2423         }
2424         dev->minor = i;
2425         csdev = device_create(comedi_class, hardware_device,
2426                               MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i", i);
2427         if (!IS_ERR(csdev))
2428                 dev->class_dev = csdev;
2429
2430         /* Note: dev->mutex needs to be unlocked by the caller. */
2431         return dev;
2432 }
2433
2434 static void comedi_free_board_minor(unsigned minor)
2435 {
2436         BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
2437         comedi_free_board_dev(comedi_clear_board_minor(minor));
2438 }
2439
2440 void comedi_release_hardware_device(struct device *hardware_device)
2441 {
2442         int minor;
2443         struct comedi_device *dev;
2444
2445         for (minor = comedi_num_legacy_minors; minor < COMEDI_NUM_BOARD_MINORS;
2446              minor++) {
2447                 mutex_lock(&comedi_board_minor_table_lock);
2448                 dev = comedi_board_minor_table[minor];
2449                 if (dev && dev->hw_dev == hardware_device) {
2450                         comedi_board_minor_table[minor] = NULL;
2451                         mutex_unlock(&comedi_board_minor_table_lock);
2452                         comedi_free_board_dev(dev);
2453                         break;
2454                 }
2455                 mutex_unlock(&comedi_board_minor_table_lock);
2456         }
2457 }
2458
2459 int comedi_alloc_subdevice_minor(struct comedi_subdevice *s)
2460 {
2461         struct comedi_device *dev = s->device;
2462         struct device *csdev;
2463         unsigned i;
2464
2465         mutex_lock(&comedi_subdevice_minor_table_lock);
2466         for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i) {
2467                 if (comedi_subdevice_minor_table[i] == NULL) {
2468                         comedi_subdevice_minor_table[i] = s;
2469                         break;
2470                 }
2471         }
2472         mutex_unlock(&comedi_subdevice_minor_table_lock);
2473         if (i == COMEDI_NUM_SUBDEVICE_MINORS) {
2474                 pr_err("comedi: error: ran out of minor numbers for subdevice files.\n");
2475                 return -EBUSY;
2476         }
2477         i += COMEDI_NUM_BOARD_MINORS;
2478         s->minor = i;
2479         csdev = device_create(comedi_class, dev->class_dev,
2480                               MKDEV(COMEDI_MAJOR, i), NULL, "comedi%i_subd%i",
2481                               dev->minor, s->index);
2482         if (!IS_ERR(csdev))
2483                 s->class_dev = csdev;
2484
2485         return 0;
2486 }
2487
2488 void comedi_free_subdevice_minor(struct comedi_subdevice *s)
2489 {
2490         unsigned int i;
2491
2492         if (s == NULL)
2493                 return;
2494         if (s->minor < 0)
2495                 return;
2496
2497         BUG_ON(s->minor >= COMEDI_NUM_MINORS);
2498         BUG_ON(s->minor < COMEDI_NUM_BOARD_MINORS);
2499
2500         i = s->minor - COMEDI_NUM_BOARD_MINORS;
2501         mutex_lock(&comedi_subdevice_minor_table_lock);
2502         if (s == comedi_subdevice_minor_table[i])
2503                 comedi_subdevice_minor_table[i] = NULL;
2504         mutex_unlock(&comedi_subdevice_minor_table_lock);
2505         if (s->class_dev) {
2506                 device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
2507                 s->class_dev = NULL;
2508         }
2509 }
2510
2511 static void comedi_cleanup_board_minors(void)
2512 {
2513         unsigned i;
2514
2515         for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++)
2516                 comedi_free_board_minor(i);
2517 }
2518
2519 static int __init comedi_init(void)
2520 {
2521         int i;
2522         int retval;
2523
2524         pr_info("comedi: version " COMEDI_RELEASE " - http://www.comedi.org\n");
2525
2526         if (comedi_num_legacy_minors < 0 ||
2527             comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
2528                 pr_err("comedi: error: invalid value for module parameter \"comedi_num_legacy_minors\".  Valid values are 0 through %i.\n",
2529                        COMEDI_NUM_BOARD_MINORS);
2530                 return -EINVAL;
2531         }
2532
2533         retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2534                                         COMEDI_NUM_MINORS, "comedi");
2535         if (retval)
2536                 return -EIO;
2537         cdev_init(&comedi_cdev, &comedi_fops);
2538         comedi_cdev.owner = THIS_MODULE;
2539         kobject_set_name(&comedi_cdev.kobj, "comedi");
2540         if (cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) {
2541                 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2542                                          COMEDI_NUM_MINORS);
2543                 return -EIO;
2544         }
2545         comedi_class = class_create(THIS_MODULE, "comedi");
2546         if (IS_ERR(comedi_class)) {
2547                 pr_err("comedi: failed to create class\n");
2548                 cdev_del(&comedi_cdev);
2549                 unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2550                                          COMEDI_NUM_MINORS);
2551                 return PTR_ERR(comedi_class);
2552         }
2553
2554         comedi_class->dev_groups = comedi_dev_groups;
2555
2556         /* XXX requires /proc interface */
2557         comedi_proc_init();
2558
2559         /* create devices files for legacy/manual use */
2560         for (i = 0; i < comedi_num_legacy_minors; i++) {
2561                 struct comedi_device *dev;
2562                 dev = comedi_alloc_board_minor(NULL);
2563                 if (IS_ERR(dev)) {
2564                         comedi_cleanup_board_minors();
2565                         cdev_del(&comedi_cdev);
2566                         unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0),
2567                                                  COMEDI_NUM_MINORS);
2568                         return PTR_ERR(dev);
2569                 } else {
2570                         /* comedi_alloc_board_minor() locked the mutex */
2571                         mutex_unlock(&dev->mutex);
2572                 }
2573         }
2574
2575         return 0;
2576 }
2577 module_init(comedi_init);
2578
2579 static void __exit comedi_cleanup(void)
2580 {
2581         int i;
2582
2583         comedi_cleanup_board_minors();
2584         for (i = 0; i < COMEDI_NUM_BOARD_MINORS; ++i)
2585                 BUG_ON(comedi_board_minor_table[i]);
2586         for (i = 0; i < COMEDI_NUM_SUBDEVICE_MINORS; ++i)
2587                 BUG_ON(comedi_subdevice_minor_table[i]);
2588
2589         class_destroy(comedi_class);
2590         cdev_del(&comedi_cdev);
2591         unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS);
2592
2593         comedi_proc_cleanup();
2594 }
2595 module_exit(comedi_cleanup);
2596
2597 MODULE_AUTHOR("http://www.comedi.org");
2598 MODULE_DESCRIPTION("Comedi core module");
2599 MODULE_LICENSE("GPL");