aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/xhci-ring.c29
-rw-r--r--drivers/usb/host/xhci.h9
2 files changed, 35 insertions, 3 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bd0f2343ef9c..3577cd663ebc 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -501,9 +501,6 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
501 addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr); 501 addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr);
502 xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n", 502 xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n",
503 (unsigned long long) addr); 503 (unsigned long long) addr);
504 xhci_dbg(xhci, "Setting dequeue pointer in internal ring state.\n");
505 ep_ring->dequeue = state->new_deq_ptr;
506 ep_ring->deq_seg = state->new_deq_seg;
507} 504}
508 505
509static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, 506static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
@@ -945,9 +942,26 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
945 } else { 942 } else {
946 xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n", 943 xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n",
947 ep_ctx->deq); 944 ep_ctx->deq);
945 if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg,
946 dev->eps[ep_index].queued_deq_ptr) ==
947 (ep_ctx->deq & ~(EP_CTX_CYCLE_MASK))) {
948 /* Update the ring's dequeue segment and dequeue pointer
949 * to reflect the new position.
950 */
951 ep_ring->deq_seg = dev->eps[ep_index].queued_deq_seg;
952 ep_ring->dequeue = dev->eps[ep_index].queued_deq_ptr;
953 } else {
954 xhci_warn(xhci, "Mismatch between completed Set TR Deq "
955 "Ptr command & xHCI internal state.\n");
956 xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n",
957 dev->eps[ep_index].queued_deq_seg,
958 dev->eps[ep_index].queued_deq_ptr);
959 }
948 } 960 }
949 961
950 dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; 962 dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING;
963 dev->eps[ep_index].queued_deq_seg = NULL;
964 dev->eps[ep_index].queued_deq_ptr = NULL;
951 /* Restart any rings with pending URBs */ 965 /* Restart any rings with pending URBs */
952 ring_doorbell_for_active_rings(xhci, slot_id, ep_index); 966 ring_doorbell_for_active_rings(xhci, slot_id, ep_index);
953} 967}
@@ -3283,6 +3297,7 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
3283 u32 trb_ep_index = EP_ID_FOR_TRB(ep_index); 3297 u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);
3284 u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); 3298 u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id);
3285 u32 type = TRB_TYPE(TRB_SET_DEQ); 3299 u32 type = TRB_TYPE(TRB_SET_DEQ);
3300 struct xhci_virt_ep *ep;
3286 3301
3287 addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr); 3302 addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr);
3288 if (addr == 0) { 3303 if (addr == 0) {
@@ -3291,6 +3306,14 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
3291 deq_seg, deq_ptr); 3306 deq_seg, deq_ptr);
3292 return 0; 3307 return 0;
3293 } 3308 }
3309 ep = &xhci->devs[slot_id]->eps[ep_index];
3310 if ((ep->ep_state & SET_DEQ_PENDING)) {
3311 xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
3312 xhci_warn(xhci, "A Set TR Deq Ptr command is pending.\n");
3313 return 0;
3314 }
3315 ep->queued_deq_seg = deq_seg;
3316 ep->queued_deq_ptr = deq_ptr;
3294 return queue_command(xhci, lower_32_bits(addr) | cycle_state, 3317 return queue_command(xhci, lower_32_bits(addr) | cycle_state,
3295 upper_32_bits(addr), trb_stream_id, 3318 upper_32_bits(addr), trb_stream_id,
3296 trb_slot_id | trb_ep_index | type, false); 3319 trb_slot_id | trb_ep_index | type, false);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e69f1cdf4b5b..7aca6b16e986 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -644,6 +644,9 @@ struct xhci_ep_ctx {
644#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) 644#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
645#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) 645#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
646 646
647/* deq bitmasks */
648#define EP_CTX_CYCLE_MASK (1 << 0)
649
647 650
648/** 651/**
649 * struct xhci_input_control_context 652 * struct xhci_input_control_context
@@ -746,6 +749,12 @@ struct xhci_virt_ep {
746 struct timer_list stop_cmd_timer; 749 struct timer_list stop_cmd_timer;
747 int stop_cmds_pending; 750 int stop_cmds_pending;
748 struct xhci_hcd *xhci; 751 struct xhci_hcd *xhci;
752 /* Dequeue pointer and dequeue segment for a submitted Set TR Dequeue
753 * command. We'll need to update the ring's dequeue segment and dequeue
754 * pointer after the command completes.
755 */
756 struct xhci_segment *queued_deq_seg;
757 union xhci_trb *queued_deq_ptr;
749 /* 758 /*
750 * Sometimes the xHC can not process isochronous endpoint ring quickly 759 * Sometimes the xHC can not process isochronous endpoint ring quickly
751 * enough, and it will miss some isoc tds on the ring and generate 760 * enough, and it will miss some isoc tds on the ring and generate