cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

comedi_fops.c (81810B)


      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 snprintf(buf, PAGE_SIZE, "%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 snprintf(buf, PAGE_SIZE, "%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 snprintf(buf, PAGE_SIZE, "%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 snprintf(buf, PAGE_SIZE, "%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");