root/drivers/staging/comedi/comedi_fops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. comedi_device_init
  2. comedi_dev_kref_release
  3. comedi_dev_put
  4. comedi_dev_get
  5. comedi_device_cleanup
  6. comedi_clear_board_dev
  7. comedi_clear_board_minor
  8. comedi_free_board_dev
  9. comedi_subdevice_from_minor
  10. comedi_dev_get_from_board_minor
  11. comedi_dev_get_from_subdevice_minor
  12. comedi_dev_get_from_minor
  13. comedi_read_subdevice
  14. comedi_write_subdevice
  15. comedi_file_reset
  16. comedi_file_check
  17. comedi_file_read_subdevice
  18. comedi_file_write_subdevice
  19. resize_async_buffer
  20. max_read_buffer_kb_show
  21. max_read_buffer_kb_store
  22. read_buffer_kb_show
  23. read_buffer_kb_store
  24. max_write_buffer_kb_show
  25. max_write_buffer_kb_store
  26. write_buffer_kb_show
  27. write_buffer_kb_store
  28. __comedi_clear_subdevice_runflags
  29. __comedi_set_subdevice_runflags
  30. comedi_update_subdevice_runflags
  31. __comedi_get_subdevice_runflags
  32. comedi_get_subdevice_runflags
  33. comedi_is_runflags_running
  34. comedi_is_runflags_in_error
  35. comedi_is_subdevice_running
  36. __comedi_is_subdevice_running
  37. comedi_can_auto_free_spriv
  38. comedi_set_spriv_auto_free
  39. comedi_alloc_spriv
  40. do_become_nonbusy
  41. do_cancel
  42. comedi_device_cancel_all
  43. is_device_busy
  44. do_devconfig_ioctl
  45. do_bufconfig_ioctl
  46. do_devinfo_ioctl
  47. do_subdinfo_ioctl
  48. do_chaninfo_ioctl
  49. do_bufinfo_ioctl
  50. check_insn_config_length
  51. check_insn_device_config_length
  52. get_valid_routes
  53. parse_insn
  54. do_insnlist_ioctl
  55. do_insn_ioctl
  56. __comedi_get_user_cmd
  57. __comedi_get_user_chanlist
  58. do_cmd_ioctl
  59. do_cmdtest_ioctl
  60. do_lock_ioctl
  61. do_unlock_ioctl
  62. do_cancel_ioctl
  63. do_poll_ioctl
  64. do_setrsubd_ioctl
  65. do_setwsubd_ioctl
  66. comedi_unlocked_ioctl
  67. comedi_vm_open
  68. comedi_vm_close
  69. comedi_vm_access
  70. comedi_mmap
  71. comedi_poll
  72. comedi_write
  73. comedi_read
  74. comedi_open
  75. comedi_fasync
  76. comedi_close
  77. comedi_event
  78. comedi_alloc_board_minor
  79. comedi_release_hardware_device
  80. comedi_alloc_subdevice_minor
  81. comedi_free_subdevice_minor
  82. comedi_cleanup_board_minors
  83. comedi_init
  84. comedi_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */