XHCI generic way of putting TRBs onto a ring
This commit is contained in:
@@ -605,31 +605,30 @@ static void xhci_irq (void* arg, void* regs, bool user, struct reschedule_ctx* r
|
||||
spin_unlock (&xhci->device->lock, fd);
|
||||
}
|
||||
|
||||
static void xhci_endpoint0_put_trb (struct xhci_usb_device* usb_device, struct xhci_trb put_trb) {
|
||||
if (usb_device->endpoint0_ring.idx == usb_device->endpoint0_ring.size - 1) {
|
||||
struct xhci_trb* link = &usb_device->endpoint0_ring.trbs[usb_device->endpoint0_ring.idx];
|
||||
link->param = usb_device->endpoint0_ring.phys;
|
||||
static void xhci_ring_put_trb (struct xhci_ring* ring, struct xhci_trb put_trb) {
|
||||
if (ring->idx == ring->size - 1) {
|
||||
struct xhci_trb* link = &ring->trbs[ring->idx];
|
||||
link->param = ring->phys;
|
||||
link->status = 0;
|
||||
|
||||
write_memory_barrier ();
|
||||
|
||||
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) |
|
||||
(1 << XHCI_LNKTRB_CTRL_TC) |
|
||||
usb_device->endpoint0_ring.cycle_bit;
|
||||
link->ctrl =
|
||||
(XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) | (1 << XHCI_LNKTRB_CTRL_TC) | ring->cycle_bit;
|
||||
|
||||
usb_device->endpoint0_ring.idx = 0;
|
||||
usb_device->endpoint0_ring.cycle_bit ^= 1;
|
||||
ring->idx = 0;
|
||||
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->status = put_trb.status;
|
||||
|
||||
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,
|
||||
@@ -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) |
|
||||
(1 << XHCI_SSTRB_CTRL_IDT) |
|
||||
(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 */
|
||||
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 ();
|
||||
|
||||
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 */
|
||||
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 ();
|
||||
|
||||
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);
|
||||
|
||||
@@ -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) |
|
||||
(1 << XHCI_SSTRB_CTRL_IDT) |
|
||||
(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 {
|
||||
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
|
||||
(1 << XHCI_SSTRB_CTRL_IDT) |
|
||||
(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 */
|
||||
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 ();
|
||||
|
||||
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 */
|
||||
@@ -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) |
|
||||
(1 << XHCI_STSTRB_CTRL_IOC) |
|
||||
(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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user