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