usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk
authorSamuel Thibault <samuel.thibault@ens-lyon.org>
Mon, 13 Mar 2017 19:50:08 +0000 (20:50 +0100)
committerJiri Slaby <jslaby@suse.cz>
Fri, 7 Apr 2017 08:38:25 +0000 (10:38 +0200)
commit 3243367b209faed5c320a4e5f9a565ee2a2ba958 upstream.

Some USB 2.0 devices erroneously report millisecond values in
bInterval. The generic config code manages to catch most of them,
but in some cases it's not completely enough.

The case at stake here is a USB 2.0 braille device, which wants to
announce 10ms and thus sets bInterval to 10, but with the USB 2.0
computation that yields to 64ms.  It happens that one can type fast
enough to reach this interval and get the device buffers overflown,
leading to problematic latencies.  The generic config code does not
catch this case because the 64ms is considered a sane enough value.

This change thus adds a USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL quirk
to mark devices which actually report milliseconds in bInterval,
and marks Vario Ultra devices as needing it.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
drivers/usb/core/config.c
drivers/usb/core/quirks.c
include/linux/usb/quirks.h

index 15b39065f1dc4ac5820c349800b298600faeecd6..ee8e42064d25a8e9b81087bdc5912978f7ef4b05 100644 (file)
@@ -248,6 +248,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
 
                        /*
                         * Adjust bInterval for quirked devices.
+                        */
+                       /*
+                        * This quirk fixes bIntervals reported in ms.
+                        */
+                       if (to_usb_device(ddev)->quirks &
+                               USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
+                               n = clamp(fls(d->bInterval) + 3, i, j);
+                               i = j = n;
+                       }
+                       /*
                         * This quirk fixes bIntervals reported in
                         * linear microframes.
                         */
index 094fe92ac21f81c809cd0f8fd49b1895ba315f3f..f792e6bea6b4e4d13f549fa21112b011bda220e7 100644 (file)
@@ -164,6 +164,14 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* M-Systems Flash Disk Pioneers */
        { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Baum Vario Ultra */
+       { USB_DEVICE(0x0904, 0x6101), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+       { USB_DEVICE(0x0904, 0x6102), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+       { USB_DEVICE(0x0904, 0x6103), .driver_info =
+                       USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+
        /* Keytouch QWERTY Panel keyboard */
        { USB_DEVICE(0x0926, 0x3333), .driver_info =
                        USB_QUIRK_CONFIG_INTF_STRINGS },
index 7eb814c60b5da97a06013010426cba8aedc122bd..24872fc869624fc95ac5ddf50130ad04ca49904f 100644 (file)
 /* device can't handle Link Power Management */
 #define USB_QUIRK_NO_LPM                       BIT(10)
 
+/*
+ * Device reports its bInterval as linear frames instead of the
+ * USB 2.0 calculation.
+ */
+#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL  BIT(11)
+
 #endif /* __LINUX_USB_QUIRKS_H */