@@ -7,6 +7,10 @@ static struct xhci_hc* g_xhci; /* single controller */
77
88static void xhci_deliver_ep1in (struct xhci_hc * hc , const struct trb * ev , bool deliver_to_driver );
99
10+ static inline uint8_t trb_cycle_bit (const struct trb * t ) {
11+ return (uint8_t )(t -> ctrl & TRB_CYCLE );
12+ }
13+
1014static inline uint8_t trb_get_type (const struct trb * e ) {
1115 return (uint8_t )((e -> ctrl >> 10 ) & 0x3F );
1216}
@@ -136,38 +140,32 @@ static inline struct trb *ring_push(struct xhci_ring *r)
136140{
137141 struct trb * cur = & r -> base [r -> enqueue ];
138142
139- // Ensure caller can set the C bit on the TRB they’re about to fill.
140- // (Caller will set TRB_CYCLE according to r->cycle.)
141- // Do NOT zero a LINK TRB.
142-
143- // Advance the producer pointer
143+ /* advance producer */
144144 r -> enqueue ++ ;
145145 dprintf ("enqueue=%u num_trbs=%u\n" , r -> enqueue , r -> num_trbs );
146146
147- // If we landed on the LINK TRB, present it to HW and wrap
148147 if (r -> enqueue == r -> num_trbs ) {
149148 dprintf ("wrap LINK\n" );
150149 struct trb * link = & r -> base [r -> num_trbs - 1 ];
151150
152- // Set LINK’s C bit to current producer cycle
151+ /* present LINK to HW with current producer cycle */
153152 link -> ctrl = (link -> ctrl & ~TRB_CYCLE ) | (r -> cycle ? TRB_CYCLE : 0 );
154153
155- // “Post” the LINK TRB by moving past it
154+ /* wrap to start */
156155 r -> enqueue = 0 ;
157156
158- // If LINK.TC=1, flip producer cycle bit
157+ /* flip producer cycle if LINK.TC set */
159158 if (link -> ctrl & TRB_TOGGLE )
160159 r -> cycle ^= 1u ;
161160
162- // Now cur becomes the first slot of the ring
163- cur = & r -> base [r -> enqueue ];
161+ /* hand back TRB[0] and advance to 1 so next push gets TRB[1] */
162+ cur = & r -> base [r -> enqueue ++ ];
164163 }
165164
166- // Hand back the slot to be filled; clear only non- LINK slots
165+ /* clear only the TRB we’re returning (never the LINK) */
167166 memset (cur , 0 , sizeof (* cur ));
168167 return cur ;
169168}
170-
171169static int xhci_cmd_submit_wait (struct xhci_hc * hc , struct trb * cmd_trb , uint64_t * out_cc_trb_lohi ) {
172170 (void )out_cc_trb_lohi ;
173171
@@ -390,6 +388,8 @@ static int xhci_reset_controller(struct xhci_hc *hc) {
390388 hc -> evt .num_trbs = (uint32_t )(4096 / sizeof (struct trb ));
391389 hc -> evt .enqueue = 0 ;
392390 hc -> evt .cycle = 1 ;
391+ hc -> evt .dequeue = 0 ; /* software consumer index for the event ring */
392+ hc -> evt .ccs = 1 ; /* consumer cycle state starts at 1 per xHCI */
393393
394394 hc -> erst = (struct erst_entry * ) kmalloc_aligned (64 , 64 );
395395 memset (hc -> erst , 0 , 64 );
@@ -401,6 +401,7 @@ static int xhci_reset_controller(struct xhci_hc *hc) {
401401 mmio_write32 (ir0 + IR_ERSTSZ , 1 );
402402 mmio_write64 (ir0 + IR_ERSTBA , hc -> erst_phys );
403403 mmio_write64 (ir0 + IR_ERDP , er_phys | (1ull << 3 ));
404+
404405 mmio_write32 (ir0 + IR_IMOD , 0 );
405406 mmio_write32 (ir0 + IR_IMAN , IR_IMAN_IE );
406407
@@ -937,14 +938,11 @@ static void xhci_isr(uint8_t isr, uint64_t error, uint64_t irq, void *opaque)
937938 if (epid == EPID_EP1_IN ) {
938939 xhci_deliver_ep1in (hc , e , true);
939940 } else {
940- /* Consume and advance ERDP by one TRB (leave EHB clear) */
941941 xhci_handle_unrelated_transfer_event (hc , e );
942942 }
943943 } else {
944- /* Consume and advance ERDP by one TRB (leave EHB clear) */
945944 xhci_handle_unrelated_transfer_event (hc , e );
946945 }
947-
948946 memset (e , 0 , sizeof (* e ));
949947 erdp_cur = (erdp_cur + 16 ) & ~0x7ull ;
950948 mmio_write64 (ir0 + IR_ERDP , erdp_cur );
0 commit comments