On Thu, 2014-09-04 at 13:36 +0200, Johan Hovold wrote:
> I got side-tracked with other stuff, but I should be able to submit the
> patch this week (just want to look through it once more first).
>
> Not sure the mark-last-busy needs to be moved, though. The device has
> already been woken up, and might as well stay unsuspended for a while
> longer should further events occur.
Hi,
on second thought I think that your moving of remote_wakeup is not good.
If we'd discard input anyway, we don't need to wake up devices for them.
So here's a version that does it that way.
Regards
Oliver
>From 46f2bba084c543922d6c67782d5ba47e663dbc37 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <[email protected]>
Date: Wed, 3 Sep 2014 15:26:39 +0200
Subject: [PATCH] usbhid: Johan's patch for devices that need constant polling
Some devices need constant polling or they crash.
So move the start of IO from open() to start()
Signed-off-by: Oliver Neukum <[email protected]>
---
drivers/hid/hid-ids.h | 1 +
drivers/hid/usbhid/hid-core.c | 33 +++++++++++++++++++++++++++------
drivers/hid/usbhid/hid-quirks.c | 1 +
include/linux/hid.h | 1 +
4 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 25cd674..b303a62 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -733,6 +733,7 @@
#define USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL 0xff
#define USB_VENDOR_ID_PIXART 0x093a
+#define USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE 0x2510
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN 0x8001
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1 0x8002
#define USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2 0x8003
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 79cf503..b214d1e 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -82,7 +82,7 @@ static int hid_start_in(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
spin_lock_irqsave(&usbhid->lock, flags);
- if (hid->open > 0 &&
+ if ((hid->open > 0 || hid->quirks & HID_QUIRK_ALWAYS_POLL) &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
!test_bit(HID_SUSPENDED, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
@@ -290,11 +290,17 @@ static void hid_irq_in(struct urb *urb)
switch (urb->status) {
case 0: /* success */
- usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
- hid_input_report(urb->context, HID_INPUT_REPORT,
- urb->transfer_buffer,
- urb->actual_length, 1);
+ /*
+ * do not not report unrequested data
+ * neither should it count for autosuspend
+ */
+ if (hid->open) {
+ usbhid_mark_busy(usbhid);
+ hid_input_report(urb->context, HID_INPUT_REPORT,
+ urb->transfer_buffer,
+ urb->actual_length, 1);
+ }
/*
* autosuspend refused while keys are pressed
* because most keyboards don't wake up when
@@ -735,7 +741,8 @@ void usbhid_close(struct hid_device *hid)
if (!--hid->open) {
spin_unlock_irq(&usbhid->lock);
hid_cancel_delayed_stuff(usbhid);
- usb_kill_urb(usbhid->urbin);
+ if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL))
+ usb_kill_urb(usbhid->urbin);
usbhid->intf->needs_remote_wakeup = 0;
} else {
spin_unlock_irq(&usbhid->lock);
@@ -1134,6 +1141,18 @@ static int usbhid_start(struct hid_device *hid)
set_bit(HID_STARTED, &usbhid->iofl);
+ if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
+ ret = usb_autopm_get_interface(usbhid->intf);
+ if (ret)
+ goto fail;
+ ret = hid_start_in(hid);
+ if (ret) {
+ dev_err(&hid->dev,
+ "failed to start in urb: %d\n", ret);
+ }
+ usb_autopm_put_interface(usbhid->intf);
+ }
+
/* Some keyboards don't work until their LEDs have been set.
* Since BIOSes do set the LEDs, it must be safe for any device
* that supports the keyboard boot protocol.
@@ -1166,6 +1185,8 @@ static void usbhid_stop(struct hid_device *hid)
if (WARN_ON(!usbhid))
return;
+ usbhid->intf->needs_remote_wakeup = 0;
+
clear_bit(HID_STARTED, &usbhid->iofl);
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 15225f3..79f94ae 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -79,6 +79,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE,
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1610, HID_QUIRK_NOGET
},
{ USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_1640, HID_QUIRK_NOGET
},
+ { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE,
HID_QUIRK_ALWAYS_POLL },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN,
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1,
HID_QUIRK_NO_INIT_REPORTS },
{ USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2,
HID_QUIRK_NO_INIT_REPORTS },
diff --git a/include/linux/hid.h b/include/linux/hid.h
index f53c4a9..26ee25f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -287,6 +287,7 @@ struct hid_item {
#define HID_QUIRK_HIDINPUT_FORCE 0x00000080
#define HID_QUIRK_NO_EMPTY_INPUT 0x00000100
#define HID_QUIRK_NO_INIT_INPUT_REPORTS 0x00000200
+#define HID_QUIRK_ALWAYS_POLL 0x00000400
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
#define HID_QUIRK_SKIP_OUTPUT_REPORT_ID 0x00020000
#define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP 0x00040000
--
1.8.4.5
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html