Merge 4.5-rc4 into usb-next
[cascardo/linux.git] / drivers / usb / host / xhci.c
index 26a44c0..d51ee0c 100644 (file)
@@ -1554,7 +1554,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
                xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
                                "HW died, freeing TD.");
                urb_priv = urb->hcpriv;
-               for (i = urb_priv->td_cnt; i < urb_priv->length; i++) {
+               for (i = urb_priv->td_cnt;
+                    i < urb_priv->length && xhci->devs[urb->dev->slot_id];
+                    i++) {
                        td = urb_priv->td[i];
                        if (!list_empty(&td->td_list))
                                list_del_init(&td->td_list);
@@ -2084,6 +2086,7 @@ static unsigned int xhci_get_block_size(struct usb_device *udev)
        case USB_SPEED_HIGH:
                return HS_BLOCK;
        case USB_SPEED_SUPER:
+       case USB_SPEED_SUPER_PLUS:
                return SS_BLOCK;
        case USB_SPEED_UNKNOWN:
        case USB_SPEED_WIRELESS:
@@ -2209,7 +2212,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
        unsigned int packets_remaining = 0;
        unsigned int i;
 
-       if (virt_dev->udev->speed == USB_SPEED_SUPER)
+       if (virt_dev->udev->speed >= USB_SPEED_SUPER)
                return xhci_check_ss_bw(xhci, virt_dev);
 
        if (virt_dev->udev->speed == USB_SPEED_HIGH) {
@@ -2410,7 +2413,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
        if (xhci_is_async_ep(ep_bw->type))
                return;
 
-       if (udev->speed == USB_SPEED_SUPER) {
+       if (udev->speed >= USB_SPEED_SUPER) {
                if (xhci_is_sync_in_ep(ep_bw->type))
                        xhci->devs[udev->slot_id]->bw_table->ss_bw_in -=
                                xhci_get_ss_bw_consumed(ep_bw);
@@ -2448,6 +2451,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci,
                interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1;
                break;
        case USB_SPEED_SUPER:
+       case USB_SPEED_SUPER_PLUS:
        case USB_SPEED_UNKNOWN:
        case USB_SPEED_WIRELESS:
                /* Should never happen because only LS/FS/HS endpoints will get
@@ -2507,6 +2511,7 @@ static void xhci_add_ep_to_interval_table(struct xhci_hcd *xhci,
                interval_bw->overhead[HS_OVERHEAD_TYPE] += 1;
                break;
        case USB_SPEED_SUPER:
+       case USB_SPEED_SUPER_PLUS:
        case USB_SPEED_UNKNOWN:
        case USB_SPEED_WIRELESS:
                /* Should never happen because only LS/FS/HS endpoints will get
@@ -4895,6 +4900,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
                if (xhci->sbrn == 0x31) {
                        xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n");
                        hcd->speed = HCD_USB31;
+                       hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS;
                }
                /* xHCI private pointer was set in xhci_pci_probe for the second
                 * registered roothub.