1/* @title: xHCI */
2#pragma once
3#include <compiler.h>
4#include <log.h>
5#include <math/bit.h>
6#include <stdbool.h>
7#include <stdint.h>
8#include <structures/list.h>
9#include <structures/locked_list.h>
10#include <sync/semaphore.h>
11#include <thread/workqueue.h>
12#include <types/types.h>
13struct usb_controller;
14struct usb_packet;
15struct xhci_request;
16struct usb_endpoint;
17struct pci_device;
18
19#define XHCI_DEVICE_TIMEOUT 1000
20#define TRB_RING_SIZE 256
21#define XHCI_PORT_COUNT 64
22#define XHCI_SLOT_COUNT 255
23
24#define XHCI_INPUT_CTX_ADD_FLAGS ((1 << 0) | (1 << 1))
25
26#define XHCI_SETUP_TRANSFER_TYPE_NONE 0
27#define XHCI_SETUP_TRANSFER_TYPE_OUT 2
28#define XHCI_SETUP_TRANSFER_TYPE_IN 3
29
30#define XHCI_USBSTS_HCH 1 /* HC halted */
31#define XHCI_USBSTS_HSE (1 << 2) /* host system error */
32#define XHCI_USBSTS_EI (1 << 3) /* event interrupt */
33#define XHCI_USBSTS_PCD (1 << 4) /* port change detect */
34#define XHCI_IMAN_MASK 0x2
35#define XHCI_IMAN_INT_PENDING 0x1
36#define XHCI_IMAN_INT_ENABLE 0x2
37
38#define XHCI_ENDPOINT_TYPE_INVAL 0
39#define XHCI_ENDPOINT_TYPE_ISOCH_OUT 1
40#define XHCI_ENDPOINT_TYPE_BULK_OUT 2
41#define XHCI_ENDPOINT_TYPE_INTERRUPT_OUT 3
42#define XHCI_ENDPOINT_TYPE_CONTROL_BI 4
43#define XHCI_ENDPOINT_TYPE_ISOCH_IN 5
44#define XHCI_ENDPOINT_TYPE_BULK_IN 6
45#define XHCI_ENDPOINT_TYPE_INTERRUPT_IN 7
46
47// NOTE: In scatter gathers, the first TRD must NOT point to a page-aligned
48// boundary. Following TRDs must point to page-aligned boundaries.
49
50#define XHCI_EXT_CAP_ID_LEGACY_SUPPORT 1
51#define XHCI_EXT_CAP_ID_USB 2
52
53// TRB Types (bits 10–15 in control word)
54#define TRB_TYPE_RESERVED 0x00
55#define TRB_TYPE_NORMAL 0x01
56#define TRB_TYPE_SETUP_STAGE 0x02
57#define TRB_TYPE_DATA_STAGE 0x03
58#define TRB_TYPE_STATUS_STAGE 0x04
59#define TRB_TYPE_ISOCH 0x05
60#define TRB_TYPE_LINK 0x06
61#define TRB_TYPE_EVENT_DATA 0x07
62#define TRB_TYPE_NO_OP 0x08
63
64// Command TRBs
65#define TRB_TYPE_NO_OP_COMMAND 0x8
66#define TRB_TYPE_ENABLE_SLOT 0x09
67#define TRB_TYPE_DISABLE_SLOT 0x0A
68#define TRB_TYPE_ADDRESS_DEVICE 0x0B
69#define TRB_TYPE_CONFIGURE_ENDPOINT 0x0C
70#define TRB_TYPE_EVALUATE_CONTEXT 0x0D
71#define TRB_TYPE_RESET_ENDPOINT 0x0E
72#define TRB_TYPE_STOP_ENDPOINT 0x0F
73#define TRB_TYPE_SET_TR_DEQUEUE_POINTER 0x10
74#define TRB_TYPE_RESET_DEVICE 0x11
75#define TRB_TYPE_FORCE_EVENT 0x12
76#define TRB_TYPE_NEGOTIATE_BW 0x13
77#define TRB_TYPE_SET_LATENCY_TOLERANCE 0x14
78#define TRB_TYPE_GET_PORT_BANDWIDTH 0x15
79#define TRB_TYPE_FORCE_HEADER 0x16
80#define TRB_TYPE_NO_OP_2_COMMAND 0x17
81
82// Event TRBs
83#define TRB_TYPE_TRANSFER_EVENT 0x20
84#define TRB_TYPE_COMMAND_COMPLETION 0x21
85#define TRB_TYPE_PORT_STATUS_CHANGE 0x22
86#define TRB_TYPE_BANDWIDTH_REQUEST 0x23
87#define TRB_TYPE_DOORBELL_EVENT 0x24
88#define TRB_TYPE_HOST_CONTROLLER_EVENT 0x25
89#define TRB_TYPE_DEVICE_NOTIFICATION 0x26
90#define TRB_TYPE_MFINDEX_WRAP 0x27
91
92#define TRB_FIELD(val, lo, hi) BIT_RANGE(val, lo, hi)
93
94#define TRB_TYPE(ctrl) TRB_FIELD(ctrl, 10, 15)
95#define TRB_SLOT(ctrl) TRB_FIELD(ctrl, 24, 31)
96#define TRB_EP(ctrl) TRB_FIELD(ctrl, 16, 23)
97
98#define TRB_CC(status) TRB_FIELD(status, 24, 31)
99#define TRB_PORT(parameter) TRB_FIELD(parameter, 24, 31)
100
101#define TRB_SET_TYPE(val) (((val) & 0x3F) << 10)
102#define TRB_SET_CYCLE(val) (((val) & 1))
103#define TRB_SET_INTERRUPTER_TARGET(target) ((target) >> 21)
104
105#define TRB_CYCLE_BIT (1 << 0)
106#define TRB_ENT_BIT (1 << 1) // Evaluate Next TRB
107#define TRB_ISP_BIT (1 << 2) // Interrupt on Short Packet
108#define TRB_NS_BIT (1 << 3) // No Snoop
109#define TRB_CH_BIT (1 << 4) // Chain
110#define TRB_IOC_BIT (1 << 5) // Interrupt On Completion
111#define TRB_IDT_BIT (1 << 6) // Immediate Data
112#define TRB_BEI_BIT (1 << 9) // Block Event Interrupt (ISO)
113#define TRB_TOGGLE_CYCLE_BIT (1 << 1)
114#define TRB_TYPE_SHIFT 10
115
116#define TRB_SET_SLOT_ID(id) (((id) & 0xFF) << 24)
117
118// Bit definitions for XHCI PORTSC register
119#define PORTSC_CCS (1 << 0) // Current Connect Status
120#define PORTSC_PED (1 << 1) // Port Enabled/Disabled
121#define PORTSC_OCA (1 << 3) // Over-Current Active
122#define PORTSC_RESET (1 << 4) // Port Reset
123#define PORTSC_PR (1 << 4) // Port Reset
124#define PORTSC_PLSE (1 << 5) // Port Link State Enable
125#define PORTSC_PRES (1 << 6) // Port Resume
126#define PORTSC_PP (1 << 9) // Port Power
127#define PORTSC_SPEED_MASK (0xF << 10) // Bits 10–13: Port Speed
128#define PORTSC_SPEED_SHIFT 10
129
130#define PORTSC_PLS_SHIFT 5
131#define PORTSC_PLS_MASK (0xF << 5)
132#define PORTSC_LWS (1 << 16) // Link Write Strobe
133#define PORTSC_CSC (1 << 17) // Connect Status Change
134#define PORTSC_PEC (1 << 18) // Port Enable/Disable Change
135#define PORTSC_WRC (1 << 19) // Warm Port Reset Change
136#define PORTSC_OCC (1 << 20) // Over-current Change
137#define PORTSC_PRC (1 << 21) // Port Reset Change
138#define PORTSC_PLC (1 << 22) // Port Link State Change
139#define PORTSC_CEC (1 << 23) // Port Config Error Change
140
141#define PORTSC_PLS_POLLING 7
142#define PORTSC_PLS_U0 0
143#define PORTSC_PLS_U2 2
144#define PORTSC_PLS_U3 3
145#define PORTSC_PLS_RXDETECT 5
146
147#define PORTSC_IND (1 << 24) // Port Indicator Control
148#define PORTSC_LWS_BIT (1 << 16) // Link Write Strobe
149#define PORTSC_DR (1 << 30) // Device Removable
150#define PORTSC_WPR (1u << 31) // Warm Port Reset
151
152#define PORT_SPEED_FULL 1 // USB 1.1 Full Speed
153#define PORT_SPEED_LOW 2 // USB 1.1 Low Speed
154#define PORT_SPEED_HIGH 3 // USB 2.0 High Speed
155#define PORT_SPEED_SUPER 4 // USB 3.0 SuperSpeed
156#define PORT_SPEED_SUPER_PLUS 5 // USB 3.1 Gen2 (SuperSpeed+)
157
158#define CC_SUCCESS 1
159#define CC_DATA_BUFFER_ERROR 2
160#define CC_BABBLE_DETECTED 3
161#define CC_USB_TRANSACTION_ERROR 4
162#define CC_TRB_ERROR 5
163#define CC_STALL_ERROR 6
164#define CC_RESOURCE_ERROR 7
165#define CC_BANDWIDTH_ERROR 8
166#define CC_NO_SLOTS_AVAILABLE 9
167#define CC_INVALID_STREAM_TYPE 10
168#define CC_SLOT_NOT_ENABLED_ERROR 11
169#define CC_ENDPOINT_NOT_ENABLED 12
170#define CC_SHORT_PACKET 13
171#define CC_RING_UNDERRUN 14
172#define CC_RING_OVERRUN 15
173#define CC_VF_EVENT_RING_FULL_ERROR 16
174#define CC_PARAMETER_ERROR 17
175#define CC_BANDWIDTH_OVERRUN_ERROR 18
176#define CC_CONTEXT_STATE_ERROR 19
177#define CC_NO_PING_RESPONSE_ERROR 20
178#define CC_EVENT_RING_FULL 21
179#define CC_INCOMPATIBLE_DEVICE 22
180#define CC_MISSED_SERVICE 23
181#define CC_COMMAND_RING_STOPPED 24
182#define CC_COMMAND_ABORTED 25
183#define CC_STOPPED 26
184#define CC_STOPPED_LEN_INVALID 27
185#define CC_STOPPED_SHORT_PACKET 28
186#define CC_MAX_EXIT_LATENCY_TOO_LARGE 29
187
188LOG_HANDLE_EXTERN(xhci);
189LOG_SITE_EXTERN(xhci);
190#define xhci_log(log_level, fmt, ...) \
191 log(LOG_SITE(xhci), LOG_HANDLE(xhci), log_level, fmt, ##__VA_ARGS__)
192#define xhci_warn(fmt, ...) xhci_log(LOG_WARN, fmt, ##__VA_ARGS__)
193#define xhci_error(fmt, ...) xhci_log(LOG_ERROR, fmt, ##__VA_ARGS__)
194#define xhci_info(fmt, ...) xhci_log(LOG_INFO, fmt, ##__VA_ARGS__)
195#define xhci_debug(fmt, ...) xhci_log(LOG_DEBUG, fmt, ##__VA_ARGS__)
196#define xhci_trace(fmt, ...) xhci_log(LOG_TRACE, fmt, ##__VA_ARGS__)
197
198/*
199 * Lifetime invariant:
200 * - Slot refcount > 0 implies:
201 * - Slot is ENABLED or DISCONNECTING
202 * - Endpoint rings may exist
203 * - When slot refcount reaches 0:
204 * - Disable Slot has completed
205 * - No TRBs may be issued
206 * - All memory may be freed
207 */
208
209// 5.3: XHCI Capability Registers
210struct xhci_cap_regs {
211 uint8_t cap_length;
212 uint8_t reserved;
213 uint16_t hci_version;
214 uint32_t hcs_params1;
215 uint32_t hcs_params2;
216 uint32_t hcs_params3;
217 uint32_t hcc_params1;
218 uint32_t dboff;
219 uint32_t rtsoff;
220 uint32_t hcc_params2;
221} __packed;
222
223struct xhci_port_regs {
224 uint32_t portsc; // Port Status and Control (offset 0x00)
225 uint32_t portpmsc; // Port Power Management Status and Control (offset 0x04)
226 uint32_t portli; // Port Link Info (offset 0x08)
227 uint32_t portct; // Port Configuration Timeout (offset 0x0C)
228};
229
230struct xhci_usbcmd {
231 union {
232 uint32_t raw;
233 struct {
234 uint32_t run_stop : 1;
235 uint32_t host_controller_reset : 1;
236 uint32_t interrupter_enable : 1;
237 uint32_t host_system_error_en : 1;
238 uint32_t reserved0 : 3;
239 uint32_t light_host_controller_reset : 1;
240 uint32_t controller_save_state : 1;
241 uint32_t controller_restore_state : 1;
242
243 uint32_t enable_wrap_event : 1;
244 uint32_t enable_u3_mf_index : 1;
245 uint32_t reserved1 : 1;
246
247 uint32_t cem_enable : 1;
248 uint32_t extended_tbc_enable : 1;
249
250 uint32_t extended_tbc_trb_status_enable : 1;
251
252 uint32_t vtio_enable : 1;
253
254 uint32_t reserved2 : 15;
255 };
256 };
257} __packed;
258static_assert_struct_size_eq(xhci_usbcmd, sizeof(uint32_t));
259
260/* Page 444 */
261struct xhci_slot_ctx {
262 uint32_t route_string : 20; // Location in USB topology
263
264 uint32_t speed : 4; // Speed of the device
265
266 uint32_t reserved0 : 1;
267
268 uint32_t mtt : 1; /* Set to '1' by software
269 * if this is a high speed hub that
270 * supports multiple TTs*/
271
272 uint32_t hub : 1; /* Set to '1' by software
273 * if this is a USB hub, 0 if
274 * function */
275
276 uint32_t context_entries : 5; /* Index of the last
277 * valid endpoint context
278 * within this structure */
279
280 uint32_t max_exit_latency : 16; /* In microseconds,
281 * worst case time it takes
282 * to wake up all links
283 * in path to device*/
284
285 uint32_t root_hub_port : 8; /* Root hub port number used to
286 * access the USB device */
287
288 uint32_t num_ports : 8; /* If this is a hub,
289 * this is set by software to
290 * identify downstream ports
291 * supported by the hub */
292
293 uint32_t parent_hub_slot_id : 8; /* Slot ID of the
294 * parent high-speed hub */
295
296 uint32_t parent_port_number : 8; /* Port number of the
297 * parent high-speed hub */
298
299 uint32_t parent_think_time : 2; /* Think time of the
300 * parent high-speed hub */
301
302 uint32_t reserved1 : 4;
303
304 uint32_t interrupter_target : 10; /* Index of the interrupter to events
305 * generated by this slot */
306
307 uint32_t usb_device_address : 8; /* Address of USB device assigned by xHC */
308 uint32_t reserved2 : 19;
309 uint32_t slot_state : 5; /* 0 - disabled/enabled, 1 - default, 2 -
310 * addressed, 3 - configured, rest reserved*/
311 uint32_t reserved3[4];
312} __packed;
313static_assert_struct_size_eq(xhci_slot_ctx, 0x20);
314
315struct xhci_ep_ctx { // Refer to page 450 of the XHCI specification
316
317 /* DWORD 0 */
318 uint32_t ep_state : 3; /* The current operational state of the endpoint
319 * 0 - Disabled (non-operational)
320 * 1 - Running
321 * 2 - Halted
322 * 3 - Stopped
323 * 4 - Error - SW can manipulate the transfer ring
324 * 5-7 - Reserved
325 */
326
327 uint32_t reserved1 : 5;
328
329 uint32_t mult : 2; /* Maximum number of bursts in an interval
330 * that this endpoint supports.
331 * Zero-based value, 0-3 is 1-4 bursts
332 * 0 for all endpoint types except SS Isochronous
333 */
334
335 uint32_t max_pstreams : 5; /* Maximum Primary streams this endpoint
336 * supports. If this is '0', the TR
337 * dequeue pointer should point to a
338 * transfer ring.
339 * If this is > '0' the TR dequeue
340 * pointer points to a Primary Stream Context
341 * Array.
342 */
343
344 uint32_t lsa : 1; /* Linear Stream Array, identifies how
345 * an ID stream is interpreted
346 * '1' disables Secondary Stream Arrays
347 * Linear index into Primary Stream Array
348 * Valid values are MaxPstreams 1 - 15
349 */
350
351 uint32_t interval : 8; /* Period between consecutive requests
352 * to a USB endpoint, expressed in 125 microsecond
353 * increments. Interval of 0 means period of 125us.
354 * A value of 1 means a period of 250us, etc.
355 */
356
357 uint32_t max_esit_payload_hi : 8; /* Max Endpoint Service Time
358 * Interval Payload High
359 * If LEC is '1' this is the high order
360 * 8 bits of the max ESIT payload value.
361 * If this is '0', then this is reserved
362 */
363
364 /* DWORD 1 */
365 uint32_t reserved2 : 1;
366
367 uint32_t error_count : 2; /* Two bit down count, identifying the number
368 * of consecutive USB-bus errors allowed
369 * while executing a TD.
370 */
371
372 uint32_t ep_type : 3; /* Endpoint type
373 * 0 - Not valid
374 * 1 - Isochronous Out
375 * 2 - Bulk Out
376 * 3 - Interrupt Out
377 * 4 - Control Bidirectional
378 * 5 - Isochronous In
379 * 6 - Bulk In
380 * 7 - Interrupt In
381 */
382
383 uint32_t reserved3 : 1;
384 uint32_t host_initiate_disable : 1; /* The field affects Stream enabled
385 * endpoints allowing the HI stream
386 * selection feature to be disabled for
387 * the endpoint. Setting to '1' disables
388 * the HI stream selection feature. '0'
389 * enables normal stream operation
390 */
391
392 uint32_t max_burst_size : 8; /* Maximum number of consecutive USB
393 * transactions per scheduling opportunity.
394 * 0-based, 0-15 means 1-16
395 */
396
397 uint32_t max_packet_size : 16; /* Max packet size in bytes that this
398 * endpoint is capable of sending or
399 * receiving when configured.
400 */
401
402 /* DWORD 2 */
403 union {
404 uint64_t dequeue_ptr_raw;
405 struct {
406 uint32_t dcs : 1; /* Dequeue cycle state - value of the xHC CCS
407 * (Consumer Cycle State) flag for the TRB
408 * referenced by the TR Dequeue pointer.
409 * '0' if `max_pstreams` > '0'
410 */
411
412 uint32_t reserved4 : 3;
413
414 uint64_t dequeue_ptr : 60; /* dequeue pointer
415 * MUST be aligned to 16 BYTE BOUNDARY
416 */
417 };
418 };
419
420 /* DWORD 4 */
421 uint32_t average_trb_length : 16; /* Average length of TRBs executed
422 * by this endpoint. Must be > '0'
423 */
424
425 uint32_t max_esit_payload_lo : 16; /* Low order 16 bits of
426 * max ESIT payload.
427 * Represends the total
428 * number of bytes
429 * this endpoint will
430 * transfer during an ESIT
431 */
432 uint32_t reserved5[3];
433} __packed;
434static_assert_struct_size_eq(xhci_ep_ctx, 0x20);
435
436struct xhci_input_ctrl_ctx { // Refer to page 461 of the XHCI specification
437
438 uint32_t drop_flags; /* Single bitfields to identify which
439 * device context data structs
440 * should be disabled by command.
441 * '1' disables the respective EP CTX.
442 *
443 * First two bits reserved
444 */
445
446 uint32_t add_flags; /* Single bitfields to identify
447 * which device CTX data structures
448 * should be evaluated or enabled
449 * by command. '1' enables the respective
450 * CTX
451 */
452
453 uint32_t reserved[5];
454
455 uint32_t config : 8; /* If CIC = '1' and CIE = '1', and this input CTX
456 * is associated with a Configure Endpoint command,
457 * this field contains the value
458 * of the Standard Configuration Descriptor
459 * bConfiguration field associated with this command.
460 * Otherwise, clear to '0'
461 */
462
463 uint32_t interface_num : 8; /* If CIC = '1' and CIE = '1',
464 * and this input CTX
465 * is associated with a
466 * Configure Endpoint
467 * Command, and this command
468 * was issued due to a
469 * SET_INTERFACE request,
470 * this contains the
471 * Standard Interface
472 * Descriptor bInterfaceNumber
473 * field associated with the command.
474 * Otherwise, clear to '0'
475 */
476
477 uint32_t alternate_setting : 8; /* If CIC = '1' and CIE = '1',
478 * and this input CTX is associated
479 * with a Configure Endpoint command,
480 * and the command was issued due
481 * to a SET_INTERFACE request,
482 * then this field contains
483 * the value of the Standard
484 * Interface Descriptor bAlternateSetting
485 * field associated with the
486 * command. Otherwise, clear to '0'.
487 */
488
489 uint32_t reserved1 : 8;
490} __packed;
491static_assert_struct_size_eq(xhci_input_ctrl_ctx, 0x20);
492
493struct xhci_input_ctx { // Refer to page 460 of the XHCI Spec
494 struct xhci_input_ctrl_ctx ctrl_ctx;
495 struct xhci_slot_ctx slot_ctx;
496 struct xhci_ep_ctx ep_ctx[31];
497} __packed;
498static_assert_struct_size_eq(xhci_input_ctx, 0x420);
499
500struct xhci_device_ctx {
501 struct xhci_slot_ctx slot_ctx;
502 struct xhci_ep_ctx ep_ctx[32]; // Endpoint 1–31 (ep0 separate)
503} __packed;
504
505struct xhci_op_regs {
506 struct xhci_usbcmd usbcmd;
507 uint32_t usbsts;
508 uint32_t pagesize;
509 uint32_t reserved[2];
510 uint32_t dnctrl;
511 uint64_t crcr;
512 uint32_t reserved2[4];
513 uint64_t dcbaap;
514 uint32_t config;
515 uint32_t reserved3[241];
516 struct xhci_port_regs regs[];
517};
518
519struct xhci_trb {
520 uint64_t parameter;
521 uint32_t status;
522 uint32_t control;
523} __packed;
524static_assert_struct_size_eq(xhci_trb, 0x10);
525
526struct xhci_ring {
527 struct xhci_trb *trbs; /* Virtual mapped TRB buffer */
528 uint64_t phys; /* Physical address of TRB buffer */
529 uint32_t enqueue_index; /* Next TRB to fill */
530 uint32_t dequeue_index; /* Point where controller sends back things */
531 uint8_t cycle; /* Cycle bit, toggles after ring wrap */
532 uint32_t size; /* Number of TRBs in ring */
533 size_t outgoing;
534};
535
536struct xhci_erst_entry {
537 uint64_t ring_segment_base;
538 uint32_t ring_segment_size;
539 uint32_t reserved;
540} __packed;
541
542#define XHCI_ERDP_EHB_BIT (1 << 3)
543
544/* Page 424 */
545struct xhci_interrupter_regs {
546 uint32_t iman; /* Interrupt management */
547 uint32_t imod; /* Interrupt moderation */
548 uint32_t erstsz; /* Event Ring Segment Table Size */
549 uint32_t reserved;
550 uint64_t erstba; /* Event Ring Segment Table Base Address */
551 uint64_t erdp;
552
553} __packed;
554
555struct xhci_dcbaa { // Device context base address array - check page 441
556 uint64_t ptrs[256];
557} __attribute__((aligned(64)));
558
559struct xhci_ext_cap {
560 uint8_t cap_id;
561 uint8_t next;
562 uint16_t cap_specific;
563};
564
565enum xhci_slot_state {
566 XHCI_SLOT_STATE_UNDEF,
567 XHCI_SLOT_STATE_ENABLED,
568 XHCI_SLOT_STATE_DISCONNECTING,
569 XHCI_SLOT_STATE_DISCONNECTED,
570};
571
572static inline const char *xhci_slot_state_str(enum xhci_slot_state s) {
573 switch (s) {
574 case XHCI_SLOT_STATE_UNDEF: return "SLOT UNDEF";
575 case XHCI_SLOT_STATE_ENABLED: return "SLOT ENABLED";
576 case XHCI_SLOT_STATE_DISCONNECTING: return "SLOT DISCONNECTING";
577 case XHCI_SLOT_STATE_DISCONNECTED: return "SLOT DISCONNECTED";
578 default: return "SLOT UNKNOWN";
579 }
580}
581
582enum xhci_port_state {
583 XHCI_PORT_STATE_UNDEF,
584 XHCI_PORT_STATE_CONNECTING,
585 XHCI_PORT_STATE_CONNECTED,
586 XHCI_PORT_STATE_DISCONNECTING,
587 XHCI_PORT_STATE_DISCONNECTED,
588};
589
590static inline const char *xhci_port_state_str(enum xhci_port_state s) {
591 switch (s) {
592 case XHCI_PORT_STATE_UNDEF: return "PORT UNDEF";
593 case XHCI_PORT_STATE_CONNECTING: return "PORT CONNECTING";
594 case XHCI_PORT_STATE_CONNECTED: return "PORT CONNECTED";
595 case XHCI_PORT_STATE_DISCONNECTING: return "PORT DISCONNECTING";
596 case XHCI_PORT_STATE_DISCONNECTED: return "PORT DISCONNECTED";
597 default: return "PORT UNKNOWN";
598 }
599}
600
601struct xhci_slot {
602 _Atomic enum xhci_slot_state state;
603 struct xhci_device *dev;
604 struct xhci_ring *ep_rings[32];
605 uint8_t slot_id; /* Just so everyone knows what slot we are */
606
607 /* As soon as this drops to zero we clear the ep_rings */
608 refcount_t refcount;
609 struct xhci_port *port;
610 struct usb_device *udev;
611};
612
613struct xhci_port {
614 /* Raw spinlock to protect against concurrent updating */
615 struct spinlock update_lock;
616 uint8_t port_id;
617 struct xhci_slot *slot;
618 uint8_t speed;
619 bool usb3;
620 uint64_t generation;
621 enum xhci_port_state state;
622 struct xhci_device *dev;
623};
624
625enum xhci_request_status {
626 /* The first 3 statuses indicate list state.
627 *
628 * OUTGOING requests have a TRB, and have rang the doorbell.
629 *
630 * WAITING requests cannot be currently satisfied because the
631 * command ring is full.
632 *
633 * PROCESSED requests have been handled by the ISR with a success state.
634 * Technically they run in the worker thread but the status is set from ISR.
635 *
636 * DISCONNECT requests occur when a port is disconnected and the request
637 * no longer goes anywhere (because the port is gone)
638 */
639 XHCI_REQUEST_SENDING,
640 XHCI_REQUEST_OK,
641 XHCI_REQUEST_CANCELLED,
642 XHCI_REQUEST_DISCONNECT,
643 XHCI_REQUEST_ERR,
644};
645
646enum xhci_request_list {
647 XHCI_REQ_LIST_NONE,
648 XHCI_REQ_LIST_OUTGOING,
649 XHCI_REQ_LIST_WAITING,
650 XHCI_REQ_LIST_PROCESSED,
651 XHCI_REQ_LIST_MAX,
652};
653
654enum xhci_request_command_type { /* Abstract command types, not 1:1 */
655 XHCI_CMD_TYPE_NONE,
656 XHCI_CMD_TYPE_ENABLE_SLOT,
657 XHCI_CMD_TYPE_DISABLE_SLOT,
658 XHCI_CMD_TYPE_ADDRESS_DEVICE,
659 XHCI_CMD_TYPE_CONFIGURE_ENDPOINT,
660 XHCI_CMD_TYPE_EVALUATE_CONTEXT,
661 XHCI_CMD_TYPE_RESET_ENDPOINT,
662 XHCI_CMD_TYPE_STOP_ENDPOINT,
663 XHCI_CMD_TYPE_SET_TR_DEQUEUE_POINTER,
664 XHCI_CMD_TYPE_RESET_DEVICE,
665 XHCI_CMD_TYPE_FORCE_EVENT,
666 XHCI_CMD_TYPE_INTERRUPT_TRANSFER,
667 XHCI_CMD_TYPE_CONTROL_TRANSFER,
668 XHCI_CMD_TYPE_NO_OP,
669 XHCI_CMD_TYPE_NORMAL, /* 'misc.' */
670};
671
672struct xhci_device {
673 irq_t irq; /* What IRQ line have we routed to this? */
674 struct pci_device *pci;
675 struct xhci_input_ctx *input_ctx;
676 struct xhci_cap_regs *cap_regs; /* Capability registers */
677 struct xhci_op_regs *op_regs; /* Operational registers */
678 struct xhci_interrupter_regs *intr_regs; /* Interrupter registers */
679
680 struct xhci_dcbaa *dcbaa;
681
682 struct xhci_ring *event_ring;
683 struct xhci_ring *cmd_ring;
684 struct xhci_erst_entry *erst;
685
686 struct xhci_port_regs *port_regs;
687 uint64_t ports;
688 struct xhci_slot slots[XHCI_SLOT_COUNT];
689 struct xhci_port port_info[XHCI_PORT_COUNT];
690
691 struct list_head requests[XHCI_REQ_LIST_MAX];
692
693 size_t num_devices;
694 struct list_head devices;
695 struct spinlock lock;
696 struct semaphore sem;
697 struct semaphore port_disconnect;
698 struct semaphore port_connect;
699 struct usb_controller *controller;
700 atomic_bool worker_waiting;
701};
702
703struct xhci_command {
704 struct xhci_ring *ring; /* what ring? */
705 struct xhci_slot *slot;
706 uint32_t ep_id;
707
708 size_t num_trbs;
709 void (*emit)(struct xhci_command *cmd, struct xhci_ring *ring);
710
711 struct xhci_request *request; /* associated request */
712 void *private;
713};
714
715struct xhci_request {
716 /* Tied back to the USB request */
717 enum xhci_request_command_type type;
718 enum xhci_request_list list_owner;
719 struct usb_request *urb;
720 struct xhci_command *command;
721
722 struct xhci_trb *last_trb;
723 uint64_t trb_phys;
724 uint8_t port; /* What port is this for? Used to match
725 * requests on disconnect */
726
727 /* the raw completion code for this request */
728 volatile uint8_t completion_code;
729 volatile uint64_t return_parameter;
730 volatile uint32_t return_status;
731 volatile uint32_t return_control;
732 uint64_t generation;
733
734 volatile enum xhci_request_status status;
735
736 struct list_head list;
737 void (*callback)(struct xhci_device *, struct xhci_request *);
738 void *private;
739};
740
741struct xhci_return {
742 uint32_t control;
743 uint32_t status;
744};
745
746static inline const char *
747xhci_request_command_type_str(enum xhci_request_command_type t) {
748 switch (t) {
749 case XHCI_CMD_TYPE_NONE: return "CMD NONE";
750 case XHCI_CMD_TYPE_ENABLE_SLOT: return "CMD ENABLE SLOT";
751 case XHCI_CMD_TYPE_DISABLE_SLOT: return "CMD DISABLE SLOT";
752 case XHCI_CMD_TYPE_ADDRESS_DEVICE: return "CMD ADDRESS DEVICE";
753 case XHCI_CMD_TYPE_CONFIGURE_ENDPOINT: return "CMD CONFIGURE ENDPOINT";
754 case XHCI_CMD_TYPE_EVALUATE_CONTEXT: return "CMD EVALUATE CONTEXT";
755 case XHCI_CMD_TYPE_RESET_ENDPOINT: return "CMD RESET ENDPOINT";
756 case XHCI_CMD_TYPE_STOP_ENDPOINT: return "CMD STOP ENDPOINT";
757 case XHCI_CMD_TYPE_SET_TR_DEQUEUE_POINTER: return "CMD SET TR DEQUEUE PTR";
758 case XHCI_CMD_TYPE_RESET_DEVICE: return "CMD RESET DEVICE";
759 case XHCI_CMD_TYPE_FORCE_EVENT: return "CMD FORCE EVENT";
760 case XHCI_CMD_TYPE_INTERRUPT_TRANSFER: return "CMD INTERRUPT TRANSFER";
761 case XHCI_CMD_TYPE_CONTROL_TRANSFER: return "CMD CONTROL TRANSFER";
762 case XHCI_CMD_TYPE_NO_OP: return "CMD NO OP";
763 case XHCI_CMD_TYPE_NORMAL: return "CMD NORMAL";
764 default: return "CMD UNKNOWN";
765 }
766}
767
768void xhci_init(uint8_t bus, uint8_t slot, uint8_t func, struct pci_device *dev);
769