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