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 | /* |
