diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
| -rw-r--r-- | drivers/usb/host/xhci-ring.c | 22 |
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 | ||
