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