Skip to content

Commit

Permalink
usb: xhci: utilize 'xhci_free_segments_for_ring()' for freeing segments
Browse files Browse the repository at this point in the history
Refactor the code to improve readability by using
'xhci_free_segments_for_ring()' function for freeing ring segments.
This replaces the custom while loop previously used within
'xhci_ring_expansion()' and 'xhci_alloc_segments_for_ring()'.

Slightly modify 'xhci_free_segments_for_ring()' to handle lists
which do not loop. This makes it possible to use it in error
paths of 'xhci_alloc_segments_for_ring()'.

This change also prepares for switching the custom xhci linked segment
list into to more standard list.h lists.

[minor commit message rewording -Mathias]

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/20240229141438.619372-6-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Niklas Neronin authored and Greg Kroah-Hartman committed Mar 2, 2024
1 parent 00bdc4a commit 2e8dd2d
Showing 1 changed file with 15 additions and 22 deletions.
37 changes: 15 additions & 22 deletions drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ static void xhci_free_segments_for_ring(struct xhci_hcd *xhci,
struct xhci_segment *seg;

seg = first->next;
while (seg != first) {
while (seg && seg != first) {
struct xhci_segment *next = seg->next;
xhci_segment_free(xhci, seg);
seg = next;
@@ -351,24 +351,21 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,

next = xhci_segment_alloc(xhci, cycle_state, max_packet, num,
flags);
if (!next) {
prev = *first;
while (prev) {
next = prev->next;
xhci_segment_free(xhci, prev);
prev = next;
}
return -ENOMEM;
}
xhci_link_segments(prev, next, type, chain_links);
if (!next)
goto free_segments;

xhci_link_segments(prev, next, type, chain_links);
prev = next;
num++;
}
xhci_link_segments(prev, *first, type, chain_links);
*last = prev;

return 0;

free_segments:
xhci_free_segments_for_ring(xhci, *first);
return -ENOMEM;
}

/*
@@ -444,19 +441,11 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
if (ret)
return -ENOMEM;

if (ring->type == TYPE_STREAM)
if (ring->type == TYPE_STREAM) {
ret = xhci_update_stream_segment_mapping(ring->trb_address_map,
ring, first, last, flags);
if (ret) {
struct xhci_segment *next;
do {
next = first->next;
xhci_segment_free(xhci, first);
if (first == last)
break;
first = next;
} while (true);
return ret;
if (ret)
goto free_segments;
}

xhci_link_rings(xhci, ring, first, last, num_new_segs);
@@ -466,6 +455,10 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
ring->num_segs);

return 0;

free_segments:
xhci_free_segments_for_ring(xhci, first);
return ret;
}

struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,

0 comments on commit 2e8dd2d

Please sign in to comment.