diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-12-30 00:20:30 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-12-30 00:21:47 -0500 |
commit | d392da5207352f09030e95d9ea335a4225667ec0 (patch) | |
tree | 7d6cd1932afcad0a5619a5c504a6d93ca318187c /drivers/input/evdev.c | |
parent | e39d5ef678045d61812c1401f04fe8edb14d6359 (diff) | |
parent | 387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff) |
Merge v2.6.37-rc8 into powerpc/next
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 260 |
1 files changed, 162 insertions, 98 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 054edf346e0b..68f09a868434 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -28,7 +28,7 @@ struct evdev { | |||
28 | int minor; | 28 | int minor; |
29 | struct input_handle handle; | 29 | struct input_handle handle; |
30 | wait_queue_head_t wait; | 30 | wait_queue_head_t wait; |
31 | struct evdev_client *grab; | 31 | struct evdev_client __rcu *grab; |
32 | struct list_head client_list; | 32 | struct list_head client_list; |
33 | spinlock_t client_lock; /* protects client_list */ | 33 | spinlock_t client_lock; /* protects client_list */ |
34 | struct mutex mutex; | 34 | struct mutex mutex; |
@@ -492,13 +492,15 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
492 | } | 492 | } |
493 | 493 | ||
494 | #define OLD_KEY_MAX 0x1ff | 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 | static unsigned long keymax_warn_time; | 499 | static unsigned long keymax_warn_time; |
498 | unsigned long *bits; | 500 | unsigned long *bits; |
499 | int len; | 501 | int len; |
500 | 502 | ||
501 | switch (_IOC_NR(cmd) & EV_MAX) { | 503 | switch (type) { |
502 | 504 | ||
503 | case 0: bits = dev->evbit; len = EV_MAX; break; | 505 | case 0: bits = dev->evbit; len = EV_MAX; break; |
504 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | 506 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; |
@@ -517,7 +519,7 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
517 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' | 519 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' |
518 | * should be in bytes, not in bits. | 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 | len = OLD_KEY_MAX; | 523 | len = OLD_KEY_MAX; |
522 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
523 | printk(KERN_WARNING | 525 | printk(KERN_WARNING |
@@ -528,10 +530,81 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user | |||
528 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | 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 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
534 | 536 | ||
537 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) | ||
538 | { | ||
539 | struct input_keymap_entry ke = { | ||
540 | .len = sizeof(unsigned int), | ||
541 | .flags = 0, | ||
542 | }; | ||
543 | int __user *ip = (int __user *)p; | ||
544 | int error; | ||
545 | |||
546 | /* legacy case */ | ||
547 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
548 | return -EFAULT; | ||
549 | |||
550 | error = input_get_keycode(dev, &ke); | ||
551 | if (error) | ||
552 | return error; | ||
553 | |||
554 | if (put_user(ke.keycode, ip + 1)) | ||
555 | return -EFAULT; | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) | ||
561 | { | ||
562 | struct input_keymap_entry ke; | ||
563 | int error; | ||
564 | |||
565 | if (copy_from_user(&ke, p, sizeof(ke))) | ||
566 | return -EFAULT; | ||
567 | |||
568 | error = input_get_keycode(dev, &ke); | ||
569 | if (error) | ||
570 | return error; | ||
571 | |||
572 | if (copy_to_user(p, &ke, sizeof(ke))) | ||
573 | return -EFAULT; | ||
574 | |||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) | ||
579 | { | ||
580 | struct input_keymap_entry ke = { | ||
581 | .len = sizeof(unsigned int), | ||
582 | .flags = 0, | ||
583 | }; | ||
584 | int __user *ip = (int __user *)p; | ||
585 | |||
586 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | ||
587 | return -EFAULT; | ||
588 | |||
589 | if (get_user(ke.keycode, ip + 1)) | ||
590 | return -EFAULT; | ||
591 | |||
592 | return input_set_keycode(dev, &ke); | ||
593 | } | ||
594 | |||
595 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) | ||
596 | { | ||
597 | struct input_keymap_entry ke; | ||
598 | |||
599 | if (copy_from_user(&ke, p, sizeof(ke))) | ||
600 | return -EFAULT; | ||
601 | |||
602 | if (ke.len > sizeof(ke.scancode)) | ||
603 | return -EINVAL; | ||
604 | |||
605 | return input_set_keycode(dev, &ke); | ||
606 | } | ||
607 | |||
535 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, | 608 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
536 | void __user *p, int compat_mode) | 609 | void __user *p, int compat_mode) |
537 | { | 610 | { |
@@ -542,8 +615,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
542 | struct ff_effect effect; | 615 | struct ff_effect effect; |
543 | int __user *ip = (int __user *)p; | 616 | int __user *ip = (int __user *)p; |
544 | unsigned int i, t, u, v; | 617 | unsigned int i, t, u, v; |
618 | unsigned int size; | ||
545 | int error; | 619 | int error; |
546 | 620 | ||
621 | /* First we check for fixed-length commands */ | ||
547 | switch (cmd) { | 622 | switch (cmd) { |
548 | 623 | ||
549 | case EVIOCGVERSION: | 624 | case EVIOCGVERSION: |
@@ -576,25 +651,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
576 | 651 | ||
577 | return 0; | 652 | return 0; |
578 | 653 | ||
579 | case EVIOCGKEYCODE: | ||
580 | if (get_user(t, ip)) | ||
581 | return -EFAULT; | ||
582 | |||
583 | error = input_get_keycode(dev, t, &v); | ||
584 | if (error) | ||
585 | return error; | ||
586 | |||
587 | if (put_user(v, ip + 1)) | ||
588 | return -EFAULT; | ||
589 | |||
590 | return 0; | ||
591 | |||
592 | case EVIOCSKEYCODE: | ||
593 | if (get_user(t, ip) || get_user(v, ip + 1)) | ||
594 | return -EFAULT; | ||
595 | |||
596 | return input_set_keycode(dev, t, v); | ||
597 | |||
598 | case EVIOCRMFF: | 654 | case EVIOCRMFF: |
599 | return input_ff_erase(dev, (int)(unsigned long) p, file); | 655 | return input_ff_erase(dev, (int)(unsigned long) p, file); |
600 | 656 | ||
@@ -611,111 +667,118 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
611 | else | 667 | else |
612 | return evdev_ungrab(evdev, client); | 668 | return evdev_ungrab(evdev, client); |
613 | 669 | ||
614 | default: | 670 | case EVIOCGKEYCODE: |
671 | return evdev_handle_get_keycode(dev, p); | ||
615 | 672 | ||
616 | if (_IOC_TYPE(cmd) != 'E') | 673 | case EVIOCSKEYCODE: |
617 | return -EINVAL; | 674 | return evdev_handle_set_keycode(dev, p); |
675 | |||
676 | case EVIOCGKEYCODE_V2: | ||
677 | return evdev_handle_get_keycode_v2(dev, p); | ||
618 | 678 | ||
619 | if (_IOC_DIR(cmd) == _IOC_READ) { | 679 | case EVIOCSKEYCODE_V2: |
680 | return evdev_handle_set_keycode_v2(dev, p); | ||
681 | } | ||
620 | 682 | ||
621 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) | 683 | size = _IOC_SIZE(cmd); |
622 | return handle_eviocgbit(dev, cmd, p, compat_mode); | ||
623 | 684 | ||
624 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | 685 | /* Now check variable-length commands */ |
625 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), | 686 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
626 | p, compat_mode); | 687 | switch (EVIOC_MASK_SIZE(cmd)) { |
627 | 688 | ||
628 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) | 689 | case EVIOCGKEY(0): |
629 | return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd), | 690 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
630 | p, compat_mode); | ||
631 | 691 | ||
632 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) | 692 | case EVIOCGLED(0): |
633 | return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd), | 693 | return bits_to_user(dev->led, LED_MAX, size, p, compat_mode); |
634 | p, compat_mode); | ||
635 | 694 | ||
636 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) | 695 | case EVIOCGSND(0): |
637 | return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd), | 696 | return bits_to_user(dev->snd, SND_MAX, size, p, compat_mode); |
638 | p, compat_mode); | ||
639 | 697 | ||
640 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 698 | case EVIOCGSW(0): |
641 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); | 699 | return bits_to_user(dev->sw, SW_MAX, size, p, compat_mode); |
642 | 700 | ||
643 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 701 | case EVIOCGNAME(0): |
644 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 702 | return str_to_user(dev->name, size, p); |
645 | 703 | ||
646 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) | 704 | case EVIOCGPHYS(0): |
647 | return str_to_user(dev->uniq, _IOC_SIZE(cmd), p); | 705 | return str_to_user(dev->phys, size, p); |
648 | 706 | ||
649 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { | 707 | case EVIOCGUNIQ(0): |
708 | return str_to_user(dev->uniq, size, p); | ||
650 | 709 | ||
651 | t = _IOC_NR(cmd) & ABS_MAX; | 710 | case EVIOC_MASK_SIZE(EVIOCSFF): |
711 | if (input_ff_effect_from_user(p, size, &effect)) | ||
712 | return -EFAULT; | ||
652 | 713 | ||
653 | abs.value = dev->abs[t]; | 714 | error = input_ff_upload(dev, &effect, file); |
654 | abs.minimum = dev->absmin[t]; | ||
655 | abs.maximum = dev->absmax[t]; | ||
656 | abs.fuzz = dev->absfuzz[t]; | ||
657 | abs.flat = dev->absflat[t]; | ||
658 | abs.resolution = dev->absres[t]; | ||
659 | 715 | ||
660 | if (copy_to_user(p, &abs, min_t(size_t, | 716 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) |
661 | _IOC_SIZE(cmd), | 717 | return -EFAULT; |
662 | sizeof(struct input_absinfo)))) | ||
663 | return -EFAULT; | ||
664 | 718 | ||
665 | return 0; | 719 | return error; |
666 | } | 720 | } |
667 | 721 | ||
668 | } | 722 | /* Multi-number variable-length handlers */ |
723 | if (_IOC_TYPE(cmd) != 'E') | ||
724 | return -EINVAL; | ||
725 | |||
726 | if (_IOC_DIR(cmd) == _IOC_READ) { | ||
669 | 727 | ||
670 | if (_IOC_DIR(cmd) == _IOC_WRITE) { | 728 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) |
729 | return handle_eviocgbit(dev, | ||
730 | _IOC_NR(cmd) & EV_MAX, size, | ||
731 | p, compat_mode); | ||
671 | 732 | ||
672 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCSFF)) { | 733 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { |
673 | 734 | ||
674 | if (input_ff_effect_from_user(p, _IOC_SIZE(cmd), &effect)) | 735 | if (!dev->absinfo) |
675 | return -EFAULT; | 736 | return -EINVAL; |
676 | 737 | ||
677 | error = input_ff_upload(dev, &effect, file); | 738 | t = _IOC_NR(cmd) & ABS_MAX; |
739 | abs = dev->absinfo[t]; | ||
740 | |||
741 | if (copy_to_user(p, &abs, min_t(size_t, | ||
742 | size, sizeof(struct input_absinfo)))) | ||
743 | return -EFAULT; | ||
678 | 744 | ||
679 | if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | 745 | return 0; |
680 | return -EFAULT; | 746 | } |
747 | } | ||
681 | 748 | ||
682 | return error; | 749 | if (_IOC_DIR(cmd) == _IOC_WRITE) { |
683 | } | ||
684 | 750 | ||
685 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { | 751 | if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { |
686 | 752 | ||
687 | t = _IOC_NR(cmd) & ABS_MAX; | 753 | if (!dev->absinfo) |
754 | return -EINVAL; | ||
688 | 755 | ||
689 | if (copy_from_user(&abs, p, min_t(size_t, | 756 | t = _IOC_NR(cmd) & ABS_MAX; |
690 | _IOC_SIZE(cmd), | ||
691 | sizeof(struct input_absinfo)))) | ||
692 | return -EFAULT; | ||
693 | 757 | ||
694 | /* We can't change number of reserved MT slots */ | 758 | if (copy_from_user(&abs, p, min_t(size_t, |
695 | if (t == ABS_MT_SLOT) | 759 | size, sizeof(struct input_absinfo)))) |
696 | return -EINVAL; | 760 | return -EFAULT; |
697 | 761 | ||
698 | /* | 762 | if (size < sizeof(struct input_absinfo)) |
699 | * Take event lock to ensure that we are not | 763 | abs.resolution = 0; |
700 | * changing device parameters in the middle | ||
701 | * of event. | ||
702 | */ | ||
703 | spin_lock_irq(&dev->event_lock); | ||
704 | 764 | ||
705 | dev->abs[t] = abs.value; | 765 | /* We can't change number of reserved MT slots */ |
706 | dev->absmin[t] = abs.minimum; | 766 | if (t == ABS_MT_SLOT) |
707 | dev->absmax[t] = abs.maximum; | 767 | return -EINVAL; |
708 | dev->absfuzz[t] = abs.fuzz; | ||
709 | dev->absflat[t] = abs.flat; | ||
710 | dev->absres[t] = _IOC_SIZE(cmd) < sizeof(struct input_absinfo) ? | ||
711 | 0 : abs.resolution; | ||
712 | 768 | ||
713 | spin_unlock_irq(&dev->event_lock); | 769 | /* |
770 | * Take event lock to ensure that we are not | ||
771 | * changing device parameters in the middle | ||
772 | * of event. | ||
773 | */ | ||
774 | spin_lock_irq(&dev->event_lock); | ||
775 | dev->absinfo[t] = abs; | ||
776 | spin_unlock_irq(&dev->event_lock); | ||
714 | 777 | ||
715 | return 0; | 778 | return 0; |
716 | } | ||
717 | } | 779 | } |
718 | } | 780 | } |
781 | |||
719 | return -EINVAL; | 782 | return -EINVAL; |
720 | } | 783 | } |
721 | 784 | ||
@@ -767,7 +830,8 @@ static const struct file_operations evdev_fops = { | |||
767 | .compat_ioctl = evdev_ioctl_compat, | 830 | .compat_ioctl = evdev_ioctl_compat, |
768 | #endif | 831 | #endif |
769 | .fasync = evdev_fasync, | 832 | .fasync = evdev_fasync, |
770 | .flush = evdev_flush | 833 | .flush = evdev_flush, |
834 | .llseek = no_llseek, | ||
771 | }; | 835 | }; |
772 | 836 | ||
773 | static int evdev_install_chrdev(struct evdev *evdev) | 837 | static int evdev_install_chrdev(struct evdev *evdev) |