]> 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)
committerLuis Henriques <luis.henriques@canonical.com>
Wed, 4 Feb 2015 10:58:13 +0000 (10:58 +0000)
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>
[ luis: 3.16-stable prereq for:
  e5dff0e80463 "USB: Add OTG PET device to TPL" ]
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
drivers/usb/core/config.c
drivers/usb/core/quirks.c
include/linux/usb/quirks.h

index 1ab4df1de2daddb7db1a6032b1b8e9320dd9b591..b2a540b43f97c3bb8c045725fe68fed1a0601ae6 100644 (file)
@@ -199,6 +199,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 666399a23da38f235bb4298f0f0376485fb97526..7d3673651b78986dda89779246594ad4a37c5c2e 100644 (file)
@@ -161,6 +161,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 8b96ae2a38fe1a57b6b639267305b2629d6ac180..4a185a0f624262c970141a007b1e8296814ba199 100644 (file)
    descriptor */
 #define USB_QUIRK_DELAY_INIT           0x00000040
 
+/*
+ * 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
+
 /* device generates spurious wakeup, ignore remote wakeup capability */
 #define USB_QUIRK_IGNORE_REMOTE_WAKEUP 0x00000200