aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f17e5c8c1cb3..b3d27e6467ea 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1081,12 +1081,14 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
1081 unsigned int stream_id; 1081 unsigned int stream_id;
1082 struct xhci_ring *ep_ring; 1082 struct xhci_ring *ep_ring;
1083 struct xhci_virt_device *dev; 1083 struct xhci_virt_device *dev;
1084 struct xhci_virt_ep *ep;
1084 struct xhci_ep_ctx *ep_ctx; 1085 struct xhci_ep_ctx *ep_ctx;
1085 struct xhci_slot_ctx *slot_ctx; 1086 struct xhci_slot_ctx *slot_ctx;
1086 1087
1087 ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3])); 1088 ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));
1088 stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2])); 1089 stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));
1089 dev = xhci->devs[slot_id]; 1090 dev = xhci->devs[slot_id];
1091 ep = &dev->eps[ep_index];
1090 1092
1091 ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id); 1093 ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id);
1092 if (!ep_ring) { 1094 if (!ep_ring) {
@@ -1134,12 +1136,19 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
1134 * cancelling URBs, which might not be an error... 1136 * cancelling URBs, which might not be an error...
1135 */ 1137 */
1136 } else { 1138 } else {
1139 u64 deq;
1140 /* 4.6.10 deq ptr is written to the stream ctx for streams */
1141 if (ep->ep_state & EP_HAS_STREAMS) {
1142 struct xhci_stream_ctx *ctx =
1143 &ep->stream_info->stream_ctx_array[stream_id];
1144 deq = le64_to_cpu(ctx->stream_ring) & SCTX_DEQ_MASK;
1145 } else {
1146 deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
1147 }
1137 xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, 1148 xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
1138 "Successful Set TR Deq Ptr cmd, deq = @%08llx", 1149 "Successful Set TR Deq Ptr cmd, deq = @%08llx", deq);
1139 le64_to_cpu(ep_ctx->deq)); 1150 if (xhci_trb_virt_to_dma(ep->queued_deq_seg,
1140 if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, 1151 ep->queued_deq_ptr) == deq) {
1141 dev->eps[ep_index].queued_deq_ptr) ==
1142 (le64_to_cpu(ep_ctx->deq) & ~(EP_CTX_CYCLE_MASK))) {
1143 /* Update the ring's dequeue segment and dequeue pointer 1152 /* Update the ring's dequeue segment and dequeue pointer
1144 * to reflect the new position. 1153 * to reflect the new position.
1145 */ 1154 */
@@ -1148,8 +1157,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
1148 } else { 1157 } else {
1149 xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n"); 1158 xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n");
1150 xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", 1159 xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n",
1151 dev->eps[ep_index].queued_deq_seg, 1160 ep->queued_deq_seg, ep->queued_deq_ptr);
1152 dev->eps[ep_index].queued_deq_ptr);
1153 } 1161 }
1154 } 1162 }
1155 1163