From f5325a0dec76f15ce2d0ba28719cc78710b63574 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Fri, 5 Apr 2024 20:03:21 -0400 Subject: kernel: xhci: Add xhci_init_evring() Add event ring init routine Signed-off-by: Ian Moffett --- sys/dev/usb/xhci.c | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'sys/dev') diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 5659d61..d68eeac 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -382,6 +382,43 @@ xhci_alloc_evring(struct xhci_hc *hc) return VIRT_TO_PHYS(hc->evring_seg); } +/* + * Sets up the event ring. + */ +static void +xhci_init_evring(struct xhci_hc *hc) +{ + struct xhci_caps *caps = XHCI_CAPS(hc->base); + struct xhci_evring_segment *seg; + uint64_t *erdp, *erstba; + uint32_t *erst_size; + void *runtime = XHCI_RTS(hc->base, caps->rtsoff); + size_t size; + + size = XHCI_EVRING_LEN * XHCI_TRB_SIZE; + seg = dynalloc_memalign(size, 64); + memset(seg, 0, size); + + /* Set the size of the event ring segment table */ + erst_size = XHCI_BASE_OFF(runtime, 0x28); + *erst_size = 1; + + /* Setup the event ring segment */ + memset(seg, 0, size); + seg->base = VIRT_TO_PHYS(seg); + seg->size = XHCI_EVRING_LEN; + + /* Setup the event ring dequeue pointer */ + erdp = XHCI_BASE_OFF(runtime, 0x38); + *erdp = seg->base; + + /* Point ERSTBA to our event ring segment */ + erstba = XHCI_BASE_OFF(runtime, 0x30); + *erstba = VIRT_TO_PHYS(seg); + + hc->event_ring = PHYS_TO_VIRT(seg->base); +} + static int xhci_init_hc(struct xhci_hc *hc) { @@ -412,8 +449,8 @@ xhci_init_hc(struct xhci_hc *hc) /* Allocate resources and tell the HC about them */ opregs->dcbaa_ptr = xhci_alloc_dcbaa(hc); xhci_init_scratchpads(hc); + xhci_init_evring(hc); opregs->cmd_ring = xhci_alloc_cmdring(hc); - xhci_set_erst_base(hc, xhci_alloc_evring(hc)); /* We're ready, start up the HC and ports */ xhci_start_hc(hc); -- cgit v1.2.3