[PATCH v3] usb-core bInterval quirk

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds a usb quirk to support devices with 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+).
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@xxxxxxxxx>
---
 drivers/usb/core/config.c  | 9 +++++++++
 drivers/usb/core/quirks.c  | 4 ++++
 include/linux/usb/quirks.h | 9 +++++++++
 3 files changed, 22 insertions(+)

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 1ab4df1..191ce69 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -199,6 +199,15 @@ 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.
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 739ee8e..33c42de 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[] = {
 	/* 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 },
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index 52f944d..9219995 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,13 @@
    descriptor */
 #define USB_QUIRK_DELAY_INIT		0x00000040
 
+/* 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 */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux