diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-06-07 02:59:36 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2017-06-08 07:56:09 -0400 |
commit | e399396a6b061ba9e68e64e2867cc3a0f26f0ace (patch) | |
tree | 7708040de84727031ef9dc17fdc13a7c44d96e0f | |
parent | 85ae91133152c8c5e214303b8e26cfcbb91dfeb9 (diff) |
HID: usbhid: remove custom locking from usbhid_open/close
Now that HID core enforces serialization of transport driver open/close
calls we can remove custom locking from usbhid driver.
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 115 |
1 files changed, 53 insertions, 62 deletions
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index d927fe4ba592..76013eb5cb7f 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -70,8 +70,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " | |||
70 | /* | 70 | /* |
71 | * Input submission and I/O error handler. | 71 | * Input submission and I/O error handler. |
72 | */ | 72 | */ |
73 | static DEFINE_MUTEX(hid_open_mut); | ||
74 | |||
75 | static void hid_io_error(struct hid_device *hid); | 73 | static void hid_io_error(struct hid_device *hid); |
76 | static int hid_submit_out(struct hid_device *hid); | 74 | static int hid_submit_out(struct hid_device *hid); |
77 | static int hid_submit_ctrl(struct hid_device *hid); | 75 | static int hid_submit_ctrl(struct hid_device *hid); |
@@ -680,50 +678,48 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | |||
680 | static int usbhid_open(struct hid_device *hid) | 678 | static int usbhid_open(struct hid_device *hid) |
681 | { | 679 | { |
682 | struct usbhid_device *usbhid = hid->driver_data; | 680 | struct usbhid_device *usbhid = hid->driver_data; |
683 | int res = 0; | 681 | int res; |
684 | |||
685 | mutex_lock(&hid_open_mut); | ||
686 | if (!hid->open++) { | ||
687 | res = usb_autopm_get_interface(usbhid->intf); | ||
688 | /* the device must be awake to reliably request remote wakeup */ | ||
689 | if (res < 0) { | ||
690 | hid->open--; | ||
691 | res = -EIO; | ||
692 | goto done; | ||
693 | } | ||
694 | usbhid->intf->needs_remote_wakeup = 1; | ||
695 | set_bit(HID_OPENED, &usbhid->iofl); | ||
696 | set_bit(HID_IN_POLLING, &usbhid->iofl); | ||
697 | set_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
698 | res = hid_start_in(hid); | ||
699 | if (res) { | ||
700 | if (res != -ENOSPC) { | ||
701 | hid_io_error(hid); | ||
702 | res = 0; | ||
703 | } else { | ||
704 | /* no use opening if resources are insufficient */ | ||
705 | hid->open--; | ||
706 | clear_bit(HID_OPENED, &usbhid->iofl); | ||
707 | if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) | ||
708 | clear_bit(HID_IN_POLLING, &usbhid->iofl); | ||
709 | res = -EBUSY; | ||
710 | usbhid->intf->needs_remote_wakeup = 0; | ||
711 | } | ||
712 | } | ||
713 | usb_autopm_put_interface(usbhid->intf); | ||
714 | 682 | ||
715 | /* | 683 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) |
716 | * In case events are generated while nobody was listening, | 684 | return 0; |
717 | * some are released when the device is re-opened. | 685 | |
718 | * Wait 50 msec for the queue to empty before allowing events | 686 | res = usb_autopm_get_interface(usbhid->intf); |
719 | * to go through hid. | 687 | /* the device must be awake to reliably request remote wakeup */ |
720 | */ | 688 | if (res < 0) |
721 | if (res == 0 && !(hid->quirks & HID_QUIRK_ALWAYS_POLL)) | 689 | return -EIO; |
722 | msleep(50); | 690 | |
723 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); | 691 | usbhid->intf->needs_remote_wakeup = 1; |
692 | |||
693 | set_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
694 | set_bit(HID_OPENED, &usbhid->iofl); | ||
695 | set_bit(HID_IN_POLLING, &usbhid->iofl); | ||
696 | |||
697 | res = hid_start_in(hid); | ||
698 | if (res) { | ||
699 | if (res != -ENOSPC) { | ||
700 | hid_io_error(hid); | ||
701 | res = 0; | ||
702 | } else { | ||
703 | /* no use opening if resources are insufficient */ | ||
704 | res = -EBUSY; | ||
705 | clear_bit(HID_OPENED, &usbhid->iofl); | ||
706 | clear_bit(HID_IN_POLLING, &usbhid->iofl); | ||
707 | usbhid->intf->needs_remote_wakeup = 0; | ||
708 | } | ||
724 | } | 709 | } |
725 | done: | 710 | |
726 | mutex_unlock(&hid_open_mut); | 711 | usb_autopm_put_interface(usbhid->intf); |
712 | |||
713 | /* | ||
714 | * In case events are generated while nobody was listening, | ||
715 | * some are released when the device is re-opened. | ||
716 | * Wait 50 msec for the queue to empty before allowing events | ||
717 | * to go through hid. | ||
718 | */ | ||
719 | if (res == 0) | ||
720 | msleep(50); | ||
721 | |||
722 | clear_bit(HID_RESUME_RUNNING, &usbhid->iofl); | ||
727 | return res; | 723 | return res; |
728 | } | 724 | } |
729 | 725 | ||
@@ -731,27 +727,22 @@ static void usbhid_close(struct hid_device *hid) | |||
731 | { | 727 | { |
732 | struct usbhid_device *usbhid = hid->driver_data; | 728 | struct usbhid_device *usbhid = hid->driver_data; |
733 | 729 | ||
734 | mutex_lock(&hid_open_mut); | 730 | if (hid->quirks & HID_QUIRK_ALWAYS_POLL) |
731 | return; | ||
735 | 732 | ||
736 | /* protecting hid->open to make sure we don't restart | 733 | /* |
737 | * data acquistion due to a resumption we no longer | 734 | * Make sure we don't restart data acquisition due to |
738 | * care about | 735 | * a resumption we no longer care about by avoiding racing |
736 | * with hid_start_in(). | ||
739 | */ | 737 | */ |
740 | spin_lock_irq(&usbhid->lock); | 738 | spin_lock_irq(&usbhid->lock); |
741 | if (!--hid->open) { | 739 | clear_bit(HID_IN_POLLING, &usbhid->iofl); |
742 | if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) | 740 | clear_bit(HID_OPENED, &usbhid->iofl); |
743 | clear_bit(HID_IN_POLLING, &usbhid->iofl); | 741 | spin_unlock_irq(&usbhid->lock); |
744 | clear_bit(HID_OPENED, &usbhid->iofl); | 742 | |
745 | spin_unlock_irq(&usbhid->lock); | 743 | hid_cancel_delayed_stuff(usbhid); |
746 | hid_cancel_delayed_stuff(usbhid); | 744 | usb_kill_urb(usbhid->urbin); |
747 | if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) { | 745 | usbhid->intf->needs_remote_wakeup = 0; |
748 | usb_kill_urb(usbhid->urbin); | ||
749 | usbhid->intf->needs_remote_wakeup = 0; | ||
750 | } | ||
751 | } else { | ||
752 | spin_unlock_irq(&usbhid->lock); | ||
753 | } | ||
754 | mutex_unlock(&hid_open_mut); | ||
755 | } | 746 | } |
756 | 747 | ||
757 | /* | 748 | /* |