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