Commit 3243367b authored by Samuel Thibault's avatar Samuel Thibault Committed by Greg Kroah-Hartman

usb-core: Add LINEAR_FRAME_INTR_BINTERVAL USB quirk

Some USB 2.0 devices erroneously report millisecond values in
bInterval. The generic config code manages to catch most of them,
but in some cases it's not completely enough.

The case at stake here is a USB 2.0 braille device, which wants to
announce 10ms and thus sets bInterval to 10, but with the USB 2.0
computation that yields to 64ms.  It happens that one can type fast
enough to reach this interval and get the device buffers overflown,
leading to problematic latencies.  The generic config code does not
catch this case because the 64ms is considered a sane enough value.

This change thus adds a USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL quirk
to mark devices which actually report milliseconds in bInterval,
and marks Vario Ultra devices as needing it.
Signed-off-by: default avatarSamuel Thibault <samuel.thibault@ens-lyon.org>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4ce36271
...@@ -280,6 +280,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum, ...@@ -280,6 +280,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
/* /*
* Adjust bInterval for quirked devices. * Adjust bInterval for quirked devices.
*/
/*
* This quirk fixes bIntervals reported in ms.
*/
if (to_usb_device(ddev)->quirks &
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
n = clamp(fls(d->bInterval) + 3, i, j);
i = j = n;
}
/*
* This quirk fixes bIntervals reported in * This quirk fixes bIntervals reported in
* linear microframes. * linear microframes.
*/ */
......
...@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -170,6 +170,14 @@ static const struct usb_device_id usb_quirk_list[] = {
/* M-Systems Flash Disk Pioneers */ /* M-Systems Flash Disk Pioneers */
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
/* Baum Vario Ultra */
{ USB_DEVICE(0x0904, 0x6101), .driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
{ USB_DEVICE(0x0904, 0x6102), .driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
{ USB_DEVICE(0x0904, 0x6103), .driver_info =
USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
/* Keytouch QWERTY Panel keyboard */ /* Keytouch QWERTY Panel keyboard */
{ USB_DEVICE(0x0926, 0x3333), .driver_info = { USB_DEVICE(0x0926, 0x3333), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS }, USB_QUIRK_CONFIG_INTF_STRINGS },
......
...@@ -50,4 +50,10 @@ ...@@ -50,4 +50,10 @@
/* device can't handle Link Power Management */ /* device can't handle Link Power Management */
#define USB_QUIRK_NO_LPM BIT(10) #define USB_QUIRK_NO_LPM BIT(10)
/*
* Device reports its bInterval as linear frames instead of the
* USB 2.0 calculation.
*/
#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
#endif /* __LINUX_USB_QUIRKS_H */ #endif /* __LINUX_USB_QUIRKS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment