]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb-core bInterval quirk
authorJames P Michels III <james.p.michels@gmail.com>
Sun, 27 Jul 2014 17:28:04 +0000 (13:28 -0400)
committerZefan Li <lizefan@huawei.com>
Tue, 14 Apr 2015 09:33:56 +0000 (17:33 +0800)
commit cd83ce9e6195aa3ea15ab4db92892802c20df5d0 upstream.

This patch adds a usb quirk to support devices with interupt endpoints
and bInterval values expressed as microframes. The quirk causes the
parse endpoint function to modify the reported bInterval to a standards
conforming value.

There is currently code in the endpoint parser that checks for
bIntervals that are outside of the valid range (1-16 for USB 2+ high
speed and super speed interupt endpoints). In this case, the code assumes
the bInterval is being reported in 1ms frames. As well, the correction
is only applied if the original bInterval value is out of the 1-16 range.

With this quirk applied to the device, the bInterval will be
accurately adjusted from microframes to an exponent.

Signed-off-by: James P Michels III <james.p.michels@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Zefan Li <lizefan@huawei.com>
drivers/usb/core/config.c
drivers/usb/core/quirks.c
include/linux/usb/quirks.h

index 6ed7e7c787d896269d2936052d212d33602a4642..cc1004a2f9cd4891382011530624d50e86b2b247 100644 (file)
@@ -201,6 +201,17 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
                        if (n == 0)
                                n = 9;  /* 32 ms = 2^(9-1) uframes */
                        j = 16;
+
+                       /*
+                        * Adjust bInterval for quirked devices.
+                        * This quirk fixes bIntervals reported in
+                        * linear microframes.
+                        */
+                       if (to_usb_device(ddev)->quirks &
+                               USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) {
+                               n = clamp(fls(d->bInterval), i, j);
+                               i = j = n;
+                       }
                        break;
                default:                /* USB_SPEED_FULL or _LOW */
                        /* For low-speed, 10 ms is the official minimum.
index ada0df9ebf34c2c668fb7a126e87b79ba3d26c56..a60c5b784c719325068a0d56332544a86f56a390 100644 (file)
@@ -152,6 +152,10 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* SKYMEDI USB_DRIVE */
        { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Razer - Razer Blade Keyboard */
+       { USB_DEVICE(0x1532, 0x0116), .driver_info =
+                       USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+
        /* BUILDWIN Photo Frame */
        { USB_DEVICE(0x1908, 0x1315), .driver_info =
                        USB_QUIRK_HONOR_BNUMINTERFACES },
index d0d2af09dcc6076cb4b2dd5479188140098bbd8c..0972470bb072b362289e5b68cdc2d77cd6cf1f61 100644 (file)
 /* device can't handle device_qualifier descriptor requests */
 #define USB_QUIRK_DEVICE_QUALIFIER     0x00000100
 
+/*
+ * For high speed and super speed interupt endpoints, the USB 2.0 and
+ * USB 3.0 spec require the interval in microframes
+ * (1 microframe = 125 microseconds) to be calculated as
+ * interval = 2 ^ (bInterval-1).
+ *
+ * Devices with this quirk report their bInterval as the result of this
+ * calculation instead of the exponent variable used in the calculation.
+ */
+#define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL 0x00000080
+
 #endif /* __LINUX_USB_QUIRKS_H */