Skip to content

Commit e399396

Browse files
dtorJiri Kosina
authored andcommitted
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 <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Reviewed-by: Benjamin Tissoires <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 85ae911 commit e399396

File tree

1 file changed

+53
-62
lines changed

1 file changed

+53
-62
lines changed

drivers/hid/usbhid/hid-core.c

Lines changed: 53 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
7070
/*
7171
* Input submission and I/O error handler.
7272
*/
73-
static DEFINE_MUTEX(hid_open_mut);
74-
7573
static void hid_io_error(struct hid_device *hid);
7674
static int hid_submit_out(struct hid_device *hid);
7775
static int hid_submit_ctrl(struct hid_device *hid);
@@ -680,78 +678,71 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
680678
static int usbhid_open(struct hid_device *hid)
681679
{
682680
struct usbhid_device *usbhid = hid->driver_data;
683-
int res = 0;
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);
681+
int res;
714682

715-
/*
716-
* In case events are generated while nobody was listening,
717-
* some are released when the device is re-opened.
718-
* Wait 50 msec for the queue to empty before allowing events
719-
* to go through hid.
720-
*/
721-
if (res == 0 && !(hid->quirks & HID_QUIRK_ALWAYS_POLL))
722-
msleep(50);
723-
clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
683+
if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
684+
return 0;
685+
686+
res = usb_autopm_get_interface(usbhid->intf);
687+
/* the device must be awake to reliably request remote wakeup */
688+
if (res < 0)
689+
return -EIO;
690+
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+
}
724709
}
725-
done:
726-
mutex_unlock(&hid_open_mut);
710+
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);
727723
return res;
728724
}
729725

730726
static void usbhid_close(struct hid_device *hid)
731727
{
732728
struct usbhid_device *usbhid = hid->driver_data;
733729

734-
mutex_lock(&hid_open_mut);
730+
if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
731+
return;
735732

736-
/* protecting hid->open to make sure we don't restart
737-
* data acquistion due to a resumption we no longer
738-
* care about
733+
/*
734+
* Make sure we don't restart data acquisition due to
735+
* a resumption we no longer care about by avoiding racing
736+
* with hid_start_in().
739737
*/
740738
spin_lock_irq(&usbhid->lock);
741-
if (!--hid->open) {
742-
if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL))
743-
clear_bit(HID_IN_POLLING, &usbhid->iofl);
744-
clear_bit(HID_OPENED, &usbhid->iofl);
745-
spin_unlock_irq(&usbhid->lock);
746-
hid_cancel_delayed_stuff(usbhid);
747-
if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
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);
739+
clear_bit(HID_IN_POLLING, &usbhid->iofl);
740+
clear_bit(HID_OPENED, &usbhid->iofl);
741+
spin_unlock_irq(&usbhid->lock);
742+
743+
hid_cancel_delayed_stuff(usbhid);
744+
usb_kill_urb(usbhid->urbin);
745+
usbhid->intf->needs_remote_wakeup = 0;
755746
}
756747

757748
/*

0 commit comments

Comments
 (0)