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