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 04:34:52 +0000 (20:34 -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 1847a7d380268febd97cf26640b215d8d61b0d99..fa114bcedabff48b51669fe7ddec40f94e27e396 100644 (file)
@@ -130,6 +130,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.
         */
@@ -4350,6 +4354,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) {
@@ -4595,7 +4601,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 804acc7003277faad974b713148a4c4c64c72f01..00addda9ad53e56e456926468d66934ab0182532 100644 (file)
@@ -205,6 +205,12 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
        /* Logitech Optical Mouse M90/M100 */
        { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* 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 8b96ae2a38fe1a57b6b639267305b2629d6ac180..5ef39160bd4763443c024f43aa11ca68ffc706fb 100644 (file)
@@ -36,4 +36,7 @@
 /* device can't handle device_qualifier descriptor requests */
 #define USB_QUIRK_DEVICE_QUALIFIER     0x00000100
 
+/* device can't handle Link Power Management */
+#define USB_QUIRK_NO_LPM                       BIT(10)
+
 #endif /* __LINUX_USB_QUIRKS_H */