⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/drivers/usb/
xhci.rs

1//! xHCI (eXtensible Host Controller Interface) USB 3.x driver
2//!
3//! Implements PCI discovery, MMIO register access, Transfer Ring Buffers
4//! (TRBs), Command/Event/Transfer rings, device slot management, port handling,
5//! USB descriptor parsing, and MSI-X interrupt stubs for xHCI controllers.
6//!
7//! xHCI PCI identification: class 0x0C, subclass 0x03, prog-if 0x30.
8
9#![allow(dead_code)]
10
11#[cfg(feature = "alloc")]
12extern crate alloc;
13
14#[cfg(feature = "alloc")]
15use alloc::vec::Vec;
16use core::sync::atomic::{AtomicBool, AtomicU32, Ordering};
17
18use crate::error::KernelError;
19
20// ---------------------------------------------------------------------------
21// Constants
22// ---------------------------------------------------------------------------
23
24/// PCI class code for Serial Bus Controller
25const PCI_CLASS_SERIAL_BUS: u8 = 0x0C;
26/// PCI subclass for USB controller
27const PCI_SUBCLASS_USB: u8 = 0x03;
28/// PCI prog-if for xHCI (USB 3.x)
29const PCI_PROGIF_XHCI: u8 = 0x30;
30
31/// Maximum number of device slots an xHCI controller can support (spec max 255)
32const MAX_DEVICE_SLOTS: usize = 256;
33/// Maximum number of ports an xHCI controller can expose
34const MAX_PORTS: usize = 256;
35/// Maximum number of interrupters
36const MAX_INTERRUPTERS: usize = 1024;
37
38/// Size of a single TRB in bytes (always 16 per xHCI spec)
39const TRB_SIZE: usize = 16;
40/// Number of TRBs in a ring segment (must be power of 2 for alignment)
41const RING_SEGMENT_TRBS: usize = 256;
42/// Ring segment size in bytes
43const RING_SEGMENT_SIZE: usize = RING_SEGMENT_TRBS * TRB_SIZE;
44
45// ---------------------------------------------------------------------------
46// USB Descriptor Type Constants (per USB 3.2 spec, Table 9-6)
47// ---------------------------------------------------------------------------
48
49/// USB descriptor type: Device
50const DESC_TYPE_DEVICE: u8 = 0x01;
51/// USB descriptor type: Configuration
52const DESC_TYPE_CONFIGURATION: u8 = 0x02;
53/// USB descriptor type: String
54const DESC_TYPE_STRING: u8 = 0x03;
55/// USB descriptor type: Interface
56const DESC_TYPE_INTERFACE: u8 = 0x04;
57/// USB descriptor type: Endpoint
58const DESC_TYPE_ENDPOINT: u8 = 0x05;
59/// USB descriptor type: Device Qualifier
60const DESC_TYPE_DEVICE_QUALIFIER: u8 = 0x06;
61/// USB descriptor type: BOS (Binary Object Store)
62const DESC_TYPE_BOS: u8 = 0x0F;
63/// USB descriptor type: SuperSpeed Endpoint Companion
64const DESC_TYPE_SS_EP_COMPANION: u8 = 0x30;
65
66// ---------------------------------------------------------------------------
67// USB Standard Request Codes (per USB 3.2 spec, Table 9-4)
68// ---------------------------------------------------------------------------
69
70/// GET_STATUS request code
71const USB_REQ_GET_STATUS: u8 = 0x00;
72/// CLEAR_FEATURE request code
73const USB_REQ_CLEAR_FEATURE: u8 = 0x01;
74/// SET_FEATURE request code
75const USB_REQ_SET_FEATURE: u8 = 0x03;
76/// SET_ADDRESS request code
77const USB_REQ_SET_ADDRESS: u8 = 0x05;
78/// GET_DESCRIPTOR request code
79const USB_REQ_GET_DESCRIPTOR: u8 = 0x06;
80/// SET_DESCRIPTOR request code
81const USB_REQ_SET_DESCRIPTOR: u8 = 0x07;
82/// GET_CONFIGURATION request code
83const USB_REQ_GET_CONFIGURATION: u8 = 0x08;
84/// SET_CONFIGURATION request code
85const USB_REQ_SET_CONFIGURATION: u8 = 0x09;
86
87// ---------------------------------------------------------------------------
88// USB Request Type Bit Fields
89// ---------------------------------------------------------------------------
90
91/// Host-to-device direction
92const USB_DIR_OUT: u8 = 0x00;
93/// Device-to-host direction
94const USB_DIR_IN: u8 = 0x80;
95/// Standard request type
96const USB_TYPE_STANDARD: u8 = 0x00;
97/// Class request type
98const USB_TYPE_CLASS: u8 = 0x20;
99/// Vendor request type
100const USB_TYPE_VENDOR: u8 = 0x40;
101/// Recipient: device
102const USB_RECIP_DEVICE: u8 = 0x00;
103/// Recipient: interface
104const USB_RECIP_INTERFACE: u8 = 0x01;
105/// Recipient: endpoint
106const USB_RECIP_ENDPOINT: u8 = 0x02;
107
108// ---------------------------------------------------------------------------
109// TRB Type Codes (xHCI spec Table 6-91)
110// ---------------------------------------------------------------------------
111
112/// TRB type: Normal (data stage of bulk/interrupt)
113const TRB_TYPE_NORMAL: u8 = 1;
114/// TRB type: Setup Stage
115const TRB_TYPE_SETUP_STAGE: u8 = 2;
116/// TRB type: Data Stage
117const TRB_TYPE_DATA_STAGE: u8 = 3;
118/// TRB type: Status Stage
119const TRB_TYPE_STATUS_STAGE: u8 = 4;
120/// TRB type: Isoch
121const TRB_TYPE_ISOCH: u8 = 5;
122/// TRB type: Link
123const TRB_TYPE_LINK: u8 = 6;
124/// TRB type: Event Data
125const TRB_TYPE_EVENT_DATA: u8 = 7;
126/// TRB type: No-Op (transfer ring)
127const TRB_TYPE_NOOP: u8 = 8;
128/// TRB type: Enable Slot Command
129const TRB_TYPE_ENABLE_SLOT: u8 = 9;
130/// TRB type: Disable Slot Command
131const TRB_TYPE_DISABLE_SLOT: u8 = 10;
132/// TRB type: Address Device Command
133const TRB_TYPE_ADDRESS_DEVICE: u8 = 11;
134/// TRB type: Configure Endpoint Command
135const TRB_TYPE_CONFIGURE_ENDPOINT: u8 = 12;
136/// TRB type: Evaluate Context Command
137const TRB_TYPE_EVALUATE_CONTEXT: u8 = 13;
138/// TRB type: Reset Endpoint Command
139const TRB_TYPE_RESET_ENDPOINT: u8 = 14;
140/// TRB type: Stop Endpoint Command
141const TRB_TYPE_STOP_ENDPOINT: u8 = 15;
142/// TRB type: Set TR Dequeue Pointer Command
143const TRB_TYPE_SET_TR_DEQUEUE: u8 = 16;
144/// TRB type: Reset Device Command
145const TRB_TYPE_RESET_DEVICE: u8 = 17;
146/// TRB type: No-Op Command
147const TRB_TYPE_NOOP_CMD: u8 = 23;
148
149// Event TRB types
150/// TRB type: Transfer Event
151const TRB_TYPE_TRANSFER_EVENT: u8 = 32;
152/// TRB type: Command Completion Event
153const TRB_TYPE_COMMAND_COMPLETION: u8 = 33;
154/// TRB type: Port Status Change Event
155const TRB_TYPE_PORT_STATUS_CHANGE: u8 = 34;
156/// TRB type: Bandwidth Request Event
157const TRB_TYPE_BANDWIDTH_REQUEST: u8 = 35;
158/// TRB type: Host Controller Event
159const TRB_TYPE_HOST_CONTROLLER: u8 = 37;
160
161// ---------------------------------------------------------------------------
162// TRB Completion Codes (xHCI spec Table 6-90)
163// ---------------------------------------------------------------------------
164
165/// Completion: Invalid (not yet completed)
166const TRB_COMPLETION_INVALID: u8 = 0;
167/// Completion: Success
168const TRB_COMPLETION_SUCCESS: u8 = 1;
169/// Completion: Data Buffer Error
170const TRB_COMPLETION_DATA_BUFFER_ERROR: u8 = 2;
171/// Completion: Babble Detected Error
172const TRB_COMPLETION_BABBLE: u8 = 3;
173/// Completion: USB Transaction Error
174const TRB_COMPLETION_USB_TRANSACTION_ERROR: u8 = 4;
175/// Completion: TRB Error
176const TRB_COMPLETION_TRB_ERROR: u8 = 5;
177/// Completion: Stall Error
178const TRB_COMPLETION_STALL: u8 = 6;
179/// Completion: Short Packet
180const TRB_COMPLETION_SHORT_PACKET: u8 = 13;
181/// Completion: Command Ring Stopped
182const TRB_COMPLETION_COMMAND_RING_STOPPED: u8 = 24;
183/// Completion: Command Aborted
184const TRB_COMPLETION_COMMAND_ABORTED: u8 = 25;
185
186// ---------------------------------------------------------------------------
187// TRB Control Field Bits
188// ---------------------------------------------------------------------------
189
190/// Cycle bit (bit 0 of control DWORD)
191const TRB_CYCLE_BIT: u32 = 1 << 0;
192/// Toggle Cycle bit for Link TRBs (bit 1)
193const TRB_TOGGLE_CYCLE: u32 = 1 << 1;
194/// Interrupt-on-Short-Packet (bit 2)
195const TRB_ISP: u32 = 1 << 2;
196/// No Snoop (bit 3)
197const TRB_NO_SNOOP: u32 = 1 << 3;
198/// Chain bit (bit 4)
199const TRB_CHAIN: u32 = 1 << 4;
200/// Interrupt-on-Completion (bit 5)
201const TRB_IOC: u32 = 1 << 5;
202/// Immediate Data (bit 6)
203const TRB_IDT: u32 = 1 << 6;
204/// Block Set Address Request (bit 9, Address Device only)
205const TRB_BSR: u32 = 1 << 9;
206
207// ---------------------------------------------------------------------------
208// Port Status and Control Register Bits (xHCI spec 5.4.8)
209// ---------------------------------------------------------------------------
210
211/// Current Connect Status
212const PORTSC_CCS: u32 = 1 << 0;
213/// Port Enabled/Disabled
214const PORTSC_PED: u32 = 1 << 1;
215/// Over-current Active
216const PORTSC_OCA: u32 = 1 << 3;
217/// Port Reset
218const PORTSC_PR: u32 = 1 << 4;
219/// Port Link State (bits 8:5)
220const PORTSC_PLS_MASK: u32 = 0xF << 5;
221/// Port Power
222const PORTSC_PP: u32 = 1 << 9;
223/// Port Speed (bits 13:10)
224const PORTSC_SPEED_MASK: u32 = 0xF << 10;
225/// Port Speed shift
226const PORTSC_SPEED_SHIFT: u32 = 10;
227/// Connect Status Change
228const PORTSC_CSC: u32 = 1 << 17;
229/// Port Enabled/Disabled Change
230const PORTSC_PEC: u32 = 1 << 18;
231/// Warm Port Reset Change
232const PORTSC_WRC: u32 = 1 << 19;
233/// Over-current Change
234const PORTSC_OCC: u32 = 1 << 20;
235/// Port Reset Change
236const PORTSC_PRC: u32 = 1 << 21;
237/// Port Link State Change
238const PORTSC_PLC: u32 = 1 << 22;
239/// Port Config Error Change
240const PORTSC_CEC: u32 = 1 << 23;
241/// Write-1-to-clear status change bits mask
242const PORTSC_CHANGE_BITS: u32 =
243    PORTSC_CSC | PORTSC_PEC | PORTSC_WRC | PORTSC_OCC | PORTSC_PRC | PORTSC_PLC | PORTSC_CEC;
244
245/// Port speed: Full-speed (USB 2.0, 12 Mb/s)
246const PORT_SPEED_FULL: u32 = 1;
247/// Port speed: Low-speed (USB 2.0, 1.5 Mb/s)
248const PORT_SPEED_LOW: u32 = 2;
249/// Port speed: High-speed (USB 2.0, 480 Mb/s)
250const PORT_SPEED_HIGH: u32 = 3;
251/// Port speed: SuperSpeed (USB 3.0, 5 Gb/s)
252const PORT_SPEED_SUPER: u32 = 4;
253/// Port speed: SuperSpeedPlus (USB 3.1+, 10+ Gb/s)
254const PORT_SPEED_SUPER_PLUS: u32 = 5;
255
256// ---------------------------------------------------------------------------
257// MMIO Register Offsets
258// ---------------------------------------------------------------------------
259
260/// Capability Registers (offset 0x00 from MMIO base)
261mod cap_regs {
262    /// Capability Register Length + HC Interface Version
263    pub const CAPLENGTH: usize = 0x00;
264    /// Host Controller Interface Version (16-bit at offset 0x02)
265    pub const HCIVERSION: usize = 0x02;
266    /// Structural Parameters 1
267    pub const HCSPARAMS1: usize = 0x04;
268    /// Structural Parameters 2
269    pub const HCSPARAMS2: usize = 0x08;
270    /// Structural Parameters 3
271    pub const HCSPARAMS3: usize = 0x0C;
272    /// Capability Parameters 1
273    pub const HCCPARAMS1: usize = 0x10;
274    /// Doorbell Offset
275    pub const DBOFF: usize = 0x14;
276    /// Runtime Register Space Offset
277    pub const RTSOFF: usize = 0x18;
278    /// Capability Parameters 2
279    pub const HCCPARAMS2: usize = 0x1C;
280}
281
282/// Operational Register offsets (relative to operational base = MMIO_base +
283/// CAPLENGTH)
284mod op_regs {
285    /// USB Command Register
286    pub const USBCMD: usize = 0x00;
287    /// USB Status Register
288    pub const USBSTS: usize = 0x04;
289    /// Page Size Register
290    pub const PAGESIZE: usize = 0x08;
291    /// Device Notification Control Register
292    pub const DNCTRL: usize = 0x14;
293    /// Command Ring Control Register (64-bit)
294    pub const CRCR: usize = 0x18;
295    /// Device Context Base Address Array Pointer (64-bit)
296    pub const DCBAAP: usize = 0x30;
297    /// Configure Register
298    pub const CONFIG: usize = 0x38;
299    /// Port Register Set base (port 1 starts here)
300    pub const PORT_REG_BASE: usize = 0x400;
301    /// Size of each port register set
302    pub const PORT_REG_SIZE: usize = 0x10;
303}
304
305/// USBCMD register bits
306mod usbcmd_bits {
307    /// Run/Stop
308    pub const RS: u32 = 1 << 0;
309    /// Host Controller Reset
310    pub const HCRST: u32 = 1 << 1;
311    /// Interrupter Enable
312    pub const INTE: u32 = 1 << 2;
313    /// Host System Error Enable
314    pub const HSEE: u32 = 1 << 3;
315    /// Light Host Controller Reset
316    pub const LHCRST: u32 = 1 << 5;
317    /// Controller Save State
318    pub const CSS: u32 = 1 << 8;
319    /// Controller Restore State
320    pub const CRS: u32 = 1 << 9;
321    /// Enable Wrap Event
322    pub const EWE: u32 = 1 << 10;
323}
324
325/// USBSTS register bits
326mod usbsts_bits {
327    /// HC Halted
328    pub const HCH: u32 = 1 << 0;
329    /// Host System Error
330    pub const HSE: u32 = 1 << 2;
331    /// Event Interrupt
332    pub const EINT: u32 = 1 << 3;
333    /// Port Change Detect
334    pub const PCD: u32 = 1 << 4;
335    /// Controller Not Ready
336    pub const CNR: u32 = 1 << 11;
337    /// Host Controller Error
338    pub const HCE: u32 = 1 << 12;
339}
340
341/// Runtime register offsets (relative to runtime base = MMIO_base + RTSOFF)
342mod rt_regs {
343    /// Microframe Index Register
344    pub const MFINDEX: usize = 0x00;
345    /// Interrupter Register Set base (interrupter 0)
346    pub const IR0_BASE: usize = 0x20;
347    /// Size of each Interrupter Register Set
348    pub const IR_SIZE: usize = 0x20;
349}
350
351/// Interrupter Register offsets (within each interrupter set)
352mod ir_regs {
353    /// Interrupter Management Register
354    pub const IMAN: usize = 0x00;
355    /// Interrupter Moderation Register
356    pub const IMOD: usize = 0x04;
357    /// Event Ring Segment Table Size
358    pub const ERSTSZ: usize = 0x08;
359    /// Event Ring Segment Table Base Address (64-bit)
360    pub const ERSTBA: usize = 0x10;
361    /// Event Ring Dequeue Pointer (64-bit)
362    pub const ERDP: usize = 0x18;
363}
364
365// ---------------------------------------------------------------------------
366// Transfer Request Block (TRB)
367// ---------------------------------------------------------------------------
368
369/// Generic 16-byte Transfer Request Block
370///
371/// All TRBs share this common layout per xHCI spec Section 4.11.
372#[derive(Debug, Clone, Copy, PartialEq, Eq)]
373#[repr(C, align(16))]
374pub struct Trb {
375    /// Parameter low DWORD (meaning varies by TRB type)
376    pub parameter_lo: u32,
377    /// Parameter high DWORD
378    pub parameter_hi: u32,
379    /// Status DWORD (transfer length, completion code, etc.)
380    pub status: u32,
381    /// Control DWORD (TRB type, cycle bit, flags)
382    pub control: u32,
383}
384
385impl Trb {
386    /// Create a zeroed TRB
387    pub const fn zeroed() -> Self {
388        Self {
389            parameter_lo: 0,
390            parameter_hi: 0,
391            status: 0,
392            control: 0,
393        }
394    }
395
396    /// Get the TRB type field (bits 15:10 of control)
397    pub fn trb_type(&self) -> u8 {
398        ((self.control >> 10) & 0x3F) as u8
399    }
400
401    /// Set the TRB type field
402    pub fn set_trb_type(&mut self, trb_type: u8) {
403        self.control = (self.control & !(0x3F << 10)) | ((trb_type as u32 & 0x3F) << 10);
404    }
405
406    /// Get the cycle bit
407    pub fn cycle_bit(&self) -> bool {
408        (self.control & TRB_CYCLE_BIT) != 0
409    }
410
411    /// Set the cycle bit
412    pub fn set_cycle_bit(&mut self, cycle: bool) {
413        if cycle {
414            self.control |= TRB_CYCLE_BIT;
415        } else {
416            self.control &= !TRB_CYCLE_BIT;
417        }
418    }
419
420    /// Get completion code from status DWORD (bits 31:24)
421    pub fn completion_code(&self) -> u8 {
422        ((self.status >> 24) & 0xFF) as u8
423    }
424
425    /// Get the slot ID from control DWORD (bits 31:24)
426    pub fn slot_id(&self) -> u8 {
427        ((self.control >> 24) & 0xFF) as u8
428    }
429
430    /// Set the slot ID in control DWORD (bits 31:24)
431    pub fn set_slot_id(&mut self, slot: u8) {
432        self.control = (self.control & !(0xFF << 24)) | ((slot as u32) << 24);
433    }
434
435    /// Get the transfer length from status DWORD (bits 16:0)
436    pub fn transfer_length(&self) -> u32 {
437        self.status & 0x1FFFF
438    }
439
440    /// Set the transfer length in status DWORD (bits 16:0)
441    pub fn set_transfer_length(&mut self, len: u32) {
442        self.status = (self.status & !0x1FFFF) | (len & 0x1FFFF);
443    }
444
445    /// Create a Normal TRB for bulk/interrupt transfers
446    pub fn normal(data_phys: u64, length: u32, ioc: bool, cycle: bool) -> Self {
447        let mut trb = Self::zeroed();
448        trb.parameter_lo = data_phys as u32;
449        trb.parameter_hi = (data_phys >> 32) as u32;
450        trb.set_transfer_length(length);
451        trb.set_trb_type(TRB_TYPE_NORMAL);
452        trb.set_cycle_bit(cycle);
453        if ioc {
454            trb.control |= TRB_IOC;
455        }
456        trb
457    }
458
459    /// Create a Setup Stage TRB for control transfers
460    pub fn setup_stage(
461        request_type: u8,
462        request: u8,
463        value: u16,
464        index: u16,
465        length: u16,
466        transfer_type: SetupTransferType,
467        cycle: bool,
468    ) -> Self {
469        let mut trb = Self::zeroed();
470        // Setup data is packed into parameter fields (8 bytes total)
471        trb.parameter_lo = (request_type as u32) | ((request as u32) << 8) | ((value as u32) << 16);
472        trb.parameter_hi = (index as u32) | ((length as u32) << 16);
473        trb.status = 8; // Setup packet is always 8 bytes
474        trb.set_trb_type(TRB_TYPE_SETUP_STAGE);
475        trb.set_cycle_bit(cycle);
476        trb.control |= TRB_IDT; // Immediate Data for setup stage
477                                // Transfer type in bits 17:16
478        trb.control |= (transfer_type as u32) << 16;
479        trb
480    }
481
482    /// Create a Data Stage TRB for control transfers
483    pub fn data_stage(data_phys: u64, length: u32, direction_in: bool, cycle: bool) -> Self {
484        let mut trb = Self::zeroed();
485        trb.parameter_lo = data_phys as u32;
486        trb.parameter_hi = (data_phys >> 32) as u32;
487        trb.set_transfer_length(length);
488        trb.set_trb_type(TRB_TYPE_DATA_STAGE);
489        trb.set_cycle_bit(cycle);
490        if direction_in {
491            trb.control |= 1 << 16; // DIR = 1 (IN)
492        }
493        trb
494    }
495
496    /// Create a Status Stage TRB for control transfers
497    pub fn status_stage(direction_in: bool, ioc: bool, cycle: bool) -> Self {
498        let mut trb = Self::zeroed();
499        trb.set_trb_type(TRB_TYPE_STATUS_STAGE);
500        trb.set_cycle_bit(cycle);
501        if direction_in {
502            trb.control |= 1 << 16; // DIR = 1 (IN)
503        }
504        if ioc {
505            trb.control |= TRB_IOC;
506        }
507        trb
508    }
509
510    /// Create a Link TRB pointing to the start of a ring segment
511    pub fn link(segment_phys: u64, toggle_cycle: bool, cycle: bool) -> Self {
512        let mut trb = Self::zeroed();
513        trb.parameter_lo = segment_phys as u32;
514        trb.parameter_hi = (segment_phys >> 32) as u32;
515        trb.set_trb_type(TRB_TYPE_LINK);
516        trb.set_cycle_bit(cycle);
517        if toggle_cycle {
518            trb.control |= TRB_TOGGLE_CYCLE;
519        }
520        trb
521    }
522
523    /// Create an Event Data TRB
524    pub fn event_data(data: u64, ioc: bool, cycle: bool) -> Self {
525        let mut trb = Self::zeroed();
526        trb.parameter_lo = data as u32;
527        trb.parameter_hi = (data >> 32) as u32;
528        trb.set_trb_type(TRB_TYPE_EVENT_DATA);
529        trb.set_cycle_bit(cycle);
530        if ioc {
531            trb.control |= TRB_IOC;
532        }
533        trb
534    }
535
536    /// Create a No-Op TRB (transfer ring)
537    pub fn noop(ioc: bool, cycle: bool) -> Self {
538        let mut trb = Self::zeroed();
539        trb.set_trb_type(TRB_TYPE_NOOP);
540        trb.set_cycle_bit(cycle);
541        if ioc {
542            trb.control |= TRB_IOC;
543        }
544        trb
545    }
546
547    /// Create an Enable Slot Command TRB
548    pub fn enable_slot(cycle: bool) -> Self {
549        let mut trb = Self::zeroed();
550        trb.set_trb_type(TRB_TYPE_ENABLE_SLOT);
551        trb.set_cycle_bit(cycle);
552        trb
553    }
554
555    /// Create a Disable Slot Command TRB
556    pub fn disable_slot(slot_id: u8, cycle: bool) -> Self {
557        let mut trb = Self::zeroed();
558        trb.set_trb_type(TRB_TYPE_DISABLE_SLOT);
559        trb.set_slot_id(slot_id);
560        trb.set_cycle_bit(cycle);
561        trb
562    }
563
564    /// Create an Address Device Command TRB
565    pub fn address_device(input_context_phys: u64, slot_id: u8, bsr: bool, cycle: bool) -> Self {
566        let mut trb = Self::zeroed();
567        trb.parameter_lo = input_context_phys as u32;
568        trb.parameter_hi = (input_context_phys >> 32) as u32;
569        trb.set_trb_type(TRB_TYPE_ADDRESS_DEVICE);
570        trb.set_slot_id(slot_id);
571        trb.set_cycle_bit(cycle);
572        if bsr {
573            trb.control |= TRB_BSR;
574        }
575        trb
576    }
577
578    /// Create a Configure Endpoint Command TRB
579    pub fn configure_endpoint(
580        input_context_phys: u64,
581        slot_id: u8,
582        deconfigure: bool,
583        cycle: bool,
584    ) -> Self {
585        let mut trb = Self::zeroed();
586        trb.parameter_lo = input_context_phys as u32;
587        trb.parameter_hi = (input_context_phys >> 32) as u32;
588        trb.set_trb_type(TRB_TYPE_CONFIGURE_ENDPOINT);
589        trb.set_slot_id(slot_id);
590        trb.set_cycle_bit(cycle);
591        if deconfigure {
592            trb.control |= 1 << 9; // DC bit
593        }
594        trb
595    }
596
597    /// Create a No-Op Command TRB
598    pub fn noop_cmd(cycle: bool) -> Self {
599        let mut trb = Self::zeroed();
600        trb.set_trb_type(TRB_TYPE_NOOP_CMD);
601        trb.set_cycle_bit(cycle);
602        trb
603    }
604}
605
606/// Transfer type for Setup Stage TRB (control DWORD bits 17:16)
607#[derive(Debug, Clone, Copy, PartialEq, Eq)]
608#[repr(u32)]
609pub enum SetupTransferType {
610    /// No data stage
611    NoData = 0,
612    /// OUT data stage
613    Out = 2,
614    /// IN data stage
615    In = 3,
616}
617
618// ---------------------------------------------------------------------------
619// Ring Buffers
620// ---------------------------------------------------------------------------
621
622/// Producer/consumer cycle state for ring buffers
623#[derive(Debug, Clone, Copy, PartialEq, Eq)]
624pub struct RingState {
625    /// Physical base address of the ring segment
626    pub segment_phys: u64,
627    /// Current enqueue/dequeue index within the segment
628    pub index: usize,
629    /// Current cycle bit (toggled when wrapping via Link TRB)
630    pub cycle: bool,
631    /// Number of TRBs in the segment (excluding Link TRB at end)
632    pub capacity: usize,
633}
634
635impl RingState {
636    /// Create a new ring state
637    pub fn new(segment_phys: u64, capacity: usize) -> Self {
638        Self {
639            segment_phys,
640            index: 0,
641            cycle: true,
642            capacity,
643        }
644    }
645
646    /// Advance index, wrapping and toggling cycle if needed
647    pub fn advance(&mut self) {
648        self.index += 1;
649        if self.index >= self.capacity {
650            self.index = 0;
651            self.cycle = !self.cycle;
652        }
653    }
654
655    /// Get the physical address of the TRB at the current index
656    pub fn current_trb_phys(&self) -> u64 {
657        self.segment_phys + (self.index as u64) * (TRB_SIZE as u64)
658    }
659}
660
661/// Command Ring: the host controller dequeues command TRBs from here
662pub struct CommandRing {
663    state: RingState,
664}
665
666impl CommandRing {
667    /// Create a new command ring
668    pub fn new(segment_phys: u64) -> Self {
669        Self {
670            state: RingState::new(segment_phys, RING_SEGMENT_TRBS - 1),
671        }
672    }
673
674    /// Enqueue a command TRB onto the ring.
675    ///
676    /// Returns the physical address of the enqueued TRB.
677    ///
678    /// # Safety
679    ///
680    /// The caller must ensure `segment_phys` points to valid,
681    /// mapped, DMA-accessible memory of at least `RING_SEGMENT_SIZE` bytes.
682    #[cfg(target_os = "none")]
683    pub unsafe fn enqueue(&mut self, mut trb: Trb) -> u64 {
684        trb.set_cycle_bit(self.state.cycle);
685        let addr = self.state.current_trb_phys();
686
687        // SAFETY: addr is within the ring segment allocated by the caller.
688        // write_volatile ensures the TRB is visible to the hardware.
689        unsafe {
690            core::ptr::write_volatile(addr as *mut Trb, trb);
691        }
692
693        self.state.advance();
694
695        // If we've wrapped, write a Link TRB at the last slot pointing back
696        if self.state.index == 0 {
697            let link_addr =
698                self.state.segment_phys + (self.state.capacity as u64) * (TRB_SIZE as u64);
699            let link = Trb::link(self.state.segment_phys, true, !self.state.cycle);
700            // SAFETY: link_addr is the last TRB slot in the segment.
701            unsafe {
702                core::ptr::write_volatile(link_addr as *mut Trb, link);
703            }
704        }
705
706        addr
707    }
708
709    /// Non-hardware stub for testing on host targets
710    #[cfg(not(target_os = "none"))]
711    pub fn enqueue(&mut self, mut trb: Trb) -> u64 {
712        trb.set_cycle_bit(self.state.cycle);
713        let addr = self.state.current_trb_phys();
714        self.state.advance();
715        addr
716    }
717
718    /// Get the physical base address and current cycle bit for CRCR
719    pub fn crcr_value(&self) -> u64 {
720        self.state.segment_phys | if self.state.cycle { 1 } else { 0 }
721    }
722}
723
724/// Event Ring Segment Table Entry (xHCI spec 6.5)
725#[derive(Debug, Clone, Copy)]
726#[repr(C, align(64))]
727pub struct EventRingSegmentTableEntry {
728    /// Ring Segment Base Address (64-bit, 64-byte aligned)
729    pub base_address: u64,
730    /// Ring Segment Size (number of TRBs)
731    pub size: u16,
732    /// Reserved
733    pub _reserved0: u16,
734    /// Reserved
735    pub _reserved1: u32,
736}
737
738/// Event Ring: the host controller enqueues event TRBs here
739pub struct EventRing {
740    state: RingState,
741}
742
743impl EventRing {
744    /// Create a new event ring
745    pub fn new(segment_phys: u64, capacity: usize) -> Self {
746        Self {
747            state: RingState::new(segment_phys, capacity),
748        }
749    }
750
751    /// Dequeue the next event TRB if one is available.
752    ///
753    /// Returns `Some(trb)` if the cycle bit of the TRB at the dequeue pointer
754    /// matches our expected cycle state, or `None` if no event is pending.
755    ///
756    /// # Safety
757    ///
758    /// The caller must ensure the event ring segment is valid memory.
759    #[cfg(target_os = "none")]
760    pub unsafe fn dequeue(&mut self) -> Option<Trb> {
761        let addr = self.state.current_trb_phys();
762        // SAFETY: addr points within the event ring segment.
763        let trb = unsafe { core::ptr::read_volatile(addr as *const Trb) };
764
765        if trb.cycle_bit() != self.state.cycle {
766            return None; // No new event
767        }
768
769        self.state.advance();
770        Some(trb)
771    }
772
773    /// Non-hardware stub for host targets
774    #[cfg(not(target_os = "none"))]
775    pub fn dequeue(&mut self) -> Option<Trb> {
776        None
777    }
778
779    /// Get the current dequeue pointer for writing to ERDP
780    pub fn erdp_value(&self) -> u64 {
781        self.state.current_trb_phys()
782    }
783}
784
785/// Transfer Ring: per-endpoint ring for bulk/interrupt/control data transfers
786pub struct TransferRing {
787    state: RingState,
788}
789
790impl TransferRing {
791    /// Create a new transfer ring
792    pub fn new(segment_phys: u64) -> Self {
793        Self {
794            state: RingState::new(segment_phys, RING_SEGMENT_TRBS - 1),
795        }
796    }
797
798    /// Enqueue a TRB onto the transfer ring.
799    ///
800    /// # Safety
801    ///
802    /// The caller must ensure the ring segment is valid DMA memory.
803    #[cfg(target_os = "none")]
804    pub unsafe fn enqueue(&mut self, mut trb: Trb) -> u64 {
805        trb.set_cycle_bit(self.state.cycle);
806        let addr = self.state.current_trb_phys();
807
808        // SAFETY: addr is within the transfer ring segment.
809        unsafe {
810            core::ptr::write_volatile(addr as *mut Trb, trb);
811        }
812
813        self.state.advance();
814
815        // Write Link TRB if we wrapped
816        if self.state.index == 0 {
817            let link_addr =
818                self.state.segment_phys + (self.state.capacity as u64) * (TRB_SIZE as u64);
819            let link = Trb::link(self.state.segment_phys, true, !self.state.cycle);
820            // SAFETY: link_addr is the last TRB slot in the transfer ring segment.
821            unsafe {
822                core::ptr::write_volatile(link_addr as *mut Trb, link);
823            }
824        }
825
826        addr
827    }
828
829    /// Non-hardware stub for host targets
830    #[cfg(not(target_os = "none"))]
831    pub fn enqueue(&mut self, mut trb: Trb) -> u64 {
832        trb.set_cycle_bit(self.state.cycle);
833        let addr = self.state.current_trb_phys();
834        self.state.advance();
835        addr
836    }
837
838    /// Enqueue a control transfer (Setup + optional Data + Status).
839    ///
840    /// Returns the physical address of the Status Stage TRB.
841    ///
842    /// # Safety
843    ///
844    /// The caller must ensure the ring segment is valid DMA memory and
845    /// `data_phys` (if non-zero) points to a valid buffer of `data_len` bytes.
846    #[cfg(target_os = "none")]
847    pub unsafe fn enqueue_control(
848        &mut self,
849        request_type: u8,
850        request: u8,
851        value: u16,
852        index: u16,
853        data_phys: u64,
854        data_len: u16,
855    ) -> u64 {
856        let direction_in = (request_type & USB_DIR_IN) != 0;
857        let transfer_type = if data_len == 0 {
858            SetupTransferType::NoData
859        } else if direction_in {
860            SetupTransferType::In
861        } else {
862            SetupTransferType::Out
863        };
864
865        // Setup Stage
866        let setup = Trb::setup_stage(
867            request_type,
868            request,
869            value,
870            index,
871            data_len,
872            transfer_type,
873            self.state.cycle,
874        );
875        // SAFETY: Caller guarantees the ring segment is valid DMA memory.
876        unsafe {
877            self.enqueue(setup);
878        }
879
880        // Data Stage (if any)
881        if data_len > 0 {
882            let data = Trb::data_stage(data_phys, data_len as u32, direction_in, self.state.cycle);
883            // SAFETY: Same ring segment invariant as setup stage above.
884            unsafe {
885                self.enqueue(data);
886            }
887        }
888
889        // Status Stage (direction is opposite of data stage, or IN if no data)
890        let status_dir_in = if data_len == 0 { true } else { !direction_in };
891        let status = Trb::status_stage(status_dir_in, true, self.state.cycle);
892        // SAFETY: Same ring segment invariant as setup stage above.
893        unsafe { self.enqueue(status) }
894    }
895
896    /// Non-hardware stub for host targets
897    #[cfg(not(target_os = "none"))]
898    pub fn enqueue_control(
899        &mut self,
900        request_type: u8,
901        request: u8,
902        value: u16,
903        index: u16,
904        _data_phys: u64,
905        data_len: u16,
906    ) -> u64 {
907        let direction_in = (request_type & USB_DIR_IN) != 0;
908        let transfer_type = if data_len == 0 {
909            SetupTransferType::NoData
910        } else if direction_in {
911            SetupTransferType::In
912        } else {
913            SetupTransferType::Out
914        };
915
916        let setup = Trb::setup_stage(
917            request_type,
918            request,
919            value,
920            index,
921            data_len,
922            transfer_type,
923            self.state.cycle,
924        );
925        self.enqueue(setup);
926
927        if data_len > 0 {
928            let data = Trb::data_stage(0, data_len as u32, direction_in, self.state.cycle);
929            self.enqueue(data);
930        }
931
932        let status_dir_in = if data_len == 0 { true } else { !direction_in };
933        let status = Trb::status_stage(status_dir_in, true, self.state.cycle);
934        self.enqueue(status)
935    }
936
937    /// Get physical base address of the ring
938    pub fn base_phys(&self) -> u64 {
939        self.state.segment_phys
940    }
941}
942
943// ---------------------------------------------------------------------------
944// USB Descriptors (parsed from raw bytes)
945// ---------------------------------------------------------------------------
946
947/// Parsed USB Device Descriptor (18 bytes)
948#[derive(Debug, Clone, Copy)]
949pub struct XhciDeviceDescriptor {
950    pub usb_version: u16,
951    pub device_class: u8,
952    pub device_subclass: u8,
953    pub device_protocol: u8,
954    pub max_packet_size_ep0: u8,
955    pub vendor_id: u16,
956    pub product_id: u16,
957    pub device_version: u16,
958    pub manufacturer_index: u8,
959    pub product_index: u8,
960    pub serial_index: u8,
961    pub num_configurations: u8,
962}
963
964impl XhciDeviceDescriptor {
965    /// Parse from a raw 18-byte descriptor buffer
966    pub fn parse(data: &[u8]) -> Result<Self, KernelError> {
967        if data.len() < 18 {
968            return Err(KernelError::InvalidArgument {
969                name: "device_descriptor",
970                value: "buffer too short (need 18 bytes)",
971            });
972        }
973        if data[1] != DESC_TYPE_DEVICE {
974            return Err(KernelError::InvalidArgument {
975                name: "device_descriptor",
976                value: "wrong descriptor type",
977            });
978        }
979        Ok(Self {
980            usb_version: u16::from_le_bytes([data[2], data[3]]),
981            device_class: data[4],
982            device_subclass: data[5],
983            device_protocol: data[6],
984            max_packet_size_ep0: data[7],
985            vendor_id: u16::from_le_bytes([data[8], data[9]]),
986            product_id: u16::from_le_bytes([data[10], data[11]]),
987            device_version: u16::from_le_bytes([data[12], data[13]]),
988            manufacturer_index: data[14],
989            product_index: data[15],
990            serial_index: data[16],
991            num_configurations: data[17],
992        })
993    }
994}
995
996/// Parsed USB Configuration Descriptor header (9 bytes)
997#[derive(Debug, Clone, Copy)]
998pub struct XhciConfigDescriptor {
999    pub total_length: u16,
1000    pub num_interfaces: u8,
1001    pub config_value: u8,
1002    pub config_index: u8,
1003    pub attributes: u8,
1004    pub max_power_ma: u16,
1005}
1006
1007impl XhciConfigDescriptor {
1008    /// Parse from a raw descriptor buffer (at least 9 bytes)
1009    pub fn parse(data: &[u8]) -> Result<Self, KernelError> {
1010        if data.len() < 9 {
1011            return Err(KernelError::InvalidArgument {
1012                name: "config_descriptor",
1013                value: "buffer too short (need 9 bytes)",
1014            });
1015        }
1016        if data[1] != DESC_TYPE_CONFIGURATION {
1017            return Err(KernelError::InvalidArgument {
1018                name: "config_descriptor",
1019                value: "wrong descriptor type",
1020            });
1021        }
1022        Ok(Self {
1023            total_length: u16::from_le_bytes([data[2], data[3]]),
1024            num_interfaces: data[4],
1025            config_value: data[5],
1026            config_index: data[6],
1027            attributes: data[7],
1028            max_power_ma: (data[8] as u16) * 2, // bMaxPower is in units of 2 mA
1029        })
1030    }
1031
1032    /// Whether the device is self-powered
1033    pub fn is_self_powered(&self) -> bool {
1034        (self.attributes & (1 << 6)) != 0
1035    }
1036
1037    /// Whether remote wakeup is supported
1038    pub fn supports_remote_wakeup(&self) -> bool {
1039        (self.attributes & (1 << 5)) != 0
1040    }
1041}
1042
1043/// Parsed USB Interface Descriptor (9 bytes)
1044#[derive(Debug, Clone, Copy)]
1045pub struct XhciInterfaceDescriptor {
1046    pub interface_number: u8,
1047    pub alternate_setting: u8,
1048    pub num_endpoints: u8,
1049    pub interface_class: u8,
1050    pub interface_subclass: u8,
1051    pub interface_protocol: u8,
1052    pub interface_index: u8,
1053}
1054
1055impl XhciInterfaceDescriptor {
1056    /// Parse from a raw descriptor buffer (at least 9 bytes)
1057    pub fn parse(data: &[u8]) -> Result<Self, KernelError> {
1058        if data.len() < 9 {
1059            return Err(KernelError::InvalidArgument {
1060                name: "interface_descriptor",
1061                value: "buffer too short (need 9 bytes)",
1062            });
1063        }
1064        if data[1] != DESC_TYPE_INTERFACE {
1065            return Err(KernelError::InvalidArgument {
1066                name: "interface_descriptor",
1067                value: "wrong descriptor type",
1068            });
1069        }
1070        Ok(Self {
1071            interface_number: data[2],
1072            alternate_setting: data[3],
1073            num_endpoints: data[4],
1074            interface_class: data[5],
1075            interface_subclass: data[6],
1076            interface_protocol: data[7],
1077            interface_index: data[8],
1078        })
1079    }
1080}
1081
1082/// Parsed USB Endpoint Descriptor (7 bytes)
1083#[derive(Debug, Clone, Copy)]
1084pub struct XhciEndpointDescriptor {
1085    pub endpoint_address: u8,
1086    pub attributes: u8,
1087    pub max_packet_size: u16,
1088    pub interval: u8,
1089}
1090
1091impl XhciEndpointDescriptor {
1092    /// Parse from a raw descriptor buffer (at least 7 bytes)
1093    pub fn parse(data: &[u8]) -> Result<Self, KernelError> {
1094        if data.len() < 7 {
1095            return Err(KernelError::InvalidArgument {
1096                name: "endpoint_descriptor",
1097                value: "buffer too short (need 7 bytes)",
1098            });
1099        }
1100        if data[1] != DESC_TYPE_ENDPOINT {
1101            return Err(KernelError::InvalidArgument {
1102                name: "endpoint_descriptor",
1103                value: "wrong descriptor type",
1104            });
1105        }
1106        Ok(Self {
1107            endpoint_address: data[2],
1108            attributes: data[3],
1109            max_packet_size: u16::from_le_bytes([data[4], data[5]]),
1110            interval: data[6],
1111        })
1112    }
1113
1114    /// Whether this is an IN endpoint
1115    pub fn is_in(&self) -> bool {
1116        (self.endpoint_address & 0x80) != 0
1117    }
1118
1119    /// Get the endpoint number (bits 3:0)
1120    pub fn endpoint_number(&self) -> u8 {
1121        self.endpoint_address & 0x0F
1122    }
1123
1124    /// Get the transfer type
1125    pub fn transfer_type(&self) -> EndpointTransferType {
1126        match self.attributes & 0x03 {
1127            0 => EndpointTransferType::Control,
1128            1 => EndpointTransferType::Isochronous,
1129            2 => EndpointTransferType::Bulk,
1130            3 => EndpointTransferType::Interrupt,
1131            _ => unreachable!(),
1132        }
1133    }
1134}
1135
1136/// Endpoint transfer type
1137#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1138pub enum EndpointTransferType {
1139    Control = 0,
1140    Isochronous = 1,
1141    Bulk = 2,
1142    Interrupt = 3,
1143}
1144
1145/// A parsed interface paired with its endpoint descriptors.
1146#[cfg(feature = "alloc")]
1147pub type InterfaceWithEndpoints = (XhciInterfaceDescriptor, Vec<XhciEndpointDescriptor>);
1148
1149/// Parse all descriptors from a full configuration descriptor buffer.
1150///
1151/// Returns (config, interfaces_with_endpoints) where each interface
1152/// is paired with its endpoints.
1153#[cfg(feature = "alloc")]
1154pub fn parse_configuration_descriptors(
1155    data: &[u8],
1156) -> Result<(XhciConfigDescriptor, Vec<InterfaceWithEndpoints>), KernelError> {
1157    let config = XhciConfigDescriptor::parse(data)?;
1158    let total = config.total_length as usize;
1159    if data.len() < total {
1160        return Err(KernelError::InvalidArgument {
1161            name: "config_descriptor",
1162            value: "buffer shorter than wTotalLength",
1163        });
1164    }
1165
1166    let mut interfaces = Vec::new();
1167    let mut current_iface: Option<XhciInterfaceDescriptor> = None;
1168    let mut current_endpoints: Vec<XhciEndpointDescriptor> = Vec::new();
1169    let mut offset = data[0] as usize; // skip config descriptor header
1170
1171    while offset + 1 < total {
1172        let desc_len = data[offset] as usize;
1173        if desc_len < 2 || offset + desc_len > total {
1174            break;
1175        }
1176        let desc_type = data[offset + 1];
1177
1178        match desc_type {
1179            DESC_TYPE_INTERFACE => {
1180                // Save previous interface if any
1181                if let Some(iface) = current_iface.take() {
1182                    interfaces.push((iface, core::mem::take(&mut current_endpoints)));
1183                }
1184                if let Ok(iface) = XhciInterfaceDescriptor::parse(&data[offset..]) {
1185                    current_iface = Some(iface);
1186                }
1187            }
1188            DESC_TYPE_ENDPOINT => {
1189                if let Ok(ep) = XhciEndpointDescriptor::parse(&data[offset..]) {
1190                    current_endpoints.push(ep);
1191                }
1192            }
1193            _ => {} // Skip unknown descriptors
1194        }
1195
1196        offset += desc_len;
1197    }
1198
1199    // Push the last interface
1200    if let Some(iface) = current_iface {
1201        interfaces.push((iface, current_endpoints));
1202    }
1203
1204    Ok((config, interfaces))
1205}
1206
1207// ---------------------------------------------------------------------------
1208// Device Slot Management
1209// ---------------------------------------------------------------------------
1210
1211/// State of a device slot
1212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1213pub enum SlotState {
1214    /// Slot is disabled (available for allocation)
1215    Disabled,
1216    /// Slot is enabled but device not yet addressed
1217    Enabled,
1218    /// Default state (BSR = 1 was used)
1219    Default,
1220    /// Device has been addressed
1221    Addressed,
1222    /// Device is configured
1223    Configured,
1224}
1225
1226/// Per-device-slot tracking information
1227#[derive(Debug)]
1228pub struct DeviceSlot {
1229    /// Slot ID (1-based, assigned by hardware via Enable Slot)
1230    pub slot_id: u8,
1231    /// Current slot state
1232    pub state: SlotState,
1233    /// Root hub port number this device is connected to (1-based)
1234    pub port_number: u8,
1235    /// USB device speed
1236    pub speed: PortSpeed,
1237    /// Physical address of the device context (output context)
1238    pub device_context_phys: u64,
1239    /// Physical address of the input context
1240    pub input_context_phys: u64,
1241}
1242
1243/// Port speed as reported by xHCI PORTSC
1244#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1245pub enum PortSpeed {
1246    /// Full-speed (12 Mb/s)
1247    Full,
1248    /// Low-speed (1.5 Mb/s)
1249    Low,
1250    /// High-speed (480 Mb/s)
1251    High,
1252    /// SuperSpeed (5 Gb/s)
1253    Super,
1254    /// SuperSpeedPlus (10+ Gb/s)
1255    SuperPlus,
1256    /// Unknown speed
1257    Unknown,
1258}
1259
1260impl PortSpeed {
1261    /// Convert from PORTSC speed field value
1262    pub fn from_portsc(speed_val: u32) -> Self {
1263        match speed_val {
1264            PORT_SPEED_FULL => Self::Full,
1265            PORT_SPEED_LOW => Self::Low,
1266            PORT_SPEED_HIGH => Self::High,
1267            PORT_SPEED_SUPER => Self::Super,
1268            PORT_SPEED_SUPER_PLUS => Self::SuperPlus,
1269            _ => Self::Unknown,
1270        }
1271    }
1272
1273    /// Get the maximum packet size for endpoint 0 for this speed
1274    pub fn default_max_packet_size_ep0(&self) -> u16 {
1275        match self {
1276            Self::Low => 8,
1277            Self::Full => 8, // Can be 8, 16, 32, or 64; start with 8
1278            Self::High => 64,
1279            Self::Super | Self::SuperPlus => 512,
1280            Self::Unknown => 8,
1281        }
1282    }
1283}
1284
1285// ---------------------------------------------------------------------------
1286// Port Management
1287// ---------------------------------------------------------------------------
1288
1289/// xHCI port information
1290#[derive(Debug, Clone, Copy)]
1291pub struct XhciPort {
1292    /// Port number (1-based)
1293    pub number: u8,
1294    /// Whether a device is connected
1295    pub connected: bool,
1296    /// Whether the port is enabled
1297    pub enabled: bool,
1298    /// Current speed of connected device
1299    pub speed: PortSpeed,
1300    /// Whether the port is powered
1301    pub powered: bool,
1302    /// Whether a reset is in progress
1303    pub resetting: bool,
1304}
1305
1306impl XhciPort {
1307    /// Parse port state from a PORTSC register value
1308    pub fn from_portsc(port_number: u8, portsc: u32) -> Self {
1309        let speed_val = (portsc & PORTSC_SPEED_MASK) >> PORTSC_SPEED_SHIFT;
1310        Self {
1311            number: port_number,
1312            connected: (portsc & PORTSC_CCS) != 0,
1313            enabled: (portsc & PORTSC_PED) != 0,
1314            speed: PortSpeed::from_portsc(speed_val),
1315            powered: (portsc & PORTSC_PP) != 0,
1316            resetting: (portsc & PORTSC_PR) != 0,
1317        }
1318    }
1319}
1320
1321// ---------------------------------------------------------------------------
1322// xHCI Controller State
1323// ---------------------------------------------------------------------------
1324
1325/// xHCI controller capabilities parsed from Capability Registers
1326#[derive(Debug, Clone, Copy)]
1327pub struct XhciCapabilities {
1328    /// Length of capability register space (offset to operational registers)
1329    pub cap_length: u8,
1330    /// xHCI interface version (e.g. 0x0100 = 1.0, 0x0110 = 1.1)
1331    pub hci_version: u16,
1332    /// Maximum number of device slots
1333    pub max_slots: u8,
1334    /// Maximum number of interrupters
1335    pub max_intrs: u16,
1336    /// Maximum number of ports
1337    pub max_ports: u8,
1338    /// Whether the controller supports 64-byte contexts
1339    pub context_size_64: bool,
1340    /// Doorbell array offset from MMIO base
1341    pub doorbell_offset: u32,
1342    /// Runtime register space offset from MMIO base
1343    pub runtime_offset: u32,
1344}
1345
1346/// State of the xHCI controller
1347pub struct XhciController {
1348    /// MMIO base address (from PCI BAR0)
1349    mmio_base: u64,
1350    /// Parsed capability registers
1351    capabilities: XhciCapabilities,
1352    /// Operational register base address
1353    op_base: u64,
1354    /// Runtime register base address
1355    rt_base: u64,
1356    /// Doorbell array base address
1357    db_base: u64,
1358    /// Command ring
1359    command_ring: CommandRing,
1360    /// Event ring for interrupter 0
1361    event_ring: EventRing,
1362    /// Whether the controller is running
1363    running: bool,
1364    /// Number of enabled device slots
1365    enabled_slots: u32,
1366}
1367
1368impl XhciController {
1369    /// Create a new xHCI controller instance from its MMIO base address.
1370    ///
1371    /// # Safety
1372    ///
1373    /// `mmio_base` must point to a valid xHCI MMIO region that is
1374    /// identity-mapped or otherwise accessible. This function reads capability
1375    /// registers to determine the layout.
1376    #[cfg(target_os = "none")]
1377    pub unsafe fn new(mmio_base: u64) -> Result<Self, KernelError> {
1378        // Read capability registers
1379        // SAFETY: Caller guarantees mmio_base is a valid, mapped xHCI MMIO region.
1380        // All reads are within the capability register space at known offsets.
1381        let cap_length = unsafe { core::ptr::read_volatile(mmio_base as *const u8) };
1382        let hci_version = unsafe {
1383            core::ptr::read_volatile((mmio_base + cap_regs::HCIVERSION as u64) as *const u16)
1384        };
1385        let hcsparams1 = unsafe {
1386            core::ptr::read_volatile((mmio_base + cap_regs::HCSPARAMS1 as u64) as *const u32)
1387        };
1388        let hccparams1 = unsafe {
1389            core::ptr::read_volatile((mmio_base + cap_regs::HCCPARAMS1 as u64) as *const u32)
1390        };
1391        let dboff =
1392            unsafe { core::ptr::read_volatile((mmio_base + cap_regs::DBOFF as u64) as *const u32) };
1393        let rtsoff = unsafe {
1394            core::ptr::read_volatile((mmio_base + cap_regs::RTSOFF as u64) as *const u32)
1395        };
1396
1397        let max_slots = (hcsparams1 & 0xFF) as u8;
1398        let max_intrs = ((hcsparams1 >> 8) & 0x7FF) as u16;
1399        let max_ports = ((hcsparams1 >> 24) & 0xFF) as u8;
1400        let context_size_64 = (hccparams1 & (1 << 2)) != 0;
1401
1402        let capabilities = XhciCapabilities {
1403            cap_length,
1404            hci_version,
1405            max_slots,
1406            max_intrs,
1407            max_ports,
1408            context_size_64,
1409            doorbell_offset: dboff & !0x3,  // Must be DWORD aligned
1410            runtime_offset: rtsoff & !0x1F, // Must be 32-byte aligned
1411        };
1412
1413        let op_base = mmio_base + cap_length as u64;
1414        let rt_base = mmio_base + capabilities.runtime_offset as u64;
1415        let db_base = mmio_base + capabilities.doorbell_offset as u64;
1416
1417        // Create command and event rings with placeholder addresses.
1418        // Real addresses will be set during init() after allocating DMA memory.
1419        let command_ring = CommandRing::new(0);
1420        let event_ring = EventRing::new(0, RING_SEGMENT_TRBS);
1421
1422        Ok(Self {
1423            mmio_base,
1424            capabilities,
1425            op_base,
1426            rt_base,
1427            db_base,
1428            command_ring,
1429            event_ring,
1430            running: false,
1431            enabled_slots: 0,
1432        })
1433    }
1434
1435    /// Non-hardware constructor for host-target testing
1436    #[cfg(not(target_os = "none"))]
1437    pub fn new_stub() -> Self {
1438        let capabilities = XhciCapabilities {
1439            cap_length: 0x20,
1440            hci_version: 0x0110,
1441            max_slots: 64,
1442            max_intrs: 8,
1443            max_ports: 4,
1444            context_size_64: false,
1445            doorbell_offset: 0x2000,
1446            runtime_offset: 0x1000,
1447        };
1448
1449        Self {
1450            mmio_base: 0,
1451            capabilities,
1452            op_base: 0x20,
1453            rt_base: 0x1000,
1454            db_base: 0x2000,
1455            command_ring: CommandRing::new(0x10_0000),
1456            event_ring: EventRing::new(0x20_0000, RING_SEGMENT_TRBS),
1457            running: false,
1458            enabled_slots: 0,
1459        }
1460    }
1461
1462    /// Get the controller capabilities
1463    pub fn capabilities(&self) -> &XhciCapabilities {
1464        &self.capabilities
1465    }
1466
1467    /// Read an operational register (32-bit)
1468    #[cfg(target_os = "none")]
1469    fn read_op_reg(&self, offset: usize) -> u32 {
1470        // SAFETY: op_base + offset is within the xHCI operational register space.
1471        unsafe { core::ptr::read_volatile((self.op_base + offset as u64) as *const u32) }
1472    }
1473
1474    #[cfg(not(target_os = "none"))]
1475    fn read_op_reg(&self, _offset: usize) -> u32 {
1476        0
1477    }
1478
1479    /// Write an operational register (32-bit)
1480    #[cfg(target_os = "none")]
1481    fn write_op_reg(&self, offset: usize, value: u32) {
1482        // SAFETY: op_base + offset is within the xHCI operational register space.
1483        unsafe { core::ptr::write_volatile((self.op_base + offset as u64) as *mut u32, value) }
1484    }
1485
1486    #[cfg(not(target_os = "none"))]
1487    fn write_op_reg(&self, _offset: usize, _value: u32) {}
1488
1489    /// Read a 64-bit operational register
1490    #[cfg(target_os = "none")]
1491    fn read_op_reg64(&self, offset: usize) -> u64 {
1492        // SAFETY: op_base + offset is within the xHCI operational register space.
1493        unsafe { core::ptr::read_volatile((self.op_base + offset as u64) as *const u64) }
1494    }
1495
1496    #[cfg(not(target_os = "none"))]
1497    fn read_op_reg64(&self, _offset: usize) -> u64 {
1498        0
1499    }
1500
1501    /// Write a 64-bit operational register
1502    #[cfg(target_os = "none")]
1503    fn write_op_reg64(&self, offset: usize, value: u64) {
1504        // SAFETY: op_base + offset is within the xHCI operational register space.
1505        unsafe { core::ptr::write_volatile((self.op_base + offset as u64) as *mut u64, value) }
1506    }
1507
1508    #[cfg(not(target_os = "none"))]
1509    fn write_op_reg64(&self, _offset: usize, _value: u64) {}
1510
1511    /// Read a PORTSC register for a given port (1-based port number)
1512    fn read_portsc(&self, port: u8) -> u32 {
1513        let offset = op_regs::PORT_REG_BASE + ((port as usize - 1) * op_regs::PORT_REG_SIZE);
1514        self.read_op_reg(offset)
1515    }
1516
1517    /// Write a PORTSC register for a given port (1-based port number)
1518    fn write_portsc(&self, port: u8, value: u32) {
1519        let offset = op_regs::PORT_REG_BASE + ((port as usize - 1) * op_regs::PORT_REG_SIZE);
1520        self.write_op_reg(offset, value);
1521    }
1522
1523    /// Ring the host controller doorbell (doorbell 0 = command ring)
1524    fn ring_doorbell(&self, slot: u8, target: u8) {
1525        let db_offset = (slot as u64) * 4;
1526        let value = target as u32;
1527        #[cfg(target_os = "none")]
1528        {
1529            // SAFETY: db_base + db_offset is within the doorbell array.
1530            unsafe {
1531                core::ptr::write_volatile((self.db_base + db_offset) as *mut u32, value);
1532            }
1533        }
1534        let _ = (db_offset, value); // suppress unused warnings on host
1535    }
1536
1537    /// Ring the command doorbell (doorbell register 0, target 0)
1538    pub fn ring_command_doorbell(&self) {
1539        self.ring_doorbell(0, 0);
1540    }
1541
1542    /// Ring a transfer doorbell for a specific endpoint on a slot
1543    pub fn ring_transfer_doorbell(&self, slot_id: u8, endpoint_id: u8) {
1544        self.ring_doorbell(slot_id, endpoint_id);
1545    }
1546
1547    /// Wait for the Controller Not Ready (CNR) flag to clear
1548    fn wait_cnr_clear(&self) -> Result<(), KernelError> {
1549        for _ in 0..10_000 {
1550            let status = self.read_op_reg(op_regs::USBSTS);
1551            if (status & usbsts_bits::CNR) == 0 {
1552                return Ok(());
1553            }
1554            core::hint::spin_loop();
1555        }
1556        Err(KernelError::Timeout {
1557            operation: "xhci_cnr_clear",
1558            duration_ms: 1000,
1559        })
1560    }
1561
1562    /// Reset the host controller
1563    pub(crate) fn reset(&mut self) -> Result<(), KernelError> {
1564        // Stop the controller first
1565        let cmd = self.read_op_reg(op_regs::USBCMD);
1566        self.write_op_reg(op_regs::USBCMD, cmd & !usbcmd_bits::RS);
1567
1568        // Wait for halt
1569        for _ in 0..10_000 {
1570            let status = self.read_op_reg(op_regs::USBSTS);
1571            if (status & usbsts_bits::HCH) != 0 {
1572                break;
1573            }
1574            core::hint::spin_loop();
1575        }
1576
1577        // Issue HCRST
1578        self.write_op_reg(op_regs::USBCMD, usbcmd_bits::HCRST);
1579
1580        // Wait for reset to complete (HCRST auto-clears)
1581        for _ in 0..10_000 {
1582            let cmd = self.read_op_reg(op_regs::USBCMD);
1583            if (cmd & usbcmd_bits::HCRST) == 0 {
1584                break;
1585            }
1586            core::hint::spin_loop();
1587        }
1588
1589        // Wait for CNR to clear
1590        self.wait_cnr_clear()?;
1591
1592        self.running = false;
1593        Ok(())
1594    }
1595
1596    /// Start the host controller (set Run/Stop bit)
1597    pub(crate) fn start(&mut self) -> Result<(), KernelError> {
1598        let cmd = self.read_op_reg(op_regs::USBCMD);
1599        self.write_op_reg(op_regs::USBCMD, cmd | usbcmd_bits::RS | usbcmd_bits::INTE);
1600
1601        // Verify it started
1602        for _ in 0..1_000 {
1603            let status = self.read_op_reg(op_regs::USBSTS);
1604            if (status & usbsts_bits::HCH) == 0 {
1605                self.running = true;
1606                return Ok(());
1607            }
1608            core::hint::spin_loop();
1609        }
1610
1611        Err(KernelError::HardwareError {
1612            device: "xhci",
1613            code: 1,
1614        })
1615    }
1616
1617    /// Stop the host controller
1618    pub(crate) fn stop(&mut self) -> Result<(), KernelError> {
1619        let cmd = self.read_op_reg(op_regs::USBCMD);
1620        self.write_op_reg(op_regs::USBCMD, cmd & !usbcmd_bits::RS);
1621
1622        for _ in 0..10_000 {
1623            let status = self.read_op_reg(op_regs::USBSTS);
1624            if (status & usbsts_bits::HCH) != 0 {
1625                self.running = false;
1626                return Ok(());
1627            }
1628            core::hint::spin_loop();
1629        }
1630
1631        Err(KernelError::Timeout {
1632            operation: "xhci_stop",
1633            duration_ms: 1000,
1634        })
1635    }
1636
1637    /// Configure the maximum number of device slots
1638    pub(crate) fn set_max_slots(&mut self, max: u8) {
1639        let max = max.min(self.capabilities.max_slots);
1640        let config = self.read_op_reg(op_regs::CONFIG);
1641        self.write_op_reg(op_regs::CONFIG, (config & !0xFF) | (max as u32));
1642        self.enabled_slots = max as u32;
1643    }
1644
1645    /// Set the Device Context Base Address Array Pointer
1646    pub(crate) fn set_dcbaap(&self, phys_addr: u64) {
1647        self.write_op_reg64(op_regs::DCBAAP, phys_addr);
1648    }
1649
1650    /// Set the Command Ring Control Register
1651    pub(crate) fn set_crcr(&self) {
1652        self.write_op_reg64(op_regs::CRCR, self.command_ring.crcr_value());
1653    }
1654
1655    /// Get port status for a given port (1-based)
1656    pub(crate) fn get_port_status(&self, port: u8) -> Result<XhciPort, KernelError> {
1657        if port == 0 || port > self.capabilities.max_ports {
1658            return Err(KernelError::InvalidArgument {
1659                name: "port",
1660                value: "out of range",
1661            });
1662        }
1663        let portsc = self.read_portsc(port);
1664        Ok(XhciPort::from_portsc(port, portsc))
1665    }
1666
1667    /// Reset a port (1-based)
1668    pub(crate) fn reset_port(&self, port: u8) -> Result<(), KernelError> {
1669        if port == 0 || port > self.capabilities.max_ports {
1670            return Err(KernelError::InvalidArgument {
1671                name: "port",
1672                value: "out of range",
1673            });
1674        }
1675
1676        let portsc = self.read_portsc(port);
1677        // Preserve RO and RW bits, set Port Reset, clear change bits
1678        let new_portsc = (portsc & !PORTSC_CHANGE_BITS) | PORTSC_PR;
1679        self.write_portsc(port, new_portsc);
1680
1681        // Wait for reset to complete (PRC bit will be set)
1682        for _ in 0..10_000 {
1683            let portsc = self.read_portsc(port);
1684            if (portsc & PORTSC_PRC) != 0 {
1685                // Clear PRC
1686                self.write_portsc(port, (portsc & !PORTSC_CHANGE_BITS) | PORTSC_PRC);
1687                return Ok(());
1688            }
1689            core::hint::spin_loop();
1690        }
1691
1692        Err(KernelError::Timeout {
1693            operation: "xhci_port_reset",
1694            duration_ms: 1000,
1695        })
1696    }
1697
1698    /// Check if a device is connected on a port (1-based)
1699    pub(crate) fn is_port_connected(&self, port: u8) -> bool {
1700        if port == 0 || port > self.capabilities.max_ports {
1701            return false;
1702        }
1703        let portsc = self.read_portsc(port);
1704        (portsc & PORTSC_CCS) != 0
1705    }
1706
1707    /// Whether the controller is currently running
1708    pub(crate) fn is_running(&self) -> bool {
1709        self.running
1710    }
1711
1712    /// Enqueue a command TRB and ring the doorbell.
1713    ///
1714    /// Returns the physical address where the command was placed.
1715    ///
1716    /// # Safety
1717    ///
1718    /// The command ring segment must be valid DMA-accessible memory.
1719    #[cfg(target_os = "none")]
1720    pub(crate) unsafe fn send_command(&mut self, trb: Trb) -> u64 {
1721        // SAFETY: Caller guarantees the command ring segment is valid DMA memory.
1722        let addr = unsafe { self.command_ring.enqueue(trb) };
1723        self.ring_command_doorbell();
1724        addr
1725    }
1726
1727    /// Non-hardware stub
1728    #[cfg(not(target_os = "none"))]
1729    pub(crate) fn send_command(&mut self, trb: Trb) -> u64 {
1730        self.command_ring.enqueue(trb)
1731    }
1732
1733    /// Poll for the next event from interrupter 0.
1734    ///
1735    /// # Safety
1736    ///
1737    /// The event ring segment must be valid memory.
1738    #[cfg(target_os = "none")]
1739    pub(crate) unsafe fn poll_event(&mut self) -> Option<Trb> {
1740        // SAFETY: Caller guarantees the event ring segment is valid memory.
1741        let event = unsafe { self.event_ring.dequeue()? };
1742        // Update ERDP to acknowledge the event
1743        let erdp = self.event_ring.erdp_value();
1744        let ir0_base = self.rt_base + rt_regs::IR0_BASE as u64;
1745        // SAFETY: Writing to the Event Ring Dequeue Pointer register.
1746        unsafe {
1747            core::ptr::write_volatile(
1748                (ir0_base + ir_regs::ERDP as u64) as *mut u64,
1749                erdp | (1 << 3), // Set EHB (Event Handler Busy) to clear
1750            );
1751        }
1752        Some(event)
1753    }
1754
1755    /// Non-hardware stub
1756    #[cfg(not(target_os = "none"))]
1757    pub(crate) fn poll_event(&mut self) -> Option<Trb> {
1758        self.event_ring.dequeue()
1759    }
1760}
1761
1762// ---------------------------------------------------------------------------
1763// MSI-X Interrupt Handling Stubs
1764// ---------------------------------------------------------------------------
1765
1766/// MSI-X capability structure offsets (within PCI config space)
1767#[derive(Debug, Clone, Copy)]
1768pub struct MsixCapability {
1769    /// Offset of the MSI-X capability in PCI config space
1770    pub cap_offset: u16,
1771    /// Table size (number of entries - 1)
1772    pub table_size: u16,
1773    /// Table BAR indicator (which BAR contains the table)
1774    pub table_bar: u8,
1775    /// Table offset within the BAR
1776    pub table_offset: u32,
1777    /// PBA (Pending Bit Array) BAR indicator
1778    pub pba_bar: u8,
1779    /// PBA offset within the BAR
1780    pub pba_offset: u32,
1781}
1782
1783/// MSI-X table entry (16 bytes per entry)
1784#[derive(Debug, Clone, Copy)]
1785#[repr(C)]
1786pub struct MsixTableEntry {
1787    /// Message Address (lower 32 bits)
1788    pub msg_addr_lo: u32,
1789    /// Message Address (upper 32 bits)
1790    pub msg_addr_hi: u32,
1791    /// Message Data
1792    pub msg_data: u32,
1793    /// Vector Control (bit 0 = mask)
1794    pub vector_control: u32,
1795}
1796
1797/// Configure MSI-X for the xHCI controller.
1798///
1799/// This is a stub that will be filled in when the full PCI MSI-X
1800/// infrastructure is available.
1801#[cfg(target_os = "none")]
1802pub fn configure_msix(
1803    _msix: &MsixCapability,
1804    _mmio_base: u64,
1805    _num_vectors: u16,
1806) -> Result<(), KernelError> {
1807    // TODO(phase7.5): Wire to actual MSI-X configuration when PCI
1808    // capability parsing is extended to support MSI-X enable/mask.
1809    crate::println!("[xHCI] MSI-X configuration stub (not yet wired)");
1810    Ok(())
1811}
1812
1813/// MSI-X interrupt handler stub.
1814///
1815/// Called from the architecture-specific interrupt dispatch when an
1816/// xHCI MSI-X vector fires.
1817#[cfg(all(target_os = "none", target_arch = "x86_64"))]
1818pub fn msix_interrupt_handler(_vector: u8) {
1819    // TODO(phase7.5): Read event ring, process events, acknowledge interrupt.
1820    // For now this is a no-op stub.
1821}
1822
1823#[cfg(all(target_os = "none", target_arch = "aarch64"))]
1824pub fn msix_interrupt_handler(_irq: u32) {
1825    // AArch64 GIC-based MSI-X handler stub
1826}
1827
1828#[cfg(all(target_os = "none", target_arch = "riscv64"))]
1829pub fn msix_interrupt_handler(_irq: u32) {
1830    // RISC-V PLIC-based MSI-X handler stub
1831}
1832
1833// ---------------------------------------------------------------------------
1834// PCI Enumeration Helpers
1835// ---------------------------------------------------------------------------
1836
1837/// Check if a PCI device is an xHCI controller
1838pub fn is_xhci_device(class_code: u8, subclass: u8, prog_if: u8) -> bool {
1839    class_code == PCI_CLASS_SERIAL_BUS && subclass == PCI_SUBCLASS_USB && prog_if == PCI_PROGIF_XHCI
1840}
1841
1842/// Scan the PCI bus for xHCI controllers and return their BAR0 addresses.
1843///
1844/// This uses the existing PCI device list from `crate::drivers::pci`.
1845#[cfg(feature = "alloc")]
1846pub fn find_xhci_controllers() -> Vec<XhciPciDevice> {
1847    #[allow(unused_mut)]
1848    let mut controllers = Vec::new();
1849
1850    // Use the PCI subsystem to iterate discovered devices
1851    #[cfg(target_os = "none")]
1852    {
1853        use crate::drivers::pci;
1854        let pci_bus = pci::get_pci_bus().lock();
1855        let devices = pci_bus.get_all_devices();
1856        for dev in &devices {
1857            if is_xhci_device(dev.class_code, dev.subclass, dev.prog_if) {
1858                let bar0_addr = dev.bars[0].get_memory_address().unwrap_or(0);
1859                controllers.push(XhciPciDevice {
1860                    bus: dev.location.bus,
1861                    device: dev.location.device,
1862                    function: dev.location.function,
1863                    vendor_id: dev.vendor_id,
1864                    device_id: dev.device_id,
1865                    bar0: bar0_addr,
1866                    irq_line: dev.interrupt_line,
1867                });
1868            }
1869        }
1870    }
1871
1872    controllers
1873}
1874
1875/// Information about a discovered xHCI PCI device
1876#[derive(Debug, Clone, Copy)]
1877pub struct XhciPciDevice {
1878    pub bus: u8,
1879    pub device: u8,
1880    pub function: u8,
1881    pub vendor_id: u16,
1882    pub device_id: u16,
1883    /// BAR0 physical address (MMIO base)
1884    pub bar0: u64,
1885    /// IRQ line from PCI config
1886    pub irq_line: u8,
1887}
1888
1889// ---------------------------------------------------------------------------
1890// Global State
1891// ---------------------------------------------------------------------------
1892
1893static XHCI_INITIALIZED: AtomicBool = AtomicBool::new(false);
1894static XHCI_CONTROLLER_COUNT: AtomicU32 = AtomicU32::new(0);
1895
1896/// Initialize the xHCI subsystem.
1897///
1898/// Scans PCI for xHCI controllers, resets and configures each one.
1899pub fn init() {
1900    if XHCI_INITIALIZED.swap(true, Ordering::SeqCst) {
1901        return; // Already initialized
1902    }
1903
1904    crate::println!("[xHCI] Scanning for xHCI USB 3.x controllers...");
1905
1906    #[cfg(feature = "alloc")]
1907    {
1908        let devices = find_xhci_controllers();
1909        let count = devices.len();
1910
1911        for dev in &devices {
1912            crate::println!(
1913                "[xHCI] Found controller at PCI {:02x}:{:02x}.{} (vendor={:04x} device={:04x}) \
1914                 BAR0=0x{:08x}",
1915                dev.bus,
1916                dev.device,
1917                dev.function,
1918                dev.vendor_id,
1919                dev.device_id,
1920                dev.bar0,
1921            );
1922        }
1923
1924        XHCI_CONTROLLER_COUNT.store(count as u32, Ordering::SeqCst);
1925
1926        if count == 0 {
1927            crate::println!("[xHCI] No xHCI controllers found");
1928        } else {
1929            crate::println!("[xHCI] Found {} xHCI controller(s)", count);
1930        }
1931    }
1932
1933    #[cfg(not(feature = "alloc"))]
1934    {
1935        crate::println!("[xHCI] xHCI init skipped (alloc feature not enabled)");
1936    }
1937}
1938
1939/// Check if the xHCI subsystem has been initialized
1940pub fn is_initialized() -> bool {
1941    XHCI_INITIALIZED.load(Ordering::SeqCst)
1942}
1943
1944/// Get the number of discovered xHCI controllers
1945pub fn controller_count() -> u32 {
1946    XHCI_CONTROLLER_COUNT.load(Ordering::SeqCst)
1947}
1948
1949// ---------------------------------------------------------------------------
1950// Unit Tests
1951// ---------------------------------------------------------------------------
1952
1953#[cfg(test)]
1954mod tests {
1955    #[cfg(feature = "alloc")]
1956    #[allow(unused_imports)]
1957    use alloc::vec;
1958
1959    use super::*;
1960
1961    // -- TRB construction tests --
1962
1963    #[test]
1964    fn test_trb_zeroed() {
1965        let trb = Trb::zeroed();
1966        assert_eq!(trb.parameter_lo, 0);
1967        assert_eq!(trb.parameter_hi, 0);
1968        assert_eq!(trb.status, 0);
1969        assert_eq!(trb.control, 0);
1970        assert_eq!(trb.trb_type(), 0);
1971        assert!(!trb.cycle_bit());
1972    }
1973
1974    #[test]
1975    fn test_trb_type_field() {
1976        let mut trb = Trb::zeroed();
1977        trb.set_trb_type(TRB_TYPE_NORMAL);
1978        assert_eq!(trb.trb_type(), TRB_TYPE_NORMAL);
1979
1980        trb.set_trb_type(TRB_TYPE_COMMAND_COMPLETION);
1981        assert_eq!(trb.trb_type(), TRB_TYPE_COMMAND_COMPLETION);
1982
1983        // Max 6-bit value
1984        trb.set_trb_type(63);
1985        assert_eq!(trb.trb_type(), 63);
1986    }
1987
1988    #[test]
1989    fn test_trb_cycle_bit() {
1990        let mut trb = Trb::zeroed();
1991        assert!(!trb.cycle_bit());
1992
1993        trb.set_cycle_bit(true);
1994        assert!(trb.cycle_bit());
1995
1996        trb.set_cycle_bit(false);
1997        assert!(!trb.cycle_bit());
1998    }
1999
2000    #[test]
2001    fn test_trb_slot_id() {
2002        let mut trb = Trb::zeroed();
2003        trb.set_slot_id(42);
2004        assert_eq!(trb.slot_id(), 42);
2005
2006        trb.set_slot_id(255);
2007        assert_eq!(trb.slot_id(), 255);
2008    }
2009
2010    #[test]
2011    fn test_trb_transfer_length() {
2012        let mut trb = Trb::zeroed();
2013        trb.set_transfer_length(1024);
2014        assert_eq!(trb.transfer_length(), 1024);
2015
2016        // Max 17-bit value
2017        trb.set_transfer_length(0x1FFFF);
2018        assert_eq!(trb.transfer_length(), 0x1FFFF);
2019
2020        // Overflow clamped
2021        trb.set_transfer_length(0xFFFFFFFF);
2022        assert_eq!(trb.transfer_length(), 0x1FFFF);
2023    }
2024
2025    #[test]
2026    fn test_trb_normal() {
2027        let trb = Trb::normal(0x1000_0000, 512, true, true);
2028        assert_eq!(trb.trb_type(), TRB_TYPE_NORMAL);
2029        assert_eq!(trb.parameter_lo, 0x1000_0000);
2030        assert_eq!(trb.parameter_hi, 0);
2031        assert_eq!(trb.transfer_length(), 512);
2032        assert!(trb.cycle_bit());
2033        assert_ne!(trb.control & TRB_IOC, 0);
2034    }
2035
2036    #[test]
2037    fn test_trb_setup_stage() {
2038        let trb = Trb::setup_stage(
2039            USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
2040            USB_REQ_GET_DESCRIPTOR,
2041            (DESC_TYPE_DEVICE as u16) << 8,
2042            0,
2043            18,
2044            SetupTransferType::In,
2045            true,
2046        );
2047        assert_eq!(trb.trb_type(), TRB_TYPE_SETUP_STAGE);
2048        assert!(trb.cycle_bit());
2049        assert_ne!(trb.control & TRB_IDT, 0); // Immediate Data set
2050        assert_eq!(trb.status, 8); // 8 bytes setup packet
2051    }
2052
2053    #[test]
2054    fn test_trb_link() {
2055        let trb = Trb::link(0x2000_0000, true, true);
2056        assert_eq!(trb.trb_type(), TRB_TYPE_LINK);
2057        assert_eq!(trb.parameter_lo, 0x2000_0000);
2058        assert!(trb.cycle_bit());
2059        assert_ne!(trb.control & TRB_TOGGLE_CYCLE, 0);
2060    }
2061
2062    #[test]
2063    fn test_trb_enable_slot() {
2064        let trb = Trb::enable_slot(true);
2065        assert_eq!(trb.trb_type(), TRB_TYPE_ENABLE_SLOT);
2066        assert!(trb.cycle_bit());
2067    }
2068
2069    #[test]
2070    fn test_trb_address_device() {
2071        let trb = Trb::address_device(0xDEAD_0000, 5, true, false);
2072        assert_eq!(trb.trb_type(), TRB_TYPE_ADDRESS_DEVICE);
2073        assert_eq!(trb.slot_id(), 5);
2074        assert!(!trb.cycle_bit());
2075        assert_ne!(trb.control & TRB_BSR, 0);
2076        assert_eq!(trb.parameter_lo, 0xDEAD_0000);
2077    }
2078
2079    #[test]
2080    fn test_trb_configure_endpoint() {
2081        let trb = Trb::configure_endpoint(0xBEEF_0000, 3, false, true);
2082        assert_eq!(trb.trb_type(), TRB_TYPE_CONFIGURE_ENDPOINT);
2083        assert_eq!(trb.slot_id(), 3);
2084        assert!(trb.cycle_bit());
2085    }
2086
2087    // -- Ring state tests --
2088
2089    #[test]
2090    fn test_ring_state_advance() {
2091        let mut state = RingState::new(0x1000, 4);
2092        assert_eq!(state.index, 0);
2093        assert!(state.cycle);
2094
2095        state.advance();
2096        assert_eq!(state.index, 1);
2097        assert!(state.cycle);
2098
2099        state.advance();
2100        state.advance();
2101        state.advance(); // index 3 -> wraps to 0
2102        assert_eq!(state.index, 0);
2103        assert!(!state.cycle); // Toggled
2104    }
2105
2106    #[test]
2107    fn test_ring_state_current_trb_phys() {
2108        let state = RingState::new(0x4000, 256);
2109        assert_eq!(state.current_trb_phys(), 0x4000);
2110
2111        let mut state2 = RingState::new(0x4000, 256);
2112        state2.advance();
2113        assert_eq!(state2.current_trb_phys(), 0x4000 + TRB_SIZE as u64);
2114    }
2115
2116    #[test]
2117    fn test_command_ring_crcr() {
2118        let ring = CommandRing::new(0x10000);
2119        // Initial cycle = true, so CRCR should have bit 0 set
2120        assert_eq!(ring.crcr_value(), 0x10001);
2121    }
2122
2123    // -- Port parsing tests --
2124
2125    #[test]
2126    fn test_port_from_portsc() {
2127        let portsc = PORTSC_CCS | PORTSC_PED | PORTSC_PP | (PORT_SPEED_SUPER << PORTSC_SPEED_SHIFT);
2128        let port = XhciPort::from_portsc(1, portsc);
2129        assert!(port.connected);
2130        assert!(port.enabled);
2131        assert!(port.powered);
2132        assert!(!port.resetting);
2133        assert_eq!(port.speed, PortSpeed::Super);
2134    }
2135
2136    #[test]
2137    fn test_port_speed_conversion() {
2138        assert_eq!(PortSpeed::from_portsc(PORT_SPEED_FULL), PortSpeed::Full);
2139        assert_eq!(PortSpeed::from_portsc(PORT_SPEED_LOW), PortSpeed::Low);
2140        assert_eq!(PortSpeed::from_portsc(PORT_SPEED_HIGH), PortSpeed::High);
2141        assert_eq!(PortSpeed::from_portsc(PORT_SPEED_SUPER), PortSpeed::Super);
2142        assert_eq!(
2143            PortSpeed::from_portsc(PORT_SPEED_SUPER_PLUS),
2144            PortSpeed::SuperPlus
2145        );
2146        assert_eq!(PortSpeed::from_portsc(99), PortSpeed::Unknown);
2147    }
2148
2149    #[test]
2150    fn test_port_speed_max_packet() {
2151        assert_eq!(PortSpeed::Low.default_max_packet_size_ep0(), 8);
2152        assert_eq!(PortSpeed::Full.default_max_packet_size_ep0(), 8);
2153        assert_eq!(PortSpeed::High.default_max_packet_size_ep0(), 64);
2154        assert_eq!(PortSpeed::Super.default_max_packet_size_ep0(), 512);
2155    }
2156
2157    // -- Descriptor parsing tests --
2158
2159    #[test]
2160    fn test_device_descriptor_parse() {
2161        let mut data = [0u8; 18];
2162        data[0] = 18; // bLength
2163        data[1] = DESC_TYPE_DEVICE; // bDescriptorType
2164        data[2] = 0x00;
2165        data[3] = 0x03; // bcdUSB = 3.00
2166        data[4] = 0x09; // bDeviceClass (Hub)
2167        data[7] = 64; // bMaxPacketSize0
2168        data[8] = 0x34;
2169        data[9] = 0x12; // idVendor = 0x1234
2170        data[10] = 0x78;
2171        data[11] = 0x56; // idProduct = 0x5678
2172        data[17] = 2; // bNumConfigurations
2173
2174        let desc = XhciDeviceDescriptor::parse(&data).unwrap();
2175        assert_eq!(desc.usb_version, 0x0300);
2176        assert_eq!(desc.device_class, 0x09);
2177        assert_eq!(desc.max_packet_size_ep0, 64);
2178        assert_eq!(desc.vendor_id, 0x1234);
2179        assert_eq!(desc.product_id, 0x5678);
2180        assert_eq!(desc.num_configurations, 2);
2181    }
2182
2183    #[test]
2184    fn test_device_descriptor_too_short() {
2185        let data = [0u8; 10];
2186        assert!(XhciDeviceDescriptor::parse(&data).is_err());
2187    }
2188
2189    #[test]
2190    fn test_device_descriptor_wrong_type() {
2191        let mut data = [0u8; 18];
2192        data[1] = DESC_TYPE_CONFIGURATION; // Wrong type
2193        assert!(XhciDeviceDescriptor::parse(&data).is_err());
2194    }
2195
2196    #[test]
2197    fn test_config_descriptor_parse() {
2198        let mut data = [0u8; 9];
2199        data[0] = 9; // bLength
2200        data[1] = DESC_TYPE_CONFIGURATION; // bDescriptorType
2201        data[2] = 32;
2202        data[3] = 0; // wTotalLength = 32
2203        data[4] = 1; // bNumInterfaces
2204        data[5] = 1; // bConfigurationValue
2205        data[7] = 0x60; // bmAttributes (self-powered + remote wakeup)
2206        data[8] = 50; // bMaxPower (50 * 2 = 100 mA)
2207
2208        let desc = XhciConfigDescriptor::parse(&data).unwrap();
2209        assert_eq!(desc.total_length, 32);
2210        assert_eq!(desc.num_interfaces, 1);
2211        assert_eq!(desc.config_value, 1);
2212        assert_eq!(desc.max_power_ma, 100);
2213        assert!(desc.is_self_powered());
2214        assert!(desc.supports_remote_wakeup());
2215    }
2216
2217    #[test]
2218    fn test_endpoint_descriptor_parse() {
2219        let mut data = [0u8; 7];
2220        data[0] = 7; // bLength
2221        data[1] = DESC_TYPE_ENDPOINT; // bDescriptorType
2222        data[2] = 0x81; // bEndpointAddress (EP1 IN)
2223        data[3] = 0x02; // bmAttributes (Bulk)
2224        data[4] = 0x00;
2225        data[5] = 0x02; // wMaxPacketSize = 512
2226        data[6] = 0; // bInterval
2227
2228        let ep = XhciEndpointDescriptor::parse(&data).unwrap();
2229        assert!(ep.is_in());
2230        assert_eq!(ep.endpoint_number(), 1);
2231        assert_eq!(ep.transfer_type(), EndpointTransferType::Bulk);
2232        assert_eq!(ep.max_packet_size, 512);
2233    }
2234
2235    #[test]
2236    fn test_interface_descriptor_parse() {
2237        let mut data = [0u8; 9];
2238        data[0] = 9;
2239        data[1] = DESC_TYPE_INTERFACE;
2240        data[2] = 0; // bInterfaceNumber
2241        data[4] = 2; // bNumEndpoints
2242        data[5] = 0x08; // bInterfaceClass (Mass Storage)
2243        data[6] = 0x06; // bInterfaceSubClass (SCSI)
2244        data[7] = 0x50; // bInterfaceProtocol (Bulk-Only)
2245
2246        let iface = XhciInterfaceDescriptor::parse(&data).unwrap();
2247        assert_eq!(iface.interface_number, 0);
2248        assert_eq!(iface.num_endpoints, 2);
2249        assert_eq!(iface.interface_class, 0x08);
2250        assert_eq!(iface.interface_subclass, 0x06);
2251        assert_eq!(iface.interface_protocol, 0x50);
2252    }
2253
2254    // -- PCI identification test --
2255
2256    #[test]
2257    fn test_is_xhci_device() {
2258        assert!(is_xhci_device(0x0C, 0x03, 0x30));
2259        assert!(!is_xhci_device(0x0C, 0x03, 0x00)); // UHCI
2260        assert!(!is_xhci_device(0x0C, 0x03, 0x10)); // OHCI
2261        assert!(!is_xhci_device(0x0C, 0x03, 0x20)); // EHCI
2262        assert!(!is_xhci_device(0x02, 0x00, 0x00)); // Network
2263    }
2264
2265    // -- Completion code test --
2266
2267    #[test]
2268    fn test_trb_completion_code() {
2269        let mut trb = Trb::zeroed();
2270        trb.status = (TRB_COMPLETION_SUCCESS as u32) << 24;
2271        assert_eq!(trb.completion_code(), TRB_COMPLETION_SUCCESS);
2272
2273        trb.status = (TRB_COMPLETION_STALL as u32) << 24 | 0x00FF_FFFF;
2274        assert_eq!(trb.completion_code(), TRB_COMPLETION_STALL);
2275    }
2276
2277    // -- Slot state test --
2278
2279    #[test]
2280    fn test_slot_state_transitions() {
2281        let slot = DeviceSlot {
2282            slot_id: 1,
2283            state: SlotState::Disabled,
2284            port_number: 1,
2285            speed: PortSpeed::Super,
2286            device_context_phys: 0,
2287            input_context_phys: 0,
2288        };
2289        assert_eq!(slot.state, SlotState::Disabled);
2290    }
2291
2292    // -- Configuration descriptor parsing (alloc) --
2293
2294    #[cfg(feature = "alloc")]
2295    #[test]
2296    fn test_parse_configuration_descriptors() {
2297        // Build a minimal config descriptor with 1 interface and 1 endpoint
2298        let mut data = vec![0u8; 32];
2299
2300        // Config descriptor (9 bytes)
2301        data[0] = 9;
2302        data[1] = DESC_TYPE_CONFIGURATION;
2303        data[2] = 25;
2304        data[3] = 0; // wTotalLength = 25
2305        data[4] = 1; // bNumInterfaces
2306        data[5] = 1; // bConfigurationValue
2307
2308        // Interface descriptor (9 bytes) at offset 9
2309        data[9] = 9;
2310        data[10] = DESC_TYPE_INTERFACE;
2311        data[11] = 0; // bInterfaceNumber
2312        data[13] = 1; // bNumEndpoints
2313        data[14] = 0x03; // bInterfaceClass (HID)
2314
2315        // Endpoint descriptor (7 bytes) at offset 18
2316        data[18] = 7;
2317        data[19] = DESC_TYPE_ENDPOINT;
2318        data[20] = 0x81; // EP1 IN
2319        data[21] = 0x03; // Interrupt
2320        data[22] = 8;
2321        data[23] = 0; // wMaxPacketSize = 8
2322        data[24] = 10; // bInterval
2323
2324        let (config, interfaces) = parse_configuration_descriptors(&data).unwrap();
2325        assert_eq!(config.num_interfaces, 1);
2326        assert_eq!(interfaces.len(), 1);
2327        assert_eq!(interfaces[0].0.interface_class, 0x03);
2328        assert_eq!(interfaces[0].1.len(), 1);
2329        assert_eq!(interfaces[0].1[0].endpoint_number(), 1);
2330        assert!(interfaces[0].1[0].is_in());
2331        assert_eq!(
2332            interfaces[0].1[0].transfer_type(),
2333            EndpointTransferType::Interrupt
2334        );
2335    }
2336
2337    // -- Transfer ring (host stub) test --
2338
2339    #[test]
2340    fn test_transfer_ring_enqueue_control() {
2341        let mut ring = TransferRing::new(0x5_0000);
2342        let _addr = ring.enqueue_control(
2343            USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
2344            USB_REQ_GET_DESCRIPTOR,
2345            (DESC_TYPE_DEVICE as u16) << 8,
2346            0,
2347            0x6_0000,
2348            18,
2349        );
2350        // After enqueueing Setup + Data + Status = 3 TRBs, index should be 3
2351        assert_eq!(ring.state.index, 3);
2352    }
2353
2354    // -- Event ring (host stub) test --
2355
2356    #[test]
2357    fn test_event_ring_dequeue_empty() {
2358        let mut ring = EventRing::new(0x7_0000, 256);
2359        assert!(ring.dequeue().is_none());
2360    }
2361
2362    // -- XhciController stub test --
2363
2364    #[test]
2365    fn test_xhci_controller_stub() {
2366        let ctrl = XhciController::new_stub();
2367        assert_eq!(ctrl.capabilities().max_slots, 64);
2368        assert_eq!(ctrl.capabilities().max_ports, 4);
2369        assert_eq!(ctrl.capabilities().hci_version, 0x0110);
2370        assert!(!ctrl.is_running());
2371    }
2372}