[PATCH v3] usb-core bInterval quirk

2014-07-26 Thread James P Michels III
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.mich...@gmail.com
---
 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   0x0040
 
+/* 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 0x0080
+
 #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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4] usb-core bInterval quirk

2014-07-26 Thread James P Michels III
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.mich...@gmail.com
---
 drivers/usb/core/config.c  | 11 +++
 drivers/usb/core/quirks.c  |  4 
 include/linux/usb/quirks.h | 11 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 1ab4df1..db4029c 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,
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..55a17b1 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,15 @@
descriptor */
 #define USB_QUIRK_DELAY_INIT   0x0040
 
+/*
+ * 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 0x0080
+
 #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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] usb-core bInterval quirks

2014-07-22 Thread James P Michels III
This patch adds usb quirks to improve support for devices
 with non standard bInterval values. Quirks are added to support devices with
 bInterval values expressed as microframes or frames. The quirks cause the
 parse endpoint function to modify the reported bInterval to the standards
 conforming value.

There is currently code in the endpoint parser that checks for bIntervals that 
are outside
of the valid range (0-15 for USB 2+). In this case, the code assumes the 
bInterval is being
reported in 1ms frames. However, the correction is only applied if the original 
bInterval
value is out of the 0-15 range.

With one of these quirks applied to the device, the bInterval will be 
accurately adjusted
even when the misreported bInterval is in the 0-15 range.

Signed-off-by: James P Michels III james.p.mich...@gmail.com
---
 drivers/usb/core/config.c  | 20 
 drivers/usb/core/quirks.c  |  4 
 include/linux/usb/quirks.h | 13 +
 3 files changed, 37 insertions(+)

diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 1ab4df1..1b343fe 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -228,6 +228,26 @@ static int usb_parse_endpoint(struct device *ddev, int 
cfgno, int inum,
endpoint-desc.bInterval = n;
}
 
+   /* Adjust bInterval reported as frames for quirked devices */
+   if (to_usb_device(ddev)-quirks  USB_QUIRK_INTERVAL_AS_FRAMES) {
+   endpoint-desc.bInterval = fls(d-bInterval * 8);
+   if (endpoint-desc.bInterval  16)
+   endpoint-desc.bInterval = 16;
+   dev_warn(ddev, bInterval adjusted from %d to %d\n,
+   d-bInterval,
+   endpoint-desc.bInterval);
+   }
+
+   /* Adjust bInterval reported as microframes for quirked devices */
+   if (to_usb_device(ddev)-quirks  USB_QUIRK_INTERVAL_AS_MICROFRAMES) {
+   endpoint-desc.bInterval = fls(d-bInterval);
+   if (endpoint-desc.bInterval  16)
+   endpoint-desc.bInterval = 16;
+   dev_warn(ddev, bInterval adjusted from %d to %d\n,
+   d-bInterval,
+   endpoint-desc.bInterval);
+   }
+
/* Some buggy low-speed devices have Bulk endpoints, which is
 * explicitly forbidden by the USB spec.  In an attempt to make
 * them usable, we will try treating them as Interrupt endpoints.
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 739ee8e..29d2288 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_INTERVAL_AS_MICROFRAMES },
+
/* 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..cec4ac2 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -30,4 +30,17 @@
descriptor */
 #define USB_QUIRK_DELAY_INIT   0x0040
 
+/* 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_INTERVAL_AS_MICROFRAMES  0x0080
+
+/* Devices with this quirk report their bInterval as the number of
+   frames per interval (1 frame = 1 millisecond) */
+#define USB_QUIRK_INTERVAL_AS_FRAMES   0x0100
+
 #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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html