diff options
author | Ian Moffett <ian@osmora.org> | 2024-04-04 19:26:45 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2024-04-04 19:27:10 -0400 |
commit | 8d6088386c1fa0bf09678b328bee19768f138dcb (patch) | |
tree | b907ef43d90f12681fbdef7ce6d412f4cef53c45 /sys/dev | |
parent | f78c52a09994d281e043110d01049cbfe393e5ac (diff) |
kernel: xhci: Add link TRB at end of cmd ring
Make the command ring circular by pointing the xHC to the start
once it reaches the end.
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/usb/xhci.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index a6996bf..2550768 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -116,14 +116,24 @@ xhci_submit_cmd(struct xhci_hc *hc, struct xhci_trb trb) hc->cmd_ring[hc->cmd_ptr++] = trb.dword3 | hc->cycle; hc->cmd_count++; - if (hc->cmd_count >= XHCI_CMDRING_LEN) { - /* TODO: Add link TRB */ - __assert(0 && "TODO"); - } - /* Ring the command doorbell */ cmd_db = XHCI_CMD_DB(hc->base, caps->dboff); *cmd_db = 0; + + if (hc->cmd_count >= XHCI_CMDRING_LEN - 1) { + /* Create raw link TRB and ring the doorbell */ + hc->cmd_ring[hc->cmd_ptr++] = VIRT_TO_PHYS(hc->cmd_ring) & 0xFFFFFFFF; + hc->cmd_ring[hc->cmd_ptr++] = VIRT_TO_PHYS(hc->cmd_ring) >> 32; + hc->cmd_ring[hc->cmd_ptr++] = 0; + hc->cmd_ring[hc->cmd_ptr++] = hc->cycle | (XHCI_LINK << 10) | __BIT(1); + *cmd_db = 0; + + /* Reset command state and flip cycle */ + hc->cmd_ptr = 0; + hc->cmd_count = 0; + hc->cycle = ~hc->cycle; + } + return 0; } |