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