diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c831194b0966..35374ddc31c1 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -469,7 +469,6 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, | |||
469 | * ring running. | 469 | * ring running. |
470 | */ | 470 | */ |
471 | ep_ring->state |= SET_DEQ_PENDING; | 471 | ep_ring->state |= SET_DEQ_PENDING; |
472 | xhci_ring_cmd_db(xhci); | ||
473 | } | 472 | } |
474 | 473 | ||
475 | /* | 474 | /* |
@@ -538,6 +537,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci, | |||
538 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { | 537 | if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { |
539 | xhci_queue_new_dequeue_state(xhci, ep_ring, | 538 | xhci_queue_new_dequeue_state(xhci, ep_ring, |
540 | slot_id, ep_index, &deq_state); | 539 | slot_id, ep_index, &deq_state); |
540 | xhci_ring_cmd_db(xhci); | ||
541 | } else { | 541 | } else { |
542 | /* Otherwise just ring the doorbell to restart the ring */ | 542 | /* Otherwise just ring the doorbell to restart the ring */ |
543 | ring_ep_doorbell(xhci, slot_id, ep_index); | 543 | ring_ep_doorbell(xhci, slot_id, ep_index); |
@@ -651,18 +651,31 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci, | |||
651 | { | 651 | { |
652 | int slot_id; | 652 | int slot_id; |
653 | unsigned int ep_index; | 653 | unsigned int ep_index; |
654 | struct xhci_ring *ep_ring; | ||
654 | 655 | ||
655 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); | 656 | slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]); |
656 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); | 657 | ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]); |
658 | ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; | ||
657 | /* This command will only fail if the endpoint wasn't halted, | 659 | /* This command will only fail if the endpoint wasn't halted, |
658 | * but we don't care. | 660 | * but we don't care. |
659 | */ | 661 | */ |
660 | xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n", | 662 | xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n", |
661 | (unsigned int) GET_COMP_CODE(event->status)); | 663 | (unsigned int) GET_COMP_CODE(event->status)); |
662 | 664 | ||
663 | /* Clear our internal halted state and restart the ring */ | 665 | /* HW with the reset endpoint quirk needs to have a configure endpoint |
664 | xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED; | 666 | * command complete before the endpoint can be used. Queue that here |
665 | ring_ep_doorbell(xhci, slot_id, ep_index); | 667 | * because the HW can't handle two commands being queued in a row. |
668 | */ | ||
669 | if (xhci->quirks & XHCI_RESET_EP_QUIRK) { | ||
670 | xhci_dbg(xhci, "Queueing configure endpoint command\n"); | ||
671 | xhci_queue_configure_endpoint(xhci, | ||
672 | xhci->devs[slot_id]->in_ctx->dma, slot_id); | ||
673 | xhci_ring_cmd_db(xhci); | ||
674 | } else { | ||
675 | /* Clear our internal halted state and restart the ring */ | ||
676 | ep_ring->state &= ~EP_HALTED; | ||
677 | ring_ep_doorbell(xhci, slot_id, ep_index); | ||
678 | } | ||
666 | } | 679 | } |
667 | 680 | ||
668 | static void handle_cmd_completion(struct xhci_hcd *xhci, | 681 | static void handle_cmd_completion(struct xhci_hcd *xhci, |
@@ -671,6 +684,10 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
671 | int slot_id = TRB_TO_SLOT_ID(event->flags); | 684 | int slot_id = TRB_TO_SLOT_ID(event->flags); |
672 | u64 cmd_dma; | 685 | u64 cmd_dma; |
673 | dma_addr_t cmd_dequeue_dma; | 686 | dma_addr_t cmd_dequeue_dma; |
687 | struct xhci_input_control_ctx *ctrl_ctx; | ||
688 | unsigned int ep_index; | ||
689 | struct xhci_ring *ep_ring; | ||
690 | unsigned int ep_state; | ||
674 | 691 | ||
675 | cmd_dma = event->cmd_trb; | 692 | cmd_dma = event->cmd_trb; |
676 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | 693 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
@@ -698,8 +715,39 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, | |||
698 | xhci_free_virt_device(xhci, slot_id); | 715 | xhci_free_virt_device(xhci, slot_id); |
699 | break; | 716 | break; |
700 | case TRB_TYPE(TRB_CONFIG_EP): | 717 | case TRB_TYPE(TRB_CONFIG_EP): |
701 | xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); | 718 | /* |
702 | complete(&xhci->devs[slot_id]->cmd_completion); | 719 | * Configure endpoint commands can come from the USB core |
720 | * configuration or alt setting changes, or because the HW | ||
721 | * needed an extra configure endpoint command after a reset | ||
722 | * endpoint command. In the latter case, the xHCI driver is | ||
723 | * not waiting on the configure endpoint command. | ||
724 | */ | ||
725 | ctrl_ctx = xhci_get_input_control_ctx(xhci, | ||
726 | xhci->devs[slot_id]->in_ctx); | ||
727 | /* Input ctx add_flags are the endpoint index plus one */ | ||
728 | ep_index = xhci_last_valid_endpoint(ctrl_ctx->add_flags) - 1; | ||
729 | ep_ring = xhci->devs[slot_id]->ep_rings[ep_index]; | ||
730 | if (!ep_ring) { | ||
731 | /* This must have been an initial configure endpoint */ | ||
732 | xhci->devs[slot_id]->cmd_status = | ||
733 | GET_COMP_CODE(event->status); | ||
734 | complete(&xhci->devs[slot_id]->cmd_completion); | ||
735 | break; | ||
736 | } | ||
737 | ep_state = ep_ring->state; | ||
738 | xhci_dbg(xhci, "Completed config ep cmd - last ep index = %d, " | ||
739 | "state = %d\n", ep_index, ep_state); | ||
740 | if (xhci->quirks & XHCI_RESET_EP_QUIRK && | ||
741 | ep_state & EP_HALTED) { | ||
742 | /* Clear our internal halted state and restart ring */ | ||
743 | xhci->devs[slot_id]->ep_rings[ep_index]->state &= | ||
744 | ~EP_HALTED; | ||
745 | ring_ep_doorbell(xhci, slot_id, ep_index); | ||
746 | } else { | ||
747 | xhci->devs[slot_id]->cmd_status = | ||
748 | GET_COMP_CODE(event->status); | ||
749 | complete(&xhci->devs[slot_id]->cmd_completion); | ||
750 | } | ||
703 | break; | 751 | break; |
704 | case TRB_TYPE(TRB_EVAL_CONTEXT): | 752 | case TRB_TYPE(TRB_EVAL_CONTEXT): |
705 | xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); | 753 | xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); |
@@ -958,7 +1006,6 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
958 | xhci_queue_reset_ep(xhci, slot_id, ep_index); | 1006 | xhci_queue_reset_ep(xhci, slot_id, ep_index); |
959 | xhci_cleanup_stalled_ring(xhci, | 1007 | xhci_cleanup_stalled_ring(xhci, |
960 | td->urb->dev, | 1008 | td->urb->dev, |
961 | td->urb->ep, | ||
962 | ep_index, ep_ring); | 1009 | ep_index, ep_ring); |
963 | xhci_ring_cmd_db(xhci); | 1010 | xhci_ring_cmd_db(xhci); |
964 | goto td_cleanup; | 1011 | goto td_cleanup; |