Commit 448cd1664a573e69f54bfd32f3bb7220212b6cf5

Authored by Dmitry Torokhov
1 parent d31b2865a4

Input: evdev - rearrange ioctl handling

Split ioctl handling into 3 separate sections: fixed-length ioctls,
variable-length ioctls and multi-number variable length handlers.
This reduces identation and makes the code a bit clearer.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

Showing 1 changed file with 73 additions and 68 deletions Side-by-side Diff

drivers/input/evdev.c
... ... @@ -492,13 +492,15 @@
492 492 }
493 493  
494 494 #define OLD_KEY_MAX 0x1ff
495   -static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode)
  495 +static int handle_eviocgbit(struct input_dev *dev,
  496 + unsigned int type, unsigned int size,
  497 + void __user *p, int compat_mode)
496 498 {
497 499 static unsigned long keymax_warn_time;
498 500 unsigned long *bits;
499 501 int len;
500 502  
501   - switch (_IOC_NR(cmd) & EV_MAX) {
  503 + switch (type) {
502 504  
503 505 case 0: bits = dev->evbit; len = EV_MAX; break;
504 506 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
... ... @@ -517,7 +519,7 @@
517 519 * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len'
518 520 * should be in bytes, not in bits.
519 521 */
520   - if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) {
  522 + if (type == EV_KEY && size == OLD_KEY_MAX) {
521 523 len = OLD_KEY_MAX;
522 524 if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
523 525 printk(KERN_WARNING
... ... @@ -528,7 +530,7 @@
528 530 BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
529 531 }
530 532  
531   - return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
  533 + return bits_to_user(bits, len, size, p, compat_mode);
532 534 }
533 535 #undef OLD_KEY_MAX
534 536  
535 537  
... ... @@ -542,8 +544,10 @@
542 544 struct ff_effect effect;
543 545 int __user *ip = (int __user *)p;
544 546 unsigned int i, t, u, v;
  547 + unsigned int size;
545 548 int error;
546 549  
  550 + /* First we check for fixed-length commands */
547 551 switch (cmd) {
548 552  
549 553 case EVIOCGVERSION:
550 554  
551 555  
552 556  
553 557  
554 558  
555 559  
556 560  
557 561  
558 562  
559 563  
560 564  
561 565  
562 566  
563 567  
564 568  
565 569  
566 570  
567 571  
568 572  
569 573  
570 574  
571 575  
572 576  
573 577  
574 578  
575 579  
576 580  
577 581  
578 582  
579 583  
... ... @@ -610,101 +614,102 @@
610 614 return evdev_grab(evdev, client);
611 615 else
612 616 return evdev_ungrab(evdev, client);
  617 + }
613 618  
614   - default:
  619 + size = _IOC_SIZE(cmd);
615 620  
616   - if (_IOC_TYPE(cmd) != 'E')
617   - return -EINVAL;
  621 + /* Now check variable-length commands */
  622 +#define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
618 623  
619   - if (_IOC_DIR(cmd) == _IOC_READ) {
  624 + switch (EVIOC_MASK_SIZE(cmd)) {
620 625  
621   - if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
622   - return handle_eviocgbit(dev, cmd, p, compat_mode);
  626 + case EVIOCGKEY(0):
  627 + return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode);
623 628  
624   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
625   - return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
626   - p, compat_mode);
  629 + case EVIOCGLED(0):
  630 + return bits_to_user(dev->led, LED_MAX, size, p, compat_mode);
627 631  
628   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
629   - return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
630   - p, compat_mode);
  632 + case EVIOCGSND(0):
  633 + return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode);
631 634  
632   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
633   - return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
634   - p, compat_mode);
  635 + case EVIOCGSW(0):
  636 + return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode);
635 637  
636   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
637   - return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
638   - p, compat_mode);
  638 + case EVIOCGNAME(0):
  639 + return str_to_user(dev->name, size, p);
639 640  
640   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
641   - return str_to_user(dev->name, _IOC_SIZE(cmd), p);
  641 + case EVIOCGPHYS(0):
  642 + return str_to_user(dev->phys, size, p);
