Skip to content

Commit 49f2985

Browse files
P33Mpelwell
authored andcommitted
xhci: refactor out TRBS_PER_SEGMENT define in runtime code
In anticipation of adjusting the number of utilised TRBs in a ring segment, add trbs_per_seg to struct xhci_ring and use this instead of a compile-time define. Signed-off-by: Jonathan Bell <[email protected]>
1 parent add55da commit 49f2985

File tree

4 files changed

+37
-30
lines changed

4 files changed

+37
-30
lines changed

drivers/usb/host/xhci-mem.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ static void xhci_free_segments_for_ring(struct xhci_hcd *xhci,
9898
*/
9999
static void xhci_link_segments(struct xhci_segment *prev,
100100
struct xhci_segment *next,
101+
unsigned int trbs_per_seg,
101102
enum xhci_ring_type type, bool chain_links)
102103
{
103104
u32 val;
@@ -106,16 +107,16 @@ static void xhci_link_segments(struct xhci_segment *prev,
106107
return;
107108
prev->next = next;
108109
if (type != TYPE_EVENT) {
109-
prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr =
110+
prev->trbs[trbs_per_seg - 1].link.segment_ptr =
110111
cpu_to_le64(next->dma);
111112

112113
/* Set the last TRB in the segment to have a TRB type ID of Link TRB */
113-
val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control);
114+
val = le32_to_cpu(prev->trbs[trbs_per_seg - 1].link.control);
114115
val &= ~TRB_TYPE_BITMASK;
115116
val |= TRB_TYPE(TRB_LINK);
116117
if (chain_links)
117118
val |= TRB_CHAIN;
118-
prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val);
119+
prev->trbs[trbs_per_seg - 1].link.control = cpu_to_le32(val);
119120
}
120121
}
121122

@@ -139,15 +140,17 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring,
139140
(xhci->quirks & XHCI_AMD_0x96_HOST)));
140141

141142
next = ring->enq_seg->next;
142-
xhci_link_segments(ring->enq_seg, first, ring->type, chain_links);
143-
xhci_link_segments(last, next, ring->type, chain_links);
143+
xhci_link_segments(ring->enq_seg, first, ring->trbs_per_seg,
144+
ring->type, chain_links);
145+
xhci_link_segments(last, next, ring->trbs_per_seg,
146+
ring->type, chain_links);
144147
ring->num_segs += num_segs;
145-
ring->num_trbs_free += (TRBS_PER_SEGMENT - 1) * num_segs;
148+
ring->num_trbs_free += (ring->trbs_per_seg - 1) * num_segs;
146149

147150
if (ring->type != TYPE_EVENT && ring->enq_seg == ring->last_seg) {
148-
ring->last_seg->trbs[TRBS_PER_SEGMENT-1].link.control
151+
ring->last_seg->trbs[ring->trbs_per_seg - 1].link.control
149152
&= ~cpu_to_le32(LINK_TOGGLE);
150-
last->trbs[TRBS_PER_SEGMENT-1].link.control
153+
last->trbs[ring->trbs_per_seg - 1].link.control
151154
|= cpu_to_le32(LINK_TOGGLE);
152155
ring->last_seg = last;
153156
}
@@ -314,14 +317,15 @@ void xhci_initialize_ring_info(struct xhci_ring *ring,
314317
* Each segment has a link TRB, and leave an extra TRB for SW
315318
* accounting purpose
316319
*/
317-
ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
320+
ring->num_trbs_free = ring->num_segs * (ring->trbs_per_seg - 1) - 1;
318321
}
319322

320323
/* Allocate segments and link them for a ring */
321324
static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
322325
struct xhci_segment **first, struct xhci_segment **last,
323-
unsigned int num_segs, unsigned int cycle_state,
324-
enum xhci_ring_type type, unsigned int max_packet, gfp_t flags)
326+
unsigned int num_segs, unsigned int trbs_per_seg,
327+
unsigned int cycle_state, enum xhci_ring_type type,
328+
unsigned int max_packet, gfp_t flags)
325329
{
326330
struct xhci_segment *prev;
327331
bool chain_links;
@@ -350,12 +354,12 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,
350354
}
351355
return -ENOMEM;
352356
}
353-
xhci_link_segments(prev, next, type, chain_links);
357+
xhci_link_segments(prev, next, trbs_per_seg, type, chain_links);
354358

355359
prev = next;
356360
num_segs--;
357361
}
358-
xhci_link_segments(prev, *first, type, chain_links);
362+
xhci_link_segments(prev, *first, trbs_per_seg, type, chain_links);
359363
*last = prev;
360364

361365
return 0;
@@ -387,16 +391,17 @@ struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
387391
if (num_segs == 0)
388392
return ring;
389393

394+
ring->trbs_per_seg = TRBS_PER_SEGMENT;
390395
ret = xhci_alloc_segments_for_ring(xhci, &ring->first_seg,
391-
&ring->last_seg, num_segs, cycle_state, type,
392-
max_packet, flags);
396+
&ring->last_seg, num_segs, ring->trbs_per_seg,
397+
cycle_state, type, max_packet, flags);
393398
if (ret)
394399
goto fail;
395400

