aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames P Michels III <james.p.michels@gmail.com>2014-07-27 13:28:04 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-08-01 18:47:05 -0400
commitcd83ce9e6195aa3ea15ab4db92892802c20df5d0 (patch)
tree8b75990711e5ce8d060f2e7e236c32ca68e17a14
parent4bdcde358b4bda74e356841d351945ca3f2245dd (diff)
usb-core bInterval quirk
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>
-rw-r--r--drivers/usb/core/config.c11
-rw-r--r--drivers/usb/core/quirks.c4
-rw-r--r--include/linux/usb/quirks.h11
3 files changed, 26 insertions, 0 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 1ab4df1de2da..b2a540b43f97 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -199,6 +199,17 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
199 if (n == 0) 199 if (n == 0)
200 n = 9; /* 32 ms = 2^(9-1) uframes */ 200 n = 9; /* 32 ms = 2^(9-1) uframes */
201 j = 16; 201 j = 16;
202
203 /*
204 * Adjust bInterval for quirked devices.
205 * This quirk fixes bIntervals reported in
206 * linear microframes.
207 */
208 if (to_usb_device(ddev)->quirks &
209 USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) {
210 n = clamp(fls(d->bInterval), i, j);
211 i = j = n;
212 }
202 break; 213 break;
203 default: /* USB_SPEED_FULL or _LOW */ 214 default: /* USB_SPEED_FULL or _LOW */
204 /* For low-speed, 10 ms is the official minimum. 215 /* For low-speed, 10 ms is the official minimum.
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 2c9ba4077075..bae636e2a1a3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -145,6 +145,10 @@ static const struct usb_device_id usb_quirk_list[] = {
145 /* SKYMEDI USB_DRIVE */ 145 /* SKYMEDI USB_DRIVE */
146 { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, 146 { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME },
147 147
148 /* Razer - Razer Blade Keyboard */
149 { USB_DEVICE(0x1532, 0x0116), .driver_info =
150 USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
151
148 /* BUILDWIN Photo Frame */ 152 /* BUILDWIN Photo Frame */
149 { USB_DEVICE(0x1908, 0x1315), .driver_info = 153 { USB_DEVICE(0x1908, 0x1315), .driver_info =
150 USB_QUIRK_HONOR_BNUMINTERFACES }, 154 USB_QUIRK_HONOR_BNUMINTERFACES },
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 52f944dfe2fd..55a17b188daa 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,15 @@
30 descriptor */ 30 descriptor */
31#define USB_QUIRK_DELAY_INIT 0x00000040 31#define USB_QUIRK_DELAY_INIT 0x00000040
32 32
33/*
34 * For high speed and super speed interupt endpoints, the USB 2.0 and
35 * USB 3.0 spec require the interval in microframes
36 * (1 microframe = 125 microseconds) to be calculated as
37 * interval = 2 ^ (bInterval-1).
38 *
39 * Devices with this quirk report their bInterval as the result of this
40 * calculation instead of the exponent variable used in the calculation.
41 */
42#define USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL 0x00000080
43
33#endif /* __LINUX_USB_QUIRKS_H */ 44#endif /* __LINUX_USB_QUIRKS_H */