Skip to content

Commit 28cbc86

Browse files
dtorJiri Kosina
authored andcommitted
HID: usbhid: do not rely on hid->open when deciding to do IO
Instead of checking hid->open (that we plan on having HID core manage) in hid_start_in(), let's allocate a couple of new flags: HID_IN_POLLING and HID_OPENED, and use them to decide whether we should be submitting URBs or not. 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 9a83563 commit 28cbc86

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

drivers/hid/usbhid/hid-core.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ static int hid_start_in(struct hid_device *hid)
8585
struct usbhid_device *usbhid = hid->driver_data;
8686

8787
spin_lock_irqsave(&usbhid->lock, flags);
88-
if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) &&
89-
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
90-
!test_bit(HID_SUSPENDED, &usbhid->iofl) &&
91-
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
88+
if (test_bit(HID_IN_POLLING, &usbhid->iofl) &&
89+
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
90+
!test_bit(HID_SUSPENDED, &usbhid->iofl) &&
91+
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
9292
rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
9393
if (rc != 0) {
9494
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
@@ -272,13 +272,13 @@ static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
272272
static void hid_irq_in(struct urb *urb)
273273
{
274274
struct hid_device *hid = urb->context;
275-
struct usbhid_device *usbhid = hid->driver_data;
275+
struct usbhid_device *usbhid = hid->driver_data;
276276
int status;
277277

278278
switch (urb->status) {
279279
case 0: /* success */
280280
usbhid->retry_delay = 0;
281-
if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) && !hid->open)
281+
if (!test_bit(HID_OPENED, &usbhid->iofl))
282282
break;
283283
usbhid_mark_busy(usbhid);
284284
if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
@@ -692,6 +692,8 @@ static int usbhid_open(struct hid_device *hid)
692692
goto done;
693693
}
694694
usbhid->intf->needs_remote_wakeup = 1;
695+
set_bit(HID_OPENED, &usbhid->iofl);
696+
set_bit(HID_IN_POLLING, &usbhid->iofl);
695697
set_bit(HID_RESUME_RUNNING, &usbhid->iofl);
696698
res = hid_start_in(hid);
697699
if (res) {
@@ -701,6 +703,9 @@ static int usbhid_open(struct hid_device *hid)
701703
} else {
702704
/* no use opening if resources are insufficient */
703705
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);
704709
res = -EBUSY;
705710
usbhid->intf->needs_remote_wakeup = 0;
706711
}
@@ -734,6 +739,9 @@ static void usbhid_close(struct hid_device *hid)
734739
*/
735740
spin_lock_irq(&usbhid->lock);
736741
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);
737745
spin_unlock_irq(&usbhid->lock);
738746
hid_cancel_delayed_stuff(usbhid);
739747
if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
@@ -1135,6 +1143,7 @@ static int usbhid_start(struct hid_device *hid)
11351143
ret = usb_autopm_get_interface(usbhid->intf);
11361144
if (ret)
11371145
goto fail;
1146+
set_bit(HID_IN_POLLING, &usbhid->iofl);
11381147
usbhid->intf->needs_remote_wakeup = 1;
11391148
ret = hid_start_in(hid);
11401149
if (ret) {
@@ -1176,8 +1185,10 @@ static void usbhid_stop(struct hid_device *hid)
11761185
if (WARN_ON(!usbhid))
11771186
return;
11781187

1179-
if (hid->quirks & HID_QUIRK_ALWAYS_POLL)
1188+
if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
1189+
clear_bit(HID_IN_POLLING, &usbhid->iofl);
11801190
usbhid->intf->needs_remote_wakeup = 0;
1191+
}
11811192

11821193
clear_bit(HID_STARTED, &usbhid->iofl);
11831194
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */

drivers/hid/usbhid/usbhid.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ struct usb_interface *usbhid_find_interface(int minor);
4949
#define HID_KEYS_PRESSED 10
5050
#define HID_NO_BANDWIDTH 11
5151
#define HID_RESUME_RUNNING 12
52+
/*
53+
* The device is opened, meaning there is a client that is interested
54+
* in data coming from the device.
55+
*/
56+
#define HID_OPENED 13
57+
/*
58+
* We are polling input endpoint by [re]submitting IN URB, because
59+
* either HID device is opened or ALWAYS POLL quirk is set for the
60+
* device.
61+
*/
62+
#define HID_IN_POLLING 14
5263

5364
/*
5465
* USB-specific HID struct, to be pointed to

0 commit comments

Comments
 (0)