642 643  
643   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
644   - return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
  644 + case EVIOCGUNIQ(0):
  645 + return str_to_user(dev->uniq, size, p);
645 646  
646   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
647   - return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
  647 + case EVIOC_MASK_SIZE(EVIOCSFF):
  648 + if (input_ff_effect_from_user(p, size, &effect))
  649 + return -EFAULT;
648 650  
649   - if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
  651 + error = input_ff_upload(dev, &effect, file);
650 652  
651   - t = _IOC_NR(cmd) & ABS_MAX;
652   - abs = dev->absinfo[t];
  653 + if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
  654 + return -EFAULT;
653 655  
654   - if (copy_to_user(p, &abs, min_t(size_t,
655   - _IOC_SIZE(cmd),
656   - sizeof(struct input_absinfo))))
657   - return -EFAULT;
  656 + return error;
  657 + }
658 658  
659   - return 0;
660   - }
  659 + /* Multi-number variable-length handlers */
  660 + if (_IOC_TYPE(cmd) != 'E')
  661 + return -EINVAL;
661 662  
662   - }
  663 + if (_IOC_DIR(cmd) == _IOC_READ) {
663 664  
664   - if (_IOC_DIR(cmd) == _IOC_WRITE) {
  665 + if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0)))
  666 + return handle_eviocgbit(dev,
  667 + _IOC_NR(cmd) & EV_MAX, size,
  668 + p, compat_mode);
665 669  
666   - if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) {
  670 + if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
667 671  
668   - if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect))
669   - return -EFAULT;
  672 + t = _IOC_NR(cmd) & ABS_MAX;
  673 + abs = dev->absinfo[t];
670 674  
671   - error = input_ff_upload(dev, &effect, file);
  675 + if (copy_to_user(p, &abs, min_t(size_t,
  676 + size, sizeof(struct input_absinfo))))
  677 + return -EFAULT;
672 678  
673   - if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
674   - return -EFAULT;
  679 + return 0;
  680 + }
  681 + }
675 682  
676   - return error;
677   - }
  683 + if (_IOC_DIR(cmd) == _IOC_READ) {
678 684  
679   - if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
  685 + if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
680 686  
681   - t = _IOC_NR(cmd) & ABS_MAX;
  687 + t = _IOC_NR(cmd) & ABS_MAX;
682 688  
683   - if (copy_from_user(&abs, p, min_t(size_t,
684   - _IOC_SIZE(cmd),
685   - sizeof(struct input_absinfo))))
686   - return -EFAULT;
  689 + if (copy_from_user(&abs, p, min_t(size_t,
  690 + size, sizeof(struct input_absinfo))))
  691 + return -EFAULT;
687 692  
688   - if (_IOC_SIZE(cmd) < sizeof(struct input_absinfo))
689   - abs.resolution = 0;
  693 + if (size < sizeof(struct input_absinfo))
  694 + abs.resolution = 0;
690 695  
691   - /* We can't change number of reserved MT slots */
692   - if (t == ABS_MT_SLOT)
693   - return -EINVAL;
  696 + /* We can't change number of reserved MT slots */
  697 + if (t == ABS_MT_SLOT)
  698 + return -EINVAL;
694 699  
695   - /*
696   - * Take event lock to ensure that we are not
697   - * changing device parameters in the middle
698   - * of event.
699   - */
700   - spin_lock_irq(&dev->event_lock);
701   - dev->absinfo[t] = abs;
702   - spin_unlock_irq(&dev->event_lock);
  700 + /*
  701 + * Take event lock to ensure that we are not
  702 + * changing device parameters in the middle
  703 + * of event.
  704 + */
  705 + spin_lock_irq(&dev->event_lock);
  706 + dev->absinfo[t] = abs;
  707 + spin_unlock_irq(&dev->event_lock);
703 708  
704   - return 0;
705   - }
  709 + return 0;
706 710 }
707 711 }
  712 +
708 713 return -EINVAL;
709 714 }
710 715