xHCI
struct xhci_cap_regs { uint8_t cap_length; uint8_t reserved; uint16_t hci_version; uint32_t hcs_params1; uint32_t hcs_params2; uint32_t hcs_params3; uint32_t hcc_params1; uint32_t dboff; uint32_t rtsoff; uint32_t hcc_params2;};struct xhci_port_regs { uint32_t portsc; uint32_t portpmsc; uint32_t portli; uint32_t portct;};struct xhci_usbcmd { union { uint32_t raw; struct { uint32_t run_stop; uint32_t host_controller_reset; uint32_t interrupter_enable; uint32_t host_system_error_en; uint32_t reserved0; uint32_t light_host_controller_reset; uint32_t controller_save_state; uint32_t controller_restore_state; uint32_t enable_wrap_event; uint32_t enable_u3_mf_index; uint32_t reserved1; uint32_t cem_enable; uint32_t extended_tbc_enable; uint32_t extended_tbc_trb_status_enable; uint32_t vtio_enable; uint32_t reserved2; }; };};struct xhci_slot_ctx { uint32_t route_string; uint32_t speed; uint32_t reserved0; uint32_t mtt; uint32_t hub; uint32_t context_entries; uint32_t max_exit_latency; uint32_t root_hub_port; uint32_t num_ports; uint32_t parent_hub_slot_id; uint32_t parent_port_number; uint32_t parent_think_time; uint32_t reserved1; uint32_t interrupter_target; uint32_t usb_device_address; uint32_t reserved2; uint32_t slot_state; uint32_t reserved3[4];};struct xhci_ep_ctx { uint32_t ep_state; uint32_t reserved1; uint32_t mult; uint32_t max_pstreams; uint32_t lsa; uint32_t interval; uint32_t max_esit_payload_hi; uint32_t reserved2; uint32_t error_count; uint32_t ep_type; uint32_t reserved3; uint32_t host_initiate_disable; uint32_t max_burst_size; uint32_t max_packet_size; union { uint64_t dequeue_ptr_raw; struct { uint32_t dcs; uint32_t reserved4; uint64_t dequeue_ptr; }; }; uint32_t average_trb_length; uint32_t max_esit_payload_lo; uint32_t reserved5[3];};struct xhci_input_ctrl_ctx { uint32_t drop_flags; uint32_t add_flags; uint32_t reserved[5]; uint32_t config; uint32_t interface_num; uint32_t alternate_setting; uint32_t reserved1;};struct xhci_input_ctx { struct xhci_input_ctrl_ctx ctrl_ctx; struct xhci_slot_ctx slot_ctx; struct xhci_ep_ctx ep_ctx[31];};struct xhci_input_ctx referenced types:
struct xhci_device_ctx { struct xhci_slot_ctx slot_ctx; struct xhci_ep_ctx ep_ctx[32];};struct xhci_device_ctx referenced types:
struct xhci_op_regs { struct xhci_usbcmd usbcmd; uint32_t usbsts; uint32_t pagesize; uint32_t reserved[2]; uint32_t dnctrl; uint64_t crcr; uint32_t reserved2[4]; uint64_t dcbaap; uint32_t config; uint32_t reserved3[241]; struct xhci_port_regs regs[];};struct xhci_op_regs referenced types:
struct xhci_trb { uint64_t parameter; uint32_t status; uint32_t control;};struct xhci_ring { struct xhci_trb *trbs; uint64_t phys; uint32_t enqueue_index; uint32_t dequeue_index; uint8_t cycle; uint32_t size; size_t outgoing;};struct xhci_ring referenced types:
struct xhci_erst_entry { uint64_t ring_segment_base; uint32_t ring_segment_size; uint32_t reserved;};struct xhci_interrupter_regs { uint32_t iman; uint32_t imod; uint32_t erstsz; uint32_t reserved; uint64_t erstba; uint64_t erdp;};struct xhci_dcbaa { uint64_t ptrs[256];};struct xhci_ext_cap { uint8_t cap_id; uint8_t next; uint16_t cap_specific;};struct xhci_slot { enum xhci_slot_state state; struct xhci_device *dev; struct xhci_ring *ep_rings[32]; uint8_t slot_id; refcount_t refcount; struct xhci_port *port; struct usb_device *udev;};struct xhci_slot referenced types:
enum xhci_slot_statestruct xhci_devicestruct xhci_ringrefcount_tstruct xhci_portstruct usb_device
struct xhci_port { struct spinlock update_lock; uint8_t port_id; struct xhci_slot *slot; uint8_t speed; bool usb3; uint64_t generation; enum xhci_port_state state; struct xhci_device *dev;};struct xhci_port referenced types:
struct xhci_device { uint8_t irq; struct pci_device *pci; struct xhci_input_ctx *input_ctx; struct xhci_cap_regs *cap_regs; struct xhci_op_regs *op_regs; struct xhci_interrupter_regs *intr_regs; struct xhci_dcbaa *dcbaa; struct xhci_ring *event_ring; struct xhci_ring *cmd_ring; struct xhci_erst_entry *erst; struct xhci_port_regs *port_regs; uint64_t ports; struct xhci_slot slots[XHCI_SLOT_COUNT]; struct xhci_port port_info[XHCI_PORT_COUNT]; struct list_head requests[XHCI_REQ_LIST_MAX]; size_t num_devices; struct list_head devices; struct spinlock lock; struct semaphore sem; struct semaphore port_disconnect; struct semaphore port_connect; struct usb_controller *controller; atomic_bool worker_waiting;};struct xhci_device referenced types:
struct pci_devicestruct xhci_input_ctxstruct xhci_cap_regsstruct xhci_op_regsstruct xhci_interrupter_regsstruct xhci_dcbaastruct xhci_ringstruct xhci_erst_entrystruct xhci_port_regsstruct xhci_slotstruct xhci_portstruct list_headstruct spinlockstruct semaphorestruct usb_controller
struct xhci_command { struct xhci_ring *ring; struct xhci_slot *slot; uint32_t ep_id; size_t num_trbs; void (*emit)(struct xhci_command *cmd, struct xhci_ring *ring); struct xhci_request *request; void *private;};struct xhci_command referenced types:
struct xhci_request { enum xhci_request_list list_owner; struct usb_request *urb; struct xhci_command *command; bool slot_reset; struct xhci_trb *last_trb; uint64_t trb_phys; uint8_t port; uint8_t completion_code; uint64_t return_parameter; uint32_t return_status; uint32_t return_control; uint64_t generation; enum xhci_request_status status; struct list_head list; void (*callback)(struct xhci_device *, struct xhci_request *); void *private;};struct xhci_request referenced types:
enum xhci_request_liststruct usb_requeststruct xhci_commandstruct xhci_trbenum xhci_request_statusstruct list_head
struct xhci_return { uint32_t control; uint32_t status;};enum xhci_slot_state { XHCI_SLOT_STATE_UNDEF, XHCI_SLOT_STATE_ENABLED, XHCI_SLOT_STATE_DISCONNECTING, XHCI_SLOT_STATE_DISCONNECTED,};enum xhci_port_state { XHCI_PORT_STATE_UNDEF, XHCI_PORT_STATE_CONNECTING, XHCI_PORT_STATE_CONNECTED, XHCI_PORT_STATE_DISCONNECTING, XHCI_PORT_STATE_DISCONNECTED,};enum xhci_request_status { XHCI_REQUEST_SENDING, XHCI_REQUEST_OK, XHCI_REQUEST_CANCELLED, XHCI_REQUEST_DISCONNECT, XHCI_REQUEST_ERR,};enum xhci_request_list { XHCI_REQ_LIST_NONE, XHCI_REQ_LIST_OUTGOING, XHCI_REQ_LIST_WAITING, XHCI_REQ_LIST_PROCESSED, XHCI_REQ_LIST_MAX,};char xhci_slot_state_str(enum xhci_slot_state s);xhci_slot_state_str referenced types:
char xhci_port_state_str(enum xhci_port_state s);xhci_port_state_str referenced types:
Defines
Section titled “Defines”#define XHCI_DEVICE_TIMEOUT 1000#define TRB_RING_SIZE 256#define XHCI_PORT_COUNT 64#define XHCI_SLOT_COUNT 255#define XHCI_INPUT_CTX_ADD_FLAGS ((1 << 0) | (1 << 1))#define XHCI_SETUP_TRANSFER_TYPE_NONE 0#define XHCI_SETUP_TRANSFER_TYPE_OUT 2#define XHCI_SETUP_TRANSFER_TYPE_IN 3#define XHCI_USBSTS_HCH 1 /* HC halted */#define XHCI_USBSTS_HSE (1 << 2) /* host system error */#define XHCI_USBSTS_EI (1 << 3) /* event interrupt */#define XHCI_USBSTS_PCD (1 << 4) /* port change detect */#define XHCI_IMAN_MASK 0x2#define XHCI_IMAN_INT_PENDING 0x1#define XHCI_IMAN_INT_ENABLE 0x2#define XHCI_ENDPOINT_TYPE_INVAL 0#define XHCI_ENDPOINT_TYPE_ISOCH_OUT 1#define XHCI_ENDPOINT_TYPE_BULK_OUT 2#define XHCI_ENDPOINT_TYPE_INTERRUPT_OUT 3#define XHCI_ENDPOINT_TYPE_CONTROL_BI 4#define XHCI_ENDPOINT_TYPE_ISOCH_IN 5#define XHCI_ENDPOINT_TYPE_BULK_IN 6#define XHCI_ENDPOINT_TYPE_INTERRUPT_IN 7#define XHCI_EXT_CAP_ID_LEGACY_SUPPORT 1#define XHCI_EXT_CAP_ID_USB 2#define TRB_TYPE_RESERVED 0x00#define TRB_TYPE_NORMAL 0x01#define TRB_TYPE_SETUP_STAGE 0x02#define TRB_TYPE_DATA_STAGE 0x03#define TRB_TYPE_STATUS_STAGE 0x04#define TRB_TYPE_ISOCH 0x05#define TRB_TYPE_LINK 0x06#define TRB_TYPE_EVENT_DATA 0x07#define TRB_TYPE_NO_OP 0x08#define TRB_TYPE_NO_OP_COMMAND 0x8#define TRB_TYPE_ENABLE_SLOT 0x09#define TRB_TYPE_DISABLE_SLOT 0x0A#define TRB_TYPE_ADDRESS_DEVICE 0x0B#define TRB_TYPE_CONFIGURE_ENDPOINT 0x0C#define TRB_TYPE_EVALUATE_CONTEXT 0x0D#define TRB_TYPE_RESET_ENDPOINT 0x0E#define TRB_TYPE_STOP_ENDPOINT 0x0F#define TRB_TYPE_SET_TR_DEQUEUE_POINTER 0x10#define TRB_TYPE_RESET_DEVICE 0x11#define TRB_TYPE_FORCE_EVENT 0x12#define TRB_TYPE_NEGOTIATE_BW 0x13#define TRB_TYPE_SET_LATENCY_TOLERANCE 0x14#define TRB_TYPE_GET_PORT_BANDWIDTH 0x15#define TRB_TYPE_FORCE_HEADER 0x16#define TRB_TYPE_NO_OP_2_COMMAND 0x17#define TRB_TYPE_TRANSFER_EVENT 0x20#define TRB_TYPE_COMMAND_COMPLETION 0x21#define TRB_TYPE_PORT_STATUS_CHANGE 0x22#define TRB_TYPE_BANDWIDTH_REQUEST 0x23#define TRB_TYPE_DOORBELL_EVENT 0x24#define TRB_TYPE_HOST_CONTROLLER_EVENT 0x25#define TRB_TYPE_DEVICE_NOTIFICATION 0x26#define TRB_TYPE_MFINDEX_WRAP 0x27#define TRB_FIELD(val, lo, hi) BIT_RANGE(val, lo, hi)#define TRB_TYPE(ctrl) TRB_FIELD(ctrl, 10, 15)#define TRB_SLOT(ctrl) TRB_FIELD(ctrl, 24, 31)#define TRB_EP(ctrl) TRB_FIELD(ctrl, 16, 23)#define TRB_CC(status) TRB_FIELD(status, 24, 31)#define TRB_PORT(parameter) TRB_FIELD(parameter, 24, 31)#define TRB_SET_TYPE(val) (((val) & 0x3F) << 10)#define TRB_SET_CYCLE(val) (((val) & 1))#define TRB_SET_INTERRUPTER_TARGET(target) ((target) >> 21)#define TRB_CYCLE_BIT (1 << 0)#define TRB_ENT_BIT (1 << 1) // Evaluate Next TRB#define TRB_ISP_BIT (1 << 2) // Interrupt on Short Packet#define TRB_NS_BIT (1 << 3) // No Snoop#define TRB_CH_BIT (1 << 4) // Chain#define TRB_IOC_BIT (1 << 5) // Interrupt On Completion#define TRB_IDT_BIT (1 << 6) // Immediate Data#define TRB_BEI_BIT (1 << 9) // Block Event Interrupt (ISO)#define TRB_TOGGLE_CYCLE_BIT (1 << 1)#define TRB_TYPE_SHIFT 10#define TRB_SET_SLOT_ID(id) (((id) & 0xFF) << 24)#define PORTSC_CCS (1 << 0) // Current Connect Status#define PORTSC_PED (1 << 1) // Port Enabled/Disabled#define PORTSC_OCA (1 << 3) // Over-Current Active#define PORTSC_RESET (1 << 4) // Port Reset#define PORTSC_PR (1 << 4) // Port Reset#define PORTSC_PLSE (1 << 5) // Port Link State Enable#define PORTSC_PRES (1 << 6) // Port Resume#define PORTSC_PP (1 << 9) // Port Power#define PORTSC_SPEED_MASK (0xF << 10) // Bits 10–13: Port Speed#define PORTSC_SPEED_SHIFT 10#define PORTSC_PLS_SHIFT 5#define PORTSC_PLS_MASK (0xF << 5)#define PORTSC_LWS (1 << 16) // Link Write Strobe#define PORTSC_CSC (1 << 17) // Connect Status Change#define PORTSC_PEC (1 << 18) // Port Enable/Disable Change#define PORTSC_WRC (1 << 19) // Warm Port Reset Change#define PORTSC_OCC (1 << 20) // Over-current Change#define PORTSC_PRC (1 << 21) // Port Reset Change#define PORTSC_PLC (1 << 22) // Port Link State Change#define PORTSC_CEC (1 << 23) // Port Config Error Change#define PORTSC_PLS_POLLING 7#define PORTSC_PLS_U0 0#define PORTSC_PLS_U2 2#define PORTSC_PLS_U3 3#define PORTSC_PLS_RXDETECT 5#define PORTSC_IND (1 << 24) // Port Indicator Control#define PORTSC_LWS_BIT (1 << 16) // Link Write Strobe#define PORTSC_DR (1 << 30) // Device Removable#define PORTSC_WPR (1u << 31) // Warm Port Reset#define PORT_SPEED_FULL 1 // USB 1.1 Full Speed#define PORT_SPEED_LOW 2 // USB 1.1 Low Speed#define PORT_SPEED_HIGH 3 // USB 2.0 High Speed#define PORT_SPEED_SUPER 4 // USB 3.0 SuperSpeed#define PORT_SPEED_SUPER_PLUS 5 // USB 3.1 Gen2 (SuperSpeed+)#define CC_SUCCESS 1#define CC_DATA_BUFFER_ERROR 2#define CC_BABBLE_DETECTED 3#define CC_USB_TRANSACTION_ERROR 4#define CC_TRB_ERROR 5#define CC_STALL_ERROR 6#define CC_RESOURCE_ERROR 7#define CC_BANDWIDTH_ERROR 8#define CC_NO_SLOTS_AVAILABLE 9#define CC_INVALID_STREAM_TYPE 10#define CC_SLOT_NOT_ENABLED_ERROR 11#define CC_ENDPOINT_NOT_ENABLED 12#define CC_SHORT_PACKET 13#define CC_RING_UNDERRUN 14#define CC_RING_OVERRUN 15#define CC_VF_EVENT_RING_FULL_ERROR 16#define CC_PARAMETER_ERROR 17#define CC_BANDWIDTH_OVERRUN_ERROR 18#define CC_CONTEXT_STATE_ERROR 19#define CC_NO_PING_RESPONSE_ERROR 20#define CC_EVENT_RING_FULL 21#define CC_INCOMPATIBLE_DEVICE 22#define CC_MISSED_SERVICE 23#define CC_COMMAND_RING_STOPPED 24#define CC_COMMAND_ABORTED 25#define CC_STOPPED 26#define CC_STOPPED_LEN_INVALID 27#define CC_STOPPED_SHORT_PACKET 28#define CC_MAX_EXIT_LATENCY_TOO_LARGE 29#define xhci_log(log_level, fmt, ...) \ log(LOG_SITE(xhci), LOG_HANDLE(xhci), log_level, fmt, ##__VA_ARGS__)#define xhci_warn(fmt, ...) xhci_log(LOG_WARN, fmt, ##__VA_ARGS__)#define xhci_error(fmt, ...) xhci_log(LOG_ERROR, fmt, ##__VA_ARGS__)#define xhci_info(fmt, ...) xhci_log(LOG_INFO, fmt, ##__VA_ARGS__)#define xhci_debug(fmt, ...) xhci_log(LOG_DEBUG, fmt, ##__VA_ARGS__)#define xhci_trace(fmt, ...) xhci_log(LOG_TRACE, fmt, ##__VA_ARGS__)#define XHCI_ERDP_EHB_BIT (1 << 3)