XHCI generic way of putting TRBs onto a ring

This commit is contained in:
2026-04-03 16:46:02 +02:00
parent 92ed1fb968
commit 6dd7a7c654

View File

@@ -605,31 +605,30 @@ static void xhci_irq (void* arg, void* regs, bool user, struct reschedule_ctx* r
spin_unlock (&xhci->device->lock, fd); spin_unlock (&xhci->device->lock, fd);
} }
static void xhci_endpoint0_put_trb (struct xhci_usb_device* usb_device, struct xhci_trb put_trb) { static void xhci_ring_put_trb (struct xhci_ring* ring, struct xhci_trb put_trb) {
if (usb_device->endpoint0_ring.idx == usb_device->endpoint0_ring.size - 1) { if (ring->idx == ring->size - 1) {
struct xhci_trb* link = &usb_device->endpoint0_ring.trbs[usb_device->endpoint0_ring.idx]; struct xhci_trb* link = &ring->trbs[ring->idx];
link->param = usb_device->endpoint0_ring.phys; link->param = ring->phys;
link->status = 0; link->status = 0;
write_memory_barrier (); write_memory_barrier ();
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) | link->ctrl =
(1 << XHCI_LNKTRB_CTRL_TC) | (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) | (1 << XHCI_LNKTRB_CTRL_TC) | ring->cycle_bit;
usb_device->endpoint0_ring.cycle_bit;
usb_device->endpoint0_ring.idx = 0; ring->idx = 0;
usb_device->endpoint0_ring.cycle_bit ^= 1; ring->cycle_bit ^= 1;
} }
struct xhci_trb* trb = &usb_device->endpoint0_ring.trbs[usb_device->endpoint0_ring.idx]; struct xhci_trb* trb = &ring->trbs[ring->idx];
trb->param = put_trb.param; trb->param = put_trb.param;
trb->status = put_trb.status; trb->status = put_trb.status;
write_memory_barrier (); write_memory_barrier ();
trb->ctrl = (put_trb.ctrl & ~XHCI_LNKTRB_CTRL_TC) | usb_device->endpoint0_ring.cycle_bit; trb->ctrl = (put_trb.ctrl & ~XHCI_LNKTRB_CTRL_TC) | ring->cycle_bit;
usb_device->endpoint0_ring.idx++; ring->idx++;
} }
static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_usb_device* usb_device, static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_usb_device* usb_device,
@@ -656,7 +655,7 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_usb_device* u
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) | trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
(1 << XHCI_SSTRB_CTRL_IDT) | (1 << XHCI_SSTRB_CTRL_IDT) |
(XHCI_SSTRB_TRT_IN_DATA_STAGE << XHCI_SSTRB_CTRL_TRT); (XHCI_SSTRB_TRT_IN_DATA_STAGE << XHCI_SSTRB_CTRL_TRT);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
/* data stage */ /* data stage */
memset (&trb, 0, sizeof (trb)); memset (&trb, 0, sizeof (trb));
@@ -666,7 +665,7 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_usb_device* u
write_memory_barrier (); write_memory_barrier ();
trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE) | (1 << XHCI_DSTRB_CTRL_DIR); trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE) | (1 << XHCI_DSTRB_CTRL_DIR);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
/* status stage */ /* status stage */
memset (&trb, 0, sizeof (trb)); memset (&trb, 0, sizeof (trb));
@@ -676,7 +675,7 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_usb_device* u
write_memory_barrier (); write_memory_barrier ();
trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) | (1 << XHCI_STSTRB_CTRL_IOC); trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) | (1 << XHCI_STSTRB_CTRL_IOC);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
atomic_store (&xhci->pending, true); atomic_store (&xhci->pending, true);
@@ -724,12 +723,12 @@ static bool xhci_endpoint0_ctrl_out (struct xhci* xhci, struct xhci_usb_device*
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) | trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
(1 << XHCI_SSTRB_CTRL_IDT) | (1 << XHCI_SSTRB_CTRL_IDT) |
(XHCI_SSTRB_TRT_NO_DATA_STAGE << XHCI_SSTRB_CTRL_TRT); (XHCI_SSTRB_TRT_NO_DATA_STAGE << XHCI_SSTRB_CTRL_TRT);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
} else { } else {
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) | trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
(1 << XHCI_SSTRB_CTRL_IDT) | (1 << XHCI_SSTRB_CTRL_IDT) |
(XHCI_SSTRB_TRT_OUT_DATA_STAGE << XHCI_SSTRB_CTRL_TRT); (XHCI_SSTRB_TRT_OUT_DATA_STAGE << XHCI_SSTRB_CTRL_TRT);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
/* data stage */ /* data stage */
memset (&trb, 0, sizeof (trb)); memset (&trb, 0, sizeof (trb));
@@ -739,7 +738,7 @@ static bool xhci_endpoint0_ctrl_out (struct xhci* xhci, struct xhci_usb_device*
write_memory_barrier (); write_memory_barrier ();
trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE); trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
} }
/* status stage */ /* status stage */
@@ -752,7 +751,7 @@ static bool xhci_endpoint0_ctrl_out (struct xhci* xhci, struct xhci_usb_device*
trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) | trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) |
(1 << XHCI_STSTRB_CTRL_IOC) | (1 << XHCI_STSTRB_CTRL_IOC) |
(1 << XHCI_STSTRB_CTRL_DIR); (1 << XHCI_STSTRB_CTRL_DIR);
xhci_endpoint0_put_trb (usb_device, trb); xhci_ring_put_trb (&usb_device->endpoint0_ring, trb);
atomic_store (&xhci->pending, true); atomic_store (&xhci->pending, true);