diff options
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2e346334a363..ee7bc7ecbc59 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
| @@ -903,28 +903,32 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
| 903 | virt_dev->in_ctx); | 903 | virt_dev->in_ctx); |
| 904 | /* Input ctx add_flags are the endpoint index plus one */ | 904 | /* Input ctx add_flags are the endpoint index plus one */ |
| 905 | ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1; | 905 | ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1; |
| 906 | ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; | 906 | /* A usb_set_interface() call directly after clearing a halted |
| 907 | if (!ep_ring) { | 907 | * condition may race on this quirky hardware. |
| 908 | /* This must have been an initial configure endpoint */ | 908 | * Not worth worrying about, since this is prototype hardware. |
| 909 | xhci->devs[slot_id]->cmd_status = | 909 | */ |
| 910 | GET_COMP_CODE(event->status); | ||
| 911 | complete(&xhci->devs[slot_id]->cmd_completion); | ||
| 912 | break; | ||
| 913 | } | ||
| 914 | ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state; | ||
| 915 | xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, " | ||
| 916 | "state = %d\n", ep_index, ep_state); | ||
| 917 | if (xhci->quirks & XHCI_RESET_EP_QUIRK && | 910 | if (xhci->quirks & XHCI_RESET_EP_QUIRK && |
| 918 | ep_state & EP_HALTED) { | 911 | ep_index != (unsigned int) -1 && |
| 912 | ctrl_ctx->add_flags - SLOT_FLAG == | ||
| 913 | ctrl_ctx->drop_flags) { | ||
| 914 | ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; | ||
| 915 | ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state; | ||
| 916 | if (!(ep_state & EP_HALTED)) | ||
| 917 | goto bandwidth_change; | ||
| 918 | xhci_dbg(xhci, "Completed config ep cmd - " | ||
| 919 | "last ep index = %d, state = %d\n", | ||
| 920 | ep_index, ep_state); | ||
| 919 | /* Clear our internal halted state and restart ring */ | 921 | /* Clear our internal halted state and restart ring */ |
| 920 | xhci->devs[slot_id]->eps[ep_index].ep_state &= | 922 | xhci->devs[slot_id]->eps[ep_index].ep_state &= |
| 921 | ~EP_HALTED; | 923 | ~EP_HALTED; |
| 922 | ring_ep_doorbell(xhci, slot_id, ep_index); | 924 | ring_ep_doorbell(xhci, slot_id, ep_index); |
| 923 | } else { | 925 | break; |
| 924 | xhci->devs[slot_id]->cmd_status = | ||
| 925 | GET_COMP_CODE(event->status); | ||
| 926 | complete(&xhci->devs[slot_id]->cmd_completion); | ||
| 927 | } | 926 | } |
| 927 | bandwidth_change: | ||
| 928 | xhci_dbg(xhci, "Completed config ep cmd\n"); | ||
| 929 | xhci->devs[slot_id]->cmd_status = | ||
| 930 | GET_COMP_CODE(event->status); | ||
| 931 | complete(&xhci->devs[slot_id]->cmd_completion); | ||
| 928 | break; | 932 | break; |
| 929 | case TRB_TYPE(TRB_EVAL_CONTEXT): | 933 | case TRB_TYPE(TRB_EVAL_CONTEXT): |
| 930 | virt_dev = xhci->devs[slot_id]; | 934 | virt_dev = xhci->devs[slot_id]; |
