diff options
-rw-r--r-- | drivers/usb/core/hub.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 47 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 37 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 25 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 11 |
6 files changed, 92 insertions, 33 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index dde4c83516a1..e6b682c6c236 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -3426,6 +3426,9 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) | |||
3426 | unsigned long long u2_pel; | 3426 | unsigned long long u2_pel; |
3427 | int ret; | 3427 | int ret; |
3428 | 3428 | ||
3429 | if (udev->state != USB_STATE_CONFIGURED) | ||
3430 | return 0; | ||
3431 | |||
3429 | /* Convert SEL and PEL stored in ns to us */ | 3432 | /* Convert SEL and PEL stored in ns to us */ |
3430 | u1_sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); | 3433 | u1_sel = DIV_ROUND_UP(udev->u1_params.sel, 1000); |
3431 | u1_pel = DIV_ROUND_UP(udev->u1_params.pel, 1000); | 3434 | u1_pel = DIV_ROUND_UP(udev->u1_params.pel, 1000); |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index fae697ed0b70..773a6b28c4f1 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -287,7 +287,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend) | |||
287 | if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) | 287 | if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) |
288 | xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); | 288 | xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); |
289 | } | 289 | } |
290 | cmd->command_trb = xhci->cmd_ring->enqueue; | 290 | cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
291 | list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); | 291 | list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); |
292 | xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); | 292 | xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); |
293 | xhci_ring_cmd_db(xhci); | 293 | xhci_ring_cmd_db(xhci); |
@@ -552,11 +552,15 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) | |||
552 | * - Mark a port as being done with device resume, | 552 | * - Mark a port as being done with device resume, |
553 | * and ring the endpoint doorbells. | 553 | * and ring the endpoint doorbells. |
554 | * - Stop the Synopsys redriver Compliance Mode polling. | 554 | * - Stop the Synopsys redriver Compliance Mode polling. |
555 | * - Drop and reacquire the xHCI lock, in order to wait for port resume. | ||
555 | */ | 556 | */ |
556 | static u32 xhci_get_port_status(struct usb_hcd *hcd, | 557 | static u32 xhci_get_port_status(struct usb_hcd *hcd, |
557 | struct xhci_bus_state *bus_state, | 558 | struct xhci_bus_state *bus_state, |
558 | __le32 __iomem **port_array, | 559 | __le32 __iomem **port_array, |
559 | u16 wIndex, u32 raw_port_status) | 560 | u16 wIndex, u32 raw_port_status, |
561 | unsigned long flags) | ||
562 | __releases(&xhci->lock) | ||
563 | __acquires(&xhci->lock) | ||
560 | { | 564 | { |
561 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 565 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
562 | u32 status = 0; | 566 | u32 status = 0; |
@@ -591,21 +595,42 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd, | |||
591 | return 0xffffffff; | 595 | return 0xffffffff; |
592 | if (time_after_eq(jiffies, | 596 | if (time_after_eq(jiffies, |
593 | bus_state->resume_done[wIndex])) { | 597 | bus_state->resume_done[wIndex])) { |
598 | int time_left; | ||
599 | |||
594 | xhci_dbg(xhci, "Resume USB2 port %d\n", | 600 | xhci_dbg(xhci, "Resume USB2 port %d\n", |
595 | wIndex + 1); | 601 | wIndex + 1); |
596 | bus_state->resume_done[wIndex] = 0; | 602 | bus_state->resume_done[wIndex] = 0; |
597 | clear_bit(wIndex, &bus_state->resuming_ports); | 603 | clear_bit(wIndex, &bus_state->resuming_ports); |
604 | |||
605 | set_bit(wIndex, &bus_state->rexit_ports); | ||
598 | xhci_set_link_state(xhci, port_array, wIndex, | 606 | xhci_set_link_state(xhci, port_array, wIndex, |
599 | XDEV_U0); | 607 | XDEV_U0); |
600 | xhci_dbg(xhci, "set port %d resume\n", | 608 | |
601 | wIndex + 1); | 609 | spin_unlock_irqrestore(&xhci->lock, flags); |
602 | slot_id = xhci_find_slot_id_by_port(hcd, xhci, | 610 | time_left = wait_for_completion_timeout( |
603 | wIndex + 1); | 611 | &bus_state->rexit_done[wIndex], |
604 | if (!slot_id) { | 612 | msecs_to_jiffies( |
605 | xhci_dbg(xhci, "slot_id is zero\n"); | 613 | XHCI_MAX_REXIT_TIMEOUT)); |
606 | return 0xffffffff; | 614 | spin_lock_irqsave(&xhci->lock, flags); |
615 | |||
616 | if (time_left) { | ||
617 | slot_id = xhci_find_slot_id_by_port(hcd, | ||
618 | xhci, wIndex + 1); | ||
619 | if (!slot_id) { | ||
620 | xhci_dbg(xhci, "slot_id is zero\n"); | ||
621 | return 0xffffffff; | ||
622 | } | ||
623 | xhci_ring_device(xhci, slot_id); | ||
624 | } else { | ||
625 | int port_status = xhci_readl(xhci, | ||
626 | port_array[wIndex]); | ||
627 | xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", | ||
628 | XHCI_MAX_REXIT_TIMEOUT, | ||
629 | port_status); | ||
630 | status |= USB_PORT_STAT_SUSPEND; | ||
631 | clear_bit(wIndex, &bus_state->rexit_ports); | ||
607 | } | 632 | } |
608 | xhci_ring_device(xhci, slot_id); | 633 | |
609 | bus_state->port_c_suspend |= 1 << wIndex; | 634 | bus_state->port_c_suspend |= 1 << wIndex; |
610 | bus_state->suspended_ports &= ~(1 << wIndex); | 635 | bus_state->suspended_ports &= ~(1 << wIndex); |
611 | } else { | 636 | } else { |
@@ -728,7 +753,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
728 | break; | 753 | break; |
729 | } | 754 | } |
730 | status = xhci_get_port_status(hcd, bus_state, port_array, | 755 | status = xhci_get_port_status(hcd, bus_state, port_array, |
731 | wIndex, temp); | 756 | wIndex, temp, flags); |
732 | if (status == 0xffffffff) | 757 | if (status == 0xffffffff) |
733 | goto error; | 758 | goto error; |
734 | 759 | ||
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 53b972c2a09f..83bcd13622c3 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -2428,6 +2428,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
2428 | for (i = 0; i < USB_MAXCHILDREN; ++i) { | 2428 | for (i = 0; i < USB_MAXCHILDREN; ++i) { |
2429 | xhci->bus_state[0].resume_done[i] = 0; | 2429 | xhci->bus_state[0].resume_done[i] = 0; |
2430 | xhci->bus_state[1].resume_done[i] = 0; | 2430 | xhci->bus_state[1].resume_done[i] = 0; |
2431 | /* Only the USB 2.0 completions will ever be used. */ | ||
2432 | init_completion(&xhci->bus_state[1].rexit_done[i]); | ||
2431 | } | 2433 | } |
2432 | 2434 | ||
2433 | if (scratchpad_alloc(xhci, flags)) | 2435 | if (scratchpad_alloc(xhci, flags)) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 411da1fc7ae8..6bfbd80ec2b9 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -123,6 +123,16 @@ static int enqueue_is_link_trb(struct xhci_ring *ring) | |||
123 | return TRB_TYPE_LINK_LE32(link->control); | 123 | return TRB_TYPE_LINK_LE32(link->control); |
124 | } | 124 | } |
125 | 125 | ||
126 | union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring) | ||
127 | { | ||
128 | /* Enqueue pointer can be left pointing to the link TRB, | ||
129 | * we must handle that | ||
130 | */ | ||
131 | if (TRB_TYPE_LINK_LE32(ring->enqueue->link.control)) | ||
132 | return ring->enq_seg->next->trbs; | ||
133 | return ring->enqueue; | ||
134 | } | ||
135 | |||
126 | /* Updates trb to point to the next TRB in the ring, and updates seg if the next | 136 | /* Updates trb to point to the next TRB in the ring, and updates seg if the next |
127 | * TRB is in a new segment. This does not skip over link TRBs, and it does not | 137 | * TRB is in a new segment. This does not skip over link TRBs, and it does not |
128 | * effect the ring dequeue or enqueue pointers. | 138 | * effect the ring dequeue or enqueue pointers. |
@@ -859,8 +869,12 @@ remove_finished_td: | |||
859 | /* Otherwise ring the doorbell(s) to restart queued transfers */ | 869 | /* Otherwise ring the doorbell(s) to restart queued transfers */ |
860 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); | 870 | ring_doorbell_for_active_rings(xhci, slot_id, ep_index); |
861 | } | 871 | } |
862 | ep->stopped_td = NULL; | 872 | |
863 | ep->stopped_trb = NULL; | 873 | /* Clear stopped_td and stopped_trb if endpoint is not halted */ |
874 | if (!(ep->ep_state & EP_HALTED)) { | ||
875 | ep->stopped_td = NULL; | ||
876 | ep->stopped_trb = NULL; | ||
877 | } | ||
864 | 878 | ||
865 | /* | 879 | /* |
866 | * Drop the lock and complete the URBs in the cancelled TD list. | 880 | * Drop the lock and complete the URBs in the cancelled TD list. |
@@ -1414,6 +1428,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
1414 | inc_deq(xhci, xhci->cmd_ring); | 1428 | inc_deq(xhci, xhci->cmd_ring); |
1415 | return; | 1429 | return; |
1416 | } | 1430 | } |
1431 | /* There is no command to handle if we get a stop event when the | ||
1432 | * command ring is empty, event->cmd_trb points to the next | ||
1433 | * unset command | ||
1434 | */ | ||
1435 | if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) | ||
1436 | return; | ||
1417 | } | 1437 | } |
1418 | 1438 | ||
1419 | switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) | 1439 | switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) |
@@ -1743,6 +1763,19 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1743 | } | 1763 | } |
1744 | } | 1764 | } |
1745 | 1765 | ||
1766 | /* | ||
1767 | * Check to see if xhci-hub.c is waiting on RExit to U0 transition (or | ||
1768 | * RExit to a disconnect state). If so, let the the driver know it's | ||
1769 | * out of the RExit state. | ||
1770 | */ | ||
1771 | if (!DEV_SUPERSPEED(temp) && | ||
1772 | test_and_clear_bit(faked_port_index, | ||
1773 | &bus_state->rexit_ports)) { | ||
1774 | complete(&bus_state->rexit_done[faked_port_index]); | ||
1775 | bogus_port_status = true; | ||
1776 | goto cleanup; | ||
1777 | } | ||
1778 | |||
1746 | if (hcd->speed != HCD_USB3) | 1779 | if (hcd->speed != HCD_USB3) |
1747 | xhci_test_and_clear_bit(xhci, port_array, faked_port_index, | 1780 | xhci_test_and_clear_bit(xhci, port_array, faked_port_index, |
1748 | PORT_PLC); | 1781 | PORT_PLC); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 49b6edb84a79..1e36dbb48366 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -2598,15 +2598,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2598 | if (command) { | 2598 | if (command) { |
2599 | cmd_completion = command->completion; | 2599 | cmd_completion = command->completion; |
2600 | cmd_status = &command->status; | 2600 | cmd_status = &command->status; |
2601 | command->command_trb = xhci->cmd_ring->enqueue; | 2601 | command->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
2602 | |||
2603 | /* Enqueue pointer can be left pointing to the link TRB, | ||
2604 | * we must handle that | ||
2605 | */ | ||
2606 | if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) | ||
2607 | command->command_trb = | ||
2608 | xhci->cmd_ring->enq_seg->next->trbs; | ||
2609 | |||
2610 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); | 2602 | list_add_tail(&command->cmd_list, &virt_dev->cmd_list); |
2611 | } else { | 2603 | } else { |
2612 | cmd_completion = &virt_dev->cmd_completion; | 2604 | cmd_completion = &virt_dev->cmd_completion; |
@@ -2614,7 +2606,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci, | |||
2614 | } | 2606 | } |
2615 | init_completion(cmd_completion); | 2607 | init_completion(cmd_completion); |
2616 | 2608 | ||
2617 | cmd_trb = xhci->cmd_ring->dequeue; | 2609 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
2618 | if (!ctx_change) | 2610 | if (!ctx_change) |
2619 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, | 2611 | ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, |
2620 | udev->slot_id, must_succeed); | 2612 | udev->slot_id, must_succeed); |
@@ -3439,14 +3431,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3439 | 3431 | ||
3440 | /* Attempt to submit the Reset Device command to the command ring */ | 3432 | /* Attempt to submit the Reset Device command to the command ring */ |
3441 | spin_lock_irqsave(&xhci->lock, flags); | 3433 | spin_lock_irqsave(&xhci->lock, flags); |
3442 | reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; | 3434 | reset_device_cmd->command_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3443 | |||
3444 | /* Enqueue pointer can be left pointing to the link TRB, | ||
3445 | * we must handle that | ||
3446 | */ | ||
3447 | if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) | ||
3448 | reset_device_cmd->command_trb = | ||
3449 | xhci->cmd_ring->enq_seg->next->trbs; | ||
3450 | 3435 | ||
3451 | list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); | 3436 | list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); |
3452 | ret = xhci_queue_reset_device(xhci, slot_id); | 3437 | ret = xhci_queue_reset_device(xhci, slot_id); |
@@ -3650,7 +3635,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
3650 | union xhci_trb *cmd_trb; | 3635 | union xhci_trb *cmd_trb; |
3651 | 3636 | ||
3652 | spin_lock_irqsave(&xhci->lock, flags); | 3637 | spin_lock_irqsave(&xhci->lock, flags); |
3653 | cmd_trb = xhci->cmd_ring->dequeue; | 3638 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3654 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); | 3639 | ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); |
3655 | if (ret) { | 3640 | if (ret) { |
3656 | spin_unlock_irqrestore(&xhci->lock, flags); | 3641 | spin_unlock_irqrestore(&xhci->lock, flags); |
@@ -3785,7 +3770,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
3785 | slot_ctx->dev_info >> 27); | 3770 | slot_ctx->dev_info >> 27); |
3786 | 3771 | ||
3787 | spin_lock_irqsave(&xhci->lock, flags); | 3772 | spin_lock_irqsave(&xhci->lock, flags); |
3788 | cmd_trb = xhci->cmd_ring->dequeue; | 3773 | cmd_trb = xhci_find_next_enqueue(xhci->cmd_ring); |
3789 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, | 3774 | ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, |
3790 | udev->slot_id); | 3775 | udev->slot_id); |
3791 | if (ret) { | 3776 | if (ret) { |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 46aa14894148..289fbfbae746 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1412,8 +1412,18 @@ struct xhci_bus_state { | |||
1412 | unsigned long resume_done[USB_MAXCHILDREN]; | 1412 | unsigned long resume_done[USB_MAXCHILDREN]; |
1413 | /* which ports have started to resume */ | 1413 | /* which ports have started to resume */ |
1414 | unsigned long resuming_ports; | 1414 | unsigned long resuming_ports; |
1415 | /* Which ports are waiting on RExit to U0 transition. */ | ||
1416 | unsigned long rexit_ports; | ||
1417 | struct completion rexit_done[USB_MAXCHILDREN]; | ||
1415 | }; | 1418 | }; |
1416 | 1419 | ||
1420 | |||
1421 | /* | ||
1422 | * It can take up to 20 ms to transition from RExit to U0 on the | ||
1423 | * Intel Lynx Point LP xHCI host. | ||
1424 | */ | ||
1425 | #define XHCI_MAX_REXIT_TIMEOUT (20 * 1000) | ||
1426 | |||
1417 | static inline unsigned int hcd_index(struct usb_hcd *hcd) | 1427 | static inline unsigned int hcd_index(struct usb_hcd *hcd) |
1418 | { | 1428 | { |
1419 | if (hcd->speed == HCD_USB3) | 1429 | if (hcd->speed == HCD_USB3) |
@@ -1840,6 +1850,7 @@ int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, | |||
1840 | union xhci_trb *cmd_trb); | 1850 | union xhci_trb *cmd_trb); |
1841 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, | 1851 | void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id, |
1842 | unsigned int ep_index, unsigned int stream_id); | 1852 | unsigned int ep_index, unsigned int stream_id); |
1853 | union xhci_trb *xhci_find_next_enqueue(struct xhci_ring *ring); | ||
1843 | 1854 | ||
1844 | /* xHCI roothub code */ | 1855 | /* xHCI roothub code */ |
1845 | void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, | 1856 | void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array, |