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