USB: add quirk for devices with broken LPM
authorAlan Stern <stern@rowland.harvard.edu>
Thu, 10 Dec 2015 20:27:21 +0000 (15:27 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Jan 2016 03:47:54 +0000 (19:47 -0800)
commit ad87e03213b552a5c33d5e1e7a19a73768397010 upstream.

Some USB device / host controller combinations seem to have problems
with Link Power Management.  For example, Steinar found that his xHCI
controller wouldn't handle bandwidth calculations correctly for two
video cards simultaneously when LPM was enabled, even though the bus
had plenty of bandwidth available.

This patch introduces a new quirk flag for devices that should remain
disabled for LPM, and creates quirk entries for Steinar's devices.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/core/hub.c
drivers/usb/core/quirks.c
include/linux/usb/quirks.h

index 11a073cda1d622518c4b0069422d3c69a5d99d93..92873f2773fc6ff62a8744f538a1bc681b466b21 100644 (file)
@@ -137,6 +137,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device *hdev)
 
 static int usb_device_supports_lpm(struct usb_device *udev)
 {
+       /* Some devices have trouble with LPM */
+       if (udev->quirks & USB_QUIRK_NO_LPM)
+               return 0;
+
        /* USB 2.1 (and greater) devices indicate LPM support through
         * their USB 2.0 Extended Capabilities BOS descriptor.
         */
@@ -4289,6 +4293,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
                goto fail;
        }
 
+       usb_detect_quirks(udev);
+
        if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
                retval = usb_get_bos_descriptor(udev);
                if (!retval) {
@@ -4530,7 +4536,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                if (status < 0)
                        goto loop;
 
-               usb_detect_quirks(udev);
                if (udev->quirks & USB_QUIRK_DELAY_INIT)
                        msleep(1000);
 
index d4db4ea4a92d904c864cbd8f440e0bf173fc0a18..94e9cddc05c17686d51a2b720cb3e0ff64fb9a30 100644 (file)
@@ -182,6 +182,12 @@ static const struct usb_device_id usb_interface_quirk_list[] = {
        { USB_DEVICE(0x0b05, 0x17e0), .driver_info =
                        USB_QUIRK_IGNORE_REMOTE_WAKEUP },
 
+       /* Blackmagic Design Intensity Shuttle */
+       { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
+
+       /* Blackmagic Design UltraStudio SDI */
+       { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+
        { }  /* terminating entry must be last */
 };
 
index 49587dc22f5d055a782a8a947e76a8535a953dcb..41ea53c39389c689c6d3c7fc843bb65927bb5754 100644 (file)
@@ -33,4 +33,7 @@
 /* device generates spurious wakeup, ignore remote wakeup capability */
 #define USB_QUIRK_IGNORE_REMOTE_WAKEUP 0x00000200
 
+/* device can't handle Link Power Management */
+#define USB_QUIRK_NO_LPM                       BIT(10)
+
 #endif /* __LINUX_USB_QUIRKS_H */