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