#ifndef _KERNEL_DEVICE_XHCI_H #define _KERNEL_DEVICE_XHCI_H #include #include #include #include #include #include #include /* event ring segment table entry */ struct xhci_erst_entry { uint64_t ptr; uint32_t size; uint32_t _rsvd; } PACKED; /* transfer request block */ struct xhci_trb { uint64_t param; uint32_t status; uint32_t ctrl; } PACKED; struct xhci_ctx32 { uint32_t dw[8]; } PACKED; struct xhci_ctx64 { uint32_t dw[16]; } PACKED; struct xhci_input_ctx32 { struct xhci_ctx32 ctrl; struct xhci_ctx32 slot; struct xhci_ctx32 endpoints[31]; }; struct xhci_input_ctx64 { struct xhci_ctx64 ctrl; struct xhci_ctx64 slot; struct xhci_ctx64 endpoints[31]; }; struct xhci_init { uintptr_t xhci_mmio_base; bool irqs_support; uint8_t irq; }; #define XHCI_PORT_USB2 0 #define XHCI_PORT_USB3 1 struct xhci_port { struct list_node_link ports_link; uint8_t port_value; int type; }; struct xhci_pdevice { struct list_node_link pdevices_link; uint8_t port_value; int slot_id; struct xhci_trb* endpoint0_ring; uintptr_t endpoint0_ring_phys; uint32_t endpoint0_ring_idx; uint32_t endpoint0_ring_size; uint8_t endpoint0_cycle_bit; }; struct xhci_port_status_change { struct list_node_link port_changes_link; uint8_t port; uint32_t portsc; }; struct xhci { struct device* device; bool irqs_support; uint8_t irq; uintptr_t xhci_mmio_base; uintptr_t xhci_oper_base; uintptr_t xhci_runtime_base; uintptr_t xhci_doorbell_base; uintptr_t* xhci_dcbaa; uintptr_t xhci_dcbaa_phys; uint32_t max_scratchpad; uintptr_t* scratchpads; uintptr_t scratchpads_phys; uint32_t max_slots; struct xhci_trb* cmd_ring; uintptr_t cmd_ring_phys; uint32_t cmd_ring_idx; uint32_t cmd_ring_size; uint8_t cmd_cycle_bit; struct xhci_trb* event_ring; uintptr_t event_ring_phys; uint32_t event_ring_idx; uint32_t event_ring_size; uint8_t event_cycle_bit; struct xhci_erst_entry* erst; uintptr_t erst_phys; size_t xhci_ctx_size; struct list_node_link* xhci_ports; struct list_node_link* xhci_pdevices; atomic_bool pending; uint8_t last_slot_id; uint8_t last_cmpl_code; struct list_node_link* port_changes; spin_lock_t setup_lock; }; DEFINE_DEVICE_INIT (xhci_init); DEFINE_DEVICE_FINI (xhci_fini); DEFINE_DEVICE_OP (xhci_poll_driver); #endif // _KERNEL_DEVICE_XHCI_H