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