1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

usb: xhci: refactor xhci_link_rings() to use source and destination rings

Refactor the xhci_link_rings() function to accept two rings: a source ring
and a destination ring. Previously, the function accepted a ring and a
segment list as arguments, now the function splices the source ring segment
list into the destination ring. This new approach reduces the number of
arguments and simplifies the code, making it easier to follow.

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/20241106101459.775897-15-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Niklas Neronin 2024-11-06 12:14:40 +02:00 committed by Greg Kroah-Hartman
parent 0049d49317
commit fe688e5006

View file

@ -116,45 +116,42 @@ static void xhci_link_segments(struct xhci_segment *prev,
} }
/* /*
* Link the ring to the new segments. * Link the src ring segments to the dst ring.
* Set Toggle Cycle for the new ring if needed. * Set Toggle Cycle for the new ring if needed.
*/ */
static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring, static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *src, struct xhci_ring *dst)
struct xhci_segment *first, struct xhci_segment *last,
unsigned int num_segs)
{ {
struct xhci_segment *next, *seg; struct xhci_segment *seg;
bool chain_links; bool chain_links;
if (!ring || !first || !last) if (!src || !dst)
return; return;
chain_links = xhci_link_chain_quirk(xhci, ring->type); chain_links = xhci_link_chain_quirk(xhci, dst->type);
/* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */ /* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */
if (ring->cycle_state == 0) { if (dst->cycle_state == 0) {
xhci_for_each_ring_seg(ring->first_seg, seg) { xhci_for_each_ring_seg(src->first_seg, seg) {
for (int i = 0; i < TRBS_PER_SEGMENT; i++) for (int i = 0; i < TRBS_PER_SEGMENT; i++)
seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE); seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE);
} }
} }
next = ring->enq_seg->next; xhci_link_segments(src->last_seg, dst->enq_seg->next, dst->type, chain_links);
xhci_link_segments(ring->enq_seg, first, ring->type, chain_links); xhci_link_segments(dst->enq_seg, src->first_seg, dst->type, chain_links);
xhci_link_segments(last, next, ring->type, chain_links); dst->num_segs += src->num_segs;
ring->num_segs += num_segs;
if (ring->enq_seg == ring->last_seg) { if (dst->enq_seg == dst->last_seg) {
if (ring->type != TYPE_EVENT) { if (dst->type != TYPE_EVENT) {
ring->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control dst->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control
&= ~cpu_to_le32(LINK_TOGGLE); &= ~cpu_to_le32(LINK_TOGGLE);
last->trbs[TRBS_PER_SEGMENT-1].link.control src->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control
|= cpu_to_le32(LINK_TOGGLE); |= cpu_to_le32(LINK_TOGGLE);
} }
ring->last_seg = last; dst->last_seg = src->last_seg;
} }
for (seg = ring->enq_seg; seg != ring->last_seg; seg = seg->next) for (seg = dst->enq_seg; seg != dst->last_seg; seg = seg->next)
seg->next->num = seg->num + 1; seg->next->num = seg->num + 1;
} }
@ -411,6 +408,9 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
struct xhci_ring new_ring; struct xhci_ring new_ring;
int ret; int ret;
if (num_new_segs == 0)
return 0;
new_ring.num_segs = num_new_segs; new_ring.num_segs = num_new_segs;
new_ring.bounce_buf_len = ring->bounce_buf_len; new_ring.bounce_buf_len = ring->bounce_buf_len;
new_ring.type = ring->type; new_ring.type = ring->type;
@ -425,7 +425,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
goto free_segments; goto free_segments;
} }
xhci_link_rings(xhci, ring, new_ring.first_seg, new_ring.last_seg, num_new_segs); xhci_link_rings(xhci, ring, &new_ring);
trace_xhci_ring_expansion(ring); trace_xhci_ring_expansion(ring);
xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion, xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion,
"ring expansion succeed, now has %d segments", "ring expansion succeed, now has %d segments",