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