usb: xhci: utilize 'xhci_free_segments_for_ring()' for freeing segments
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>
This commit is contained in:
parent
00bdc4a34b
commit
2e8dd2ded2
|
@ -84,7 +84,7 @@ static void xhci_free_segments_for_ring(struct xhci_hcd *xhci,
|
||||||
struct xhci_segment *seg;
|
struct xhci_segment *seg;
|
||||||
|
|
||||||
seg = first->next;
|
seg = first->next;
|
||||||
while (seg != first) {
|
while (seg && seg != first) {
|
||||||
struct xhci_segment *next = seg->next;
|
struct xhci_segment *next = seg->next;
|
||||||
xhci_segment_free(xhci, seg);
|
xhci_segment_free(xhci, seg);
|
||||||
seg = next;
|
seg = next;
|
||||||
|
@ -351,17 +351,10 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
|
||||||
|
|
||||||
next = xhci_segment_alloc(xhci, cycle_state, max_packet, num,
|
next = xhci_segment_alloc(xhci, cycle_state, max_packet, num,
|
||||||
flags);
|
flags);
|
||||||
if (!next) {
|
if (!next)
|
||||||
prev = *first;
|
goto free_segments;
|
||||||
while (prev) {
|
|
||||||
next = prev->next;
|
|
||||||
xhci_segment_free(xhci, prev);
|
|
||||||
prev = next;
|
|
||||||
}
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
xhci_link_segments(prev, next, type, chain_links);
|
|
||||||
|
|
||||||
|
xhci_link_segments(prev, next, type, chain_links);
|
||||||
prev = next;
|
prev = next;
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
@ -369,6 +362,10 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
|
||||||
*last = prev;
|
*last = prev;
|
||||||
|
|
||||||
return 0;
|
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)
|
if (ret)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (ring->type == TYPE_STREAM)
|
if (ring->type == TYPE_STREAM) {
|
||||||
ret = xhci_update_stream_segment_mapping(ring->trb_address_map,
|
ret = xhci_update_stream_segment_mapping(ring->trb_address_map,
|
||||||
ring, first, last, flags);
|
ring, first, last, flags);
|
||||||
if (ret) {
|
if (ret)
|
||||||
struct xhci_segment *next;
|
goto free_segments;
|
||||||
do {
|
|
||||||
next = first->next;
|
|
||||||
xhci_segment_free(xhci, first);
|
|
||||||
if (first == last)
|
|
||||||
break;
|
|
||||||
first = next;
|
|
||||||
} while (true);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xhci_link_rings(xhci, ring, first, last, num_new_segs);
|
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);
|
ring->num_segs);
|
||||||
|
|
||||||
return 0;
|
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,
|
struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
|
||||||
|
|
Loading…
Reference in New Issue