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