mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
usb: xhci: introduce macro for ring segment list iteration
Add macro to streamline and standardize the iteration over ring segment list. xhci_for_each_ring_seg(): Iterates over the entire ring segment list. The xhci_free_segments_for_ring() function's while loop has not been updated to use the new macro. This function has some underlying issues, and as a result, it will be handled separately in a future patch. Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 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-11-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
6d00b6142d
commit
3f970bd06c
|
@ -214,14 +214,11 @@ static void xhci_ring_dump_segment(struct seq_file *s,
|
|||
|
||||
static int xhci_ring_trb_show(struct seq_file *s, void *unused)
|
||||
{
|
||||
int i;
|
||||
struct xhci_ring *ring = *(struct xhci_ring **)s->private;
|
||||
struct xhci_segment *seg = ring->first_seg;
|
||||
|
||||
for (i = 0; i < ring->num_segs; i++) {
|
||||
xhci_for_each_ring_seg(ring->first_seg, seg)
|
||||
xhci_ring_dump_segment(s, seg);
|
||||
seg = seg->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -224,7 +224,6 @@ static int xhci_update_stream_segment_mapping(
|
|||
struct radix_tree_root *trb_address_map,
|
||||
struct xhci_ring *ring,
|
||||
struct xhci_segment *first_seg,
|
||||
struct xhci_segment *last_seg,
|
||||
gfp_t mem_flags)
|
||||
{
|
||||
struct xhci_segment *seg;
|
||||
|
@ -234,28 +233,22 @@ static int xhci_update_stream_segment_mapping(
|
|||
if (WARN_ON_ONCE(trb_address_map == NULL))
|
||||
return 0;
|
||||
|
||||
seg = first_seg;
|
||||
do {
|
||||
xhci_for_each_ring_seg(first_seg, seg) {
|
||||
ret = xhci_insert_segment_mapping(trb_address_map,
|
||||
ring, seg, mem_flags);
|
||||
if (ret)
|
||||
goto remove_streams;
|
||||
if (seg == last_seg)
|
||||
return 0;
|
||||
seg = seg->next;
|
||||
} while (seg != first_seg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
remove_streams:
|
||||
failed_seg = seg;
|
||||
seg = first_seg;
|
||||
do {
|
||||
xhci_for_each_ring_seg(first_seg, seg) {
|
||||
xhci_remove_segment_mapping(trb_address_map, seg);
|
||||
if (seg == failed_seg)
|
||||
return ret;
|
||||
seg = seg->next;
|
||||
} while (seg != first_seg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -267,17 +260,14 @@ static void xhci_remove_stream_mapping(struct xhci_ring *ring)
|
|||
if (WARN_ON_ONCE(ring->trb_address_map == NULL))
|
||||
return;
|
||||
|
||||
seg = ring->first_seg;
|
||||
do {
|
||||
xhci_for_each_ring_seg(ring->first_seg, seg)
|
||||
xhci_remove_segment_mapping(ring->trb_address_map, seg);
|
||||
seg = seg->next;
|
||||
} while (seg != ring->first_seg);
|
||||
}
|
||||
|
||||
static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags)
|
||||
{
|
||||
return xhci_update_stream_segment_mapping(ring->trb_address_map, ring,
|
||||
ring->first_seg, ring->last_seg, mem_flags);
|
||||
ring->first_seg, mem_flags);
|
||||
}
|
||||
|
||||
/* XXX: Do we need the hcd structure in all these functions? */
|
||||
|
@ -438,7 +428,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
|
|||
|
||||
if (ring->type == TYPE_STREAM) {
|
||||
ret = xhci_update_stream_segment_mapping(ring->trb_address_map,
|
||||
ring, first, last, flags);
|
||||
ring, first, flags);
|
||||
if (ret)
|
||||
goto free_segments;
|
||||
}
|
||||
|
|
|
@ -40,15 +40,15 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
|
|||
|
||||
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
|
||||
{
|
||||
struct xhci_segment *seg = ring->first_seg;
|
||||
struct xhci_segment *seg;
|
||||
|
||||
if (!td || !td->start_seg)
|
||||
return false;
|
||||
do {
|
||||
|
||||
xhci_for_each_ring_seg(ring->first_seg, seg) {
|
||||
if (seg == td->start_seg)
|
||||
return true;
|
||||
seg = seg->next;
|
||||
} while (seg && seg != ring->first_seg);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -785,14 +785,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
|
|||
struct xhci_segment *seg;
|
||||
|
||||
ring = xhci->cmd_ring;
|
||||
seg = ring->deq_seg;
|
||||
do {
|
||||
memset(seg->trbs, 0,
|
||||
sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
|
||||
seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
|
||||
cpu_to_le32(~TRB_CYCLE);
|
||||
seg = seg->next;
|
||||
} while (seg != ring->deq_seg);
|
||||
xhci_for_each_ring_seg(ring->deq_seg, seg) {
|
||||
memset(seg->trbs, 0, sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
|
||||
seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= cpu_to_le32(~TRB_CYCLE);
|
||||
}
|
||||
|
||||
xhci_initialize_ring_info(ring, 1);
|
||||
/*
|
||||
|
|
|
@ -1263,6 +1263,9 @@ static inline const char *xhci_trb_type_string(u8 type)
|
|||
#define AVOID_BEI_INTERVAL_MIN 8
|
||||
#define AVOID_BEI_INTERVAL_MAX 32
|
||||
|
||||
#define xhci_for_each_ring_seg(head, seg) \
|
||||
for (seg = head; seg != NULL; seg = (seg->next != head ? seg->next : NULL))
|
||||
|
||||
struct xhci_segment {
|
||||
union xhci_trb *trbs;
|
||||
/* private to HCD */
|
||||
|
|
Loading…
Reference in New Issue
Block a user