396401
/* Only event ring does not use link TRB */
397402
if (type != TYPE_EVENT) {
398403
/* See section 4.9.2.1 and 6.4.4.1 */
399-
ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |=
404+
ring->last_seg->trbs[ring->trbs_per_seg - 1].link.control |=
400405
cpu_to_le32(LINK_TOGGLE);
401406
}
402407
xhci_initialize_ring_info(ring, cycle_state);
@@ -429,16 +434,15 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,
429434
unsigned int num_segs_needed;
430435
int ret;
431436

432-
num_segs_needed = (num_trbs + (TRBS_PER_SEGMENT - 1) - 1) /
433-
(TRBS_PER_SEGMENT - 1);
434-
437+
num_segs_needed = (num_trbs + (ring->trbs_per_seg - 1) - 1) /
438+
(ring->trbs_per_seg - 1);
435439
/* Allocate number of segments we needed, or double the ring size */
436440
num_segs = ring->num_segs > num_segs_needed ?
437441
ring->num_segs : num_segs_needed;
438442

439443
ret = xhci_alloc_segments_for_ring(xhci, &first, &last,
440-
num_segs, ring->cycle_state, ring->type,
441-
ring->bounce_buf_len, flags);
444+
num_segs, ring->trbs_per_seg, ring->cycle_state,
445+
ring->type, ring->bounce_buf_len, flags);
442446
if (ret)
443447
return -ENOMEM;
444448

@@ -1825,7 +1829,7 @@ int xhci_alloc_erst(struct xhci_hcd *xhci,
18251829
for (val = 0; val < evt_ring->num_segs; val++) {
18261830
entry = &erst->entries[val];
18271831
entry->seg_addr = cpu_to_le64(seg->dma);
1828-
entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT);
1832+
entry->seg_size = cpu_to_le32(evt_ring->trbs_per_seg);
18291833
entry->rsvd = 0;
18301834
seg = seg->next;
18311835
}

drivers/usb/host/xhci-ring.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,16 @@ static bool trb_is_link(union xhci_trb *trb)
8787
return TRB_TYPE_LINK_LE32(trb->link.control);
8888
}
8989

90-
static bool last_trb_on_seg(struct xhci_segment *seg, union xhci_trb *trb)
90+
static bool last_trb_on_seg(struct xhci_segment *seg,
91+
unsigned int trbs_per_seg, union xhci_trb *trb)
9192
{
92-
return trb == &seg->trbs[TRBS_PER_SEGMENT - 1];
93+
return trb == &seg->trbs[trbs_per_seg - 1];
9394
}
9495

9596
static bool last_trb_on_ring(struct xhci_ring *ring,
9697
struct xhci_segment *seg, union xhci_trb *trb)
9798
{
98-
return last_trb_on_seg(seg, trb) && (seg->next == ring->first_seg);
99+
return last_trb_on_seg(seg, ring->trbs_per_seg, trb) && (seg->next == ring->first_seg);
99100
}
100101

101102
static bool link_trb_toggles_cycle(union xhci_trb *trb)
@@ -157,7 +158,8 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)
157158
{
158159
/* event ring doesn't have link trbs, check for last trb */
159160
if (ring->type == TYPE_EVENT) {
160-
if (!last_trb_on_seg(ring->deq_seg, ring->dequeue)) {
161+
if (!last_trb_on_seg(ring->deq_seg, ring->trbs_per_seg,
162+
ring->dequeue)) {
161163
ring->dequeue++;
162164
goto out;
163165
}
@@ -2976,7 +2978,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
29762978
* that clears the EHB.
29772979
*/
29782980
while (xhci_handle_event(xhci) > 0) {
2979-
if (event_loop++ < TRBS_PER_SEGMENT / 2)
2981+
if (event_loop++ < xhci->event_ring->trbs_per_seg / 2)
29802982
continue;
29812983
xhci_update_erst_dequeue(xhci, event_ring_deq);
29822984
event_loop = 0;

drivers/usb/host/xhci.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,8 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
858858
seg = ring->deq_seg;
859859
do {
860860
memset(seg->trbs, 0,
861-
sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
862-
seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
861+
sizeof(union xhci_trb) * (ring->trbs_per_seg - 1));
862+
seg->trbs[ring->trbs_per_seg - 1].link.control &=
863863
cpu_to_le32(~TRB_CYCLE);
864864
seg = seg->next;
865865
} while (seg != ring->deq_seg);
@@ -870,7 +870,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
870870
ring->enq_seg = ring->deq_seg;
871871
ring->enqueue = ring->dequeue;
872872

873-
ring->num_trbs_free = ring->num_segs * (TRBS_PER_SEGMENT - 1) - 1;
873+
ring->num_trbs_free = ring->num_segs * (ring->trbs_per_seg - 1) - 1;
874874
/*
875875
* Ring is now zeroed, so the HW should look for change of ownership
876876
* when the cycle bit is set to 1.

drivers/usb/host/xhci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,6 +1615,7 @@ struct xhci_ring {
16151615
unsigned int num_trbs_free;
16161616
unsigned int num_trbs_free_temp;
16171617
unsigned int bounce_buf_len;
1618+
unsigned int trbs_per_seg;
16181619
enum xhci_ring_type type;
16191620
bool last_td_was_short;
16201621
struct radix_tree_root *trb_address_map;

0 commit comments

Comments
 (0)