Linux Audio

Check our new training course

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