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