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