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