Skip to content

Commit 931e468

Browse files
Epicuriusgregkh
authored andcommitted
usb: xhci: improve TR Dequeue Pointer mask
Address the naming and usage of the TR Dequeue Pointer mask in the xhci driver. The Endpoint Context Field at offset 0x08 is defined as follows: Bit 0 Dequeue Cycle State (DCS) Bits 3:1 RsvdZ (Reserved and Zero) Bits 63:4 TR Dequeue Pointer When extracting the TR Dequeue Pointer for an Endpoint without Streams, in xhci_handle_cmd_set_deq(), the inverted Dequeue Cycle State mask (~EP_CTX_CYCLE_MASK) is used, inadvertently including the Reserved bits. Although bits 3:1 are typically zero, using the incorrect mask could cause issues. The existing mask, named "SCTX_DEQ_MASK," is misleading because "SCTX" implies exclusivity to Stream Contexts, whereas the TR Dequeue Pointer is applicable to both Stream and non-Stream Contexts. Rename the mask to "TR_DEQ_PTR_MASK", utilize GENMASK_ULL() macro and use the mask when handling the TR Dequeue Pointer field. Function xhci_get_hw_deq() returns the Endpoint Context Field 0x08, either directly from the Endpoint context or a Stream. Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20250917210726.97100-5-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 719de07 commit 931e468

2 files changed

Lines changed: 8 additions & 7 deletions

File tree

drivers/usb/host/xhci-ring.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
711711
return -ENODEV;
712712
}
713713

714-
hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
714+
hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id) & TR_DEQ_PTR_MASK;
715715
new_seg = ep_ring->deq_seg;
716716
new_deq = ep_ring->dequeue;
717717
new_cycle = le32_to_cpu(td->end_trb->generic.field[3]) & TRB_CYCLE;
@@ -723,7 +723,7 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci,
723723
*/
724724
do {
725725
if (!hw_dequeue_found && xhci_trb_virt_to_dma(new_seg, new_deq)
726-
== (dma_addr_t)(hw_dequeue & ~0xf)) {
726+
== (dma_addr_t)hw_dequeue) {
727727
hw_dequeue_found = true;
728728
if (td_last_trb_found)
729729
break;
@@ -1066,7 +1066,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep)
10661066
*/
10671067
hw_deq = xhci_get_hw_deq(xhci, ep->vdev, ep->ep_index,
10681068
td->urb->stream_id);
1069-
hw_deq &= ~0xf;
1069+
hw_deq &= TR_DEQ_PTR_MASK;
10701070

10711071
if (td->cancel_status == TD_HALTED || trb_in_td(td, hw_deq)) {
10721072
switch (td->cancel_status) {
@@ -1156,7 +1156,7 @@ static struct xhci_td *find_halted_td(struct xhci_virt_ep *ep)
11561156

11571157
if (!list_empty(&ep->ring->td_list)) { /* Not streams compatible */
11581158
hw_deq = xhci_get_hw_deq(ep->xhci, ep->vdev, ep->ep_index, 0);
1159-
hw_deq &= ~0xf;
1159+
hw_deq &= TR_DEQ_PTR_MASK;
11601160
td = list_first_entry(&ep->ring->td_list, struct xhci_td, td_list);
11611161
if (trb_in_td(td, hw_deq))
11621162
return td;
@@ -1479,7 +1479,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
14791479
u64 deq;
14801480
/* 4.6.10 deq ptr is written to the stream ctx for streams */
14811481
if (ep->ep_state & EP_HAS_STREAMS) {
1482-
deq = le64_to_cpu(stream_ctx->stream_ring) & SCTX_DEQ_MASK;
1482+
deq = le64_to_cpu(stream_ctx->stream_ring) & TR_DEQ_PTR_MASK;
14831483

14841484
/*
14851485
* Cadence xHCI controllers store some endpoint state
@@ -1495,7 +1495,7 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id,
14951495
stream_ctx->reserved[1] = 0;
14961496
}
14971497
} else {
1498-
deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK;
1498+
deq = le64_to_cpu(ep_ctx->deq) & TR_DEQ_PTR_MASK;
14991499
}
15001500
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
15011501
"Successful Set TR Deq Ptr cmd, deq = @%08llx", deq);

drivers/usb/host/xhci.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ struct xhci_ep_ctx {
500500

501501
/* deq bitmasks */
502502
#define EP_CTX_CYCLE_MASK (1 << 0)
503-
#define SCTX_DEQ_MASK (~0xfL)
503+
/* bits 63:4 - TR Dequeue Pointer */
504+
#define TR_DEQ_PTR_MASK GENMASK_ULL(63, 4)
504505

505506

506507
/**

0 commit comments

Comments
 (0)