usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message
[pandora-kernel.git] / drivers / usb / core / config.c
index f4bdd0c..ffc6989 100644 (file)
@@ -114,16 +114,18 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                                cfgno, inum, asnum, ep->desc.bEndpointAddress);
                ep->ss_ep_comp.bmAttributes = 16;
        } else if (usb_endpoint_xfer_isoc(&ep->desc) &&
-                       desc->bmAttributes > 2) {
+                  USB_SS_MULT(desc->bmAttributes) > 3) {
                dev_warn(ddev, "Isoc endpoint has Mult of %d in "
                                "config %d interface %d altsetting %d ep %d: "
-                               "setting to 3\n", desc->bmAttributes + 1,
+                               "setting to 3\n",
+                               USB_SS_MULT(desc->bmAttributes),
                                cfgno, inum, asnum, ep->desc.bEndpointAddress);
                ep->ss_ep_comp.bmAttributes = 2;
        }
 
        if (usb_endpoint_xfer_isoc(&ep->desc))
-               max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) *
+               max_tx = (desc->bMaxBurst + 1) *
+                       (USB_SS_MULT(desc->bmAttributes)) *
                        usb_endpoint_maxp(&ep->desc);
        else if (usb_endpoint_xfer_int(&ep->desc))
                max_tx = usb_endpoint_maxp(&ep->desc) *
@@ -201,6 +203,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.
@@ -424,7 +437,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
 
        memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
        if (config->desc.bDescriptorType != USB_DT_CONFIG ||
-           config->desc.bLength < USB_DT_CONFIG_SIZE) {
+           config->desc.bLength < USB_DT_CONFIG_SIZE ||
+           config->desc.bLength > size) {
                dev_err(ddev, "invalid descriptor for config index %d: "
                    "type = 0x%X, length = %d\n", cfgidx,
                    config->desc.bDescriptorType, config->desc.bLength);
@@ -721,6 +735,10 @@ int usb_get_configuration(struct usb_device *dev)
                        result = -ENOMEM;
                        goto err;
                }
+
+               if (dev->quirks & USB_QUIRK_DELAY_INIT)
+                       msleep(100);
+
                result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno,
                    bigbuffer, length);
                if (result < 0) {