1#![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
20const PCI_CLASS_SERIAL_BUS: u8 = 0x0C;
26const PCI_SUBCLASS_USB: u8 = 0x03;
28const PCI_PROGIF_XHCI: u8 = 0x30;
30
31const MAX_DEVICE_SLOTS: usize = 256;
33const MAX_PORTS: usize = 256;
35const MAX_INTERRUPTERS: usize = 1024;
37
38const TRB_SIZE: usize = 16;
40const RING_SEGMENT_TRBS: usize = 256;
42const RING_SEGMENT_SIZE: usize = RING_SEGMENT_TRBS * TRB_SIZE;
44
45const DESC_TYPE_DEVICE: u8 = 0x01;
51const DESC_TYPE_CONFIGURATION: u8 = 0x02;
53const DESC_TYPE_STRING: u8 = 0x03;
55const DESC_TYPE_INTERFACE: u8 = 0x04;
57const DESC_TYPE_ENDPOINT: u8 = 0x05;
59const DESC_TYPE_DEVICE_QUALIFIER: u8 = 0x06;
61const DESC_TYPE_BOS: u8 = 0x0F;
63const DESC_TYPE_SS_EP_COMPANION: u8 = 0x30;
65
66const USB_REQ_GET_STATUS: u8 = 0x00;
72const USB_REQ_CLEAR_FEATURE: u8 = 0x01;
74const USB_REQ_SET_FEATURE: u8 = 0x03;
76const USB_REQ_SET_ADDRESS: u8 = 0x05;
78const USB_REQ_GET_DESCRIPTOR: u8 = 0x06;
80const USB_REQ_SET_DESCRIPTOR: u8 = 0x07;
82const USB_REQ_GET_CONFIGURATION: u8 = 0x08;
84const USB_REQ_SET_CONFIGURATION: u8 = 0x09;
86
87const USB_DIR_OUT: u8 = 0x00;
93const USB_DIR_IN: u8 = 0x80;
95const USB_TYPE_STANDARD: u8 = 0x00;
97const USB_TYPE_CLASS: u8 = 0x20;
99const USB_TYPE_VENDOR: u8 = 0x40;
101const USB_RECIP_DEVICE: u8 = 0x00;
103const USB_RECIP_INTERFACE: u8 = 0x01;
105const USB_RECIP_ENDPOINT: u8 = 0x02;
107
108const TRB_TYPE_NORMAL: u8 = 1;
114const TRB_TYPE_SETUP_STAGE: u8 = 2;
116const TRB_TYPE_DATA_STAGE: u8 = 3;
118const TRB_TYPE_STATUS_STAGE: u8 = 4;
120const TRB_TYPE_ISOCH: u8 = 5;
122const TRB_TYPE_LINK: u8 = 6;
124const TRB_TYPE_EVENT_DATA: u8 = 7;
126const TRB_TYPE_NOOP: u8 = 8;
128const TRB_TYPE_ENABLE_SLOT: u8 = 9;
130const TRB_TYPE_DISABLE_SLOT: u8 = 10;
132const TRB_TYPE_ADDRESS_DEVICE: u8 = 11;
134const TRB_TYPE_CONFIGURE_ENDPOINT: u8 = 12;
136const TRB_TYPE_EVALUATE_CONTEXT: u8 = 13;
138const TRB_TYPE_RESET_ENDPOINT: u8 = 14;
140const TRB_TYPE_STOP_ENDPOINT: u8 = 15;
142const TRB_TYPE_SET_TR_DEQUEUE: u8 = 16;
144const TRB_TYPE_RESET_DEVICE: u8 = 17;
146const TRB_TYPE_NOOP_CMD: u8 = 23;
148
149const TRB_TYPE_TRANSFER_EVENT: u8 = 32;
152const TRB_TYPE_COMMAND_COMPLETION: u8 = 33;
154const TRB_TYPE_PORT_STATUS_CHANGE: u8 = 34;
156const TRB_TYPE_BANDWIDTH_REQUEST: u8 = 35;
158const TRB_TYPE_HOST_CONTROLLER: u8 = 37;
160
161const TRB_COMPLETION_INVALID: u8 = 0;
167const TRB_COMPLETION_SUCCESS: u8 = 1;
169const TRB_COMPLETION_DATA_BUFFER_ERROR: u8 = 2;
171const TRB_COMPLETION_BABBLE: u8 = 3;
173const TRB_COMPLETION_USB_TRANSACTION_ERROR: u8 = 4;
175const TRB_COMPLETION_TRB_ERROR: u8 = 5;
177const TRB_COMPLETION_STALL: u8 = 6;
179const TRB_COMPLETION_SHORT_PACKET: u8 = 13;
181const TRB_COMPLETION_COMMAND_RING_STOPPED: u8 = 24;
183const TRB_COMPLETION_COMMAND_ABORTED: u8 = 25;
185
186const TRB_CYCLE_BIT: u32 = 1 << 0;
192const TRB_TOGGLE_CYCLE: u32 = 1 << 1;
194const TRB_ISP: u32 = 1 << 2;
196const TRB_NO_SNOOP: u32 = 1 << 3;
198const TRB_CHAIN: u32 = 1 << 4;
200const TRB_IOC: u32 = 1 << 5;
202const TRB_IDT: u32 = 1 << 6;
204const TRB_BSR: u32 = 1 << 9;
206
207const PORTSC_CCS: u32 = 1 << 0;
213const PORTSC_PED: u32 = 1 << 1;
215const PORTSC_OCA: u32 = 1 << 3;
217const PORTSC_PR: u32 = 1 << 4;
219const PORTSC_PLS_MASK: u32 = 0xF << 5;
221const PORTSC_PP: u32 = 1 << 9;
223const PORTSC_SPEED_MASK: u32 = 0xF << 10;
225const PORTSC_SPEED_SHIFT: u32 = 10;
227const PORTSC_CSC: u32 = 1 << 17;
229const PORTSC_PEC: u32 = 1 << 18;
231const PORTSC_WRC: u32 = 1 << 19;
233const PORTSC_OCC: u32 = 1 << 20;
235const PORTSC_PRC: u32 = 1 << 21;
237const PORTSC_PLC: u32 = 1 << 22;
239const PORTSC_CEC: u32 = 1 << 23;
241const PORTSC_CHANGE_BITS: u32 =
243 PORTSC_CSC | PORTSC_PEC | PORTSC_WRC | PORTSC_OCC | PORTSC_PRC | PORTSC_PLC | PORTSC_CEC;
244
245const PORT_SPEED_FULL: u32 = 1;
247const PORT_SPEED_LOW: u32 = 2;
249const PORT_SPEED_HIGH: u32 = 3;
251const PORT_SPEED_SUPER: u32 = 4;
253const PORT_SPEED_SUPER_PLUS: u32 = 5;
255
256mod cap_regs {
262 pub const CAPLENGTH: usize = 0x00;
264 pub const HCIVERSION: usize = 0x02;
266 pub const HCSPARAMS1: usize = 0x04;
268 pub const HCSPARAMS2: usize = 0x08;
270 pub const HCSPARAMS3: usize = 0x0C;
272 pub const HCCPARAMS1: usize = 0x10;
274 pub const DBOFF: usize = 0x14;
276 pub const RTSOFF: usize = 0x18;
278 pub const HCCPARAMS2: usize = 0x1C;
280}
281
282mod op_regs {
285 pub const USBCMD: usize = 0x00;
287 pub const USBSTS: usize = 0x04;
289 pub const PAGESIZE: usize = 0x08;
291 pub const DNCTRL: usize = 0x14;
293 pub const CRCR: usize = 0x18;
295 pub const DCBAAP: usize = 0x30;
297 pub const CONFIG: usize = 0x38;
299 pub const PORT_REG_BASE: usize = 0x400;
301 pub const PORT_REG_SIZE: usize = 0x10;
303}
304
305mod usbcmd_bits {
307 pub const RS: u32 = 1 << 0;
309 pub const HCRST: u32 = 1 << 1;
311 pub const INTE: u32 = 1 << 2;
313 pub const HSEE: u32 = 1 << 3;
315 pub const LHCRST: u32 = 1 << 5;
317 pub const CSS: u32 = 1 << 8;
319 pub const CRS: u32 = 1 << 9;
321 pub const EWE: u32 = 1 << 10;
323}
324
325mod usbsts_bits {
327 pub const HCH: u32 = 1 << 0;
329 pub const HSE: u32 = 1 << 2;
331 pub const EINT: u32 = 1 << 3;
333 pub const PCD: u32 = 1 << 4;
335 pub const CNR: u32 = 1 << 11;
337 pub const HCE: u32 = 1 << 12;
339}
340
341mod rt_regs {
343 pub const MFINDEX: usize = 0x00;
345 pub const IR0_BASE: usize = 0x20;
347 pub const IR_SIZE: usize = 0x20;
349}
350
351mod ir_regs {
353 pub const IMAN: usize = 0x00;
355 pub const IMOD: usize = 0x04;
357 pub const ERSTSZ: usize = 0x08;
359 pub const ERSTBA: usize = 0x10;
361 pub const ERDP: usize = 0x18;
363}
364
365#[derive(Debug, Clone, Copy, PartialEq, Eq)]
373#[repr(C, align(16))]
374pub struct Trb {
375 pub parameter_lo: u32,
377 pub parameter_hi: u32,
379 pub status: u32,
381 pub control: u32,
383}
384
385impl Trb {
386 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 pub fn trb_type(&self) -> u8 {
398 ((self.control >> 10) & 0x3F) as u8
399 }
400
401 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 pub fn cycle_bit(&self) -> bool {
408 (self.control & TRB_CYCLE_BIT) != 0
409 }
410
411 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 pub fn completion_code(&self) -> u8 {
422 ((self.status >> 24) & 0xFF) as u8
423 }
424
425 pub fn slot_id(&self) -> u8 {
427 ((self.control >> 24) & 0xFF) as u8
428 }
429
430 pub fn set_slot_id(&mut self, slot: u8) {
432 self.control = (self.control & !(0xFF << 24)) | ((slot as u32) << 24);
433 }
434
435 pub fn transfer_length(&self) -> u32 {
437 self.status & 0x1FFFF
438 }
439
440 pub fn set_transfer_length(&mut self, len: u32) {
442 self.status = (self.status & !0x1FFFF) | (len & 0x1FFFF);
443 }
444
445 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 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 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; trb.set_trb_type(TRB_TYPE_SETUP_STAGE);
475 trb.set_cycle_bit(cycle);
476 trb.control |= TRB_IDT; trb.control |= (transfer_type as u32) << 16;
479 trb
480 }
481
482 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; }
493 trb
494 }
495
496 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; }
504 if ioc {
505 trb.control |= TRB_IOC;
506 }
507 trb
508 }
509
510 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 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 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 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 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 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 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; }
594 trb
595 }
596
597 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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
608#[repr(u32)]
609pub enum SetupTransferType {
610 NoData = 0,
612 Out = 2,
614 In = 3,
616}
617
618#[derive(Debug, Clone, Copy, PartialEq, Eq)]
624pub struct RingState {
625 pub segment_phys: u64,
627 pub index: usize,
629 pub cycle: bool,
631 pub capacity: usize,
633}
634
635impl RingState {
636 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 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 pub fn current_trb_phys(&self) -> u64 {
657 self.segment_phys + (self.index as u64) * (TRB_SIZE as u64)
658 }
659}
660
661pub struct CommandRing {
663 state: RingState,
664}
665
666impl CommandRing {
667 pub fn new(segment_phys: u64) -> Self {
669 Self {
670 state: RingState::new(segment_phys, RING_SEGMENT_TRBS - 1),
671 }
672 }
673
674 #[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 unsafe {
690 core::ptr::write_volatile(addr as *mut Trb, trb);
691 }
692
693 self.state.advance();
694
695 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 unsafe {
702 core::ptr::write_volatile(link_addr as *mut Trb, link);
703 }
704 }
705
706 addr
707 }
708
709 #[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 pub fn crcr_value(&self) -> u64 {
720 self.state.segment_phys | if self.state.cycle { 1 } else { 0 }
721 }
722}
723
724#[derive(Debug, Clone, Copy)]
726#[repr(C, align(64))]
727pub struct EventRingSegmentTableEntry {
728 pub base_address: u64,
730 pub size: u16,
732 pub _reserved0: u16,
734 pub _reserved1: u32,
736}
737
738pub struct EventRing {
740 state: RingState,
741}
742
743impl EventRing {
744 pub fn new(segment_phys: u64, capacity: usize) -> Self {
746 Self {
747 state: RingState::new(segment_phys, capacity),
748 }
749 }
750
751 #[cfg(target_os = "none")]
760 pub unsafe fn dequeue(&mut self) -> Option<Trb> {
761 let addr = self.state.current_trb_phys();
762 let trb = unsafe { core::ptr::read_volatile(addr as *const Trb) };
764
765 if trb.cycle_bit() != self.state.cycle {
766 return None; }
768
769 self.state.advance();
770 Some(trb)
771 }
772
773 #[cfg(not(target_os = "none"))]
775 pub fn dequeue(&mut self) -> Option<Trb> {
776 None
777 }
778
779 pub fn erdp_value(&self) -> u64 {
781 self.state.current_trb_phys()
782 }
783}
784
785pub struct TransferRing {
787 state: RingState,
788}
789
790impl TransferRing {
791 pub fn new(segment_phys: u64) -> Self {
793 Self {
794 state: RingState::new(segment_phys, RING_SEGMENT_TRBS - 1),
795 }
796 }
797
798 #[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 unsafe {
810 core::ptr::write_volatile(addr as *mut Trb, trb);
811 }
812
813 self.state.advance();
814
815 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 unsafe {
822 core::ptr::write_volatile(link_addr as *mut Trb, link);
823 }
824 }
825
826 addr
827 }
828
829 #[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 #[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 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 unsafe {
877 self.enqueue(setup);
878 }
879
880 if data_len > 0 {
882 let data = Trb::data_stage(data_phys, data_len as u32, direction_in, self.state.cycle);
883 unsafe {
885 self.enqueue(data);
886 }
887 }
888
889 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 unsafe { self.enqueue(status) }
894 }
895
896 #[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 pub fn base_phys(&self) -> u64 {
939 self.state.segment_phys
940 }
941}
942
943#[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 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#[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 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, })
1030 }
1031
1032 pub fn is_self_powered(&self) -> bool {
1034 (self.attributes & (1 << 6)) != 0
1035 }
1036
1037 pub fn supports_remote_wakeup(&self) -> bool {
1039 (self.attributes & (1 << 5)) != 0
1040 }
1041}
1042
1043#[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 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#[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 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 pub fn is_in(&self) -> bool {
1116 (self.endpoint_address & 0x80) != 0
1117 }
1118
1119 pub fn endpoint_number(&self) -> u8 {
1121 self.endpoint_address & 0x0F
1122 }
1123
1124 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#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1138pub enum EndpointTransferType {
1139 Control = 0,
1140 Isochronous = 1,
1141 Bulk = 2,
1142 Interrupt = 3,
1143}
1144
1145#[cfg(feature = "alloc")]
1147pub type InterfaceWithEndpoints = (XhciInterfaceDescriptor, Vec<XhciEndpointDescriptor>);
1148
1149#[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; 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 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 _ => {} }
1195
1196 offset += desc_len;
1197 }
1198
1199 if let Some(iface) = current_iface {
1201 interfaces.push((iface, current_endpoints));
1202 }
1203
1204 Ok((config, interfaces))
1205}
1206
1207#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1213pub enum SlotState {
1214 Disabled,
1216 Enabled,
1218 Default,
1220 Addressed,
1222 Configured,
1224}
1225
1226#[derive(Debug)]
1228pub struct DeviceSlot {
1229 pub slot_id: u8,
1231 pub state: SlotState,
1233 pub port_number: u8,
1235 pub speed: PortSpeed,
1237 pub device_context_phys: u64,
1239 pub input_context_phys: u64,
1241}
1242
1243#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1245pub enum PortSpeed {
1246 Full,
1248 Low,
1250 High,
1252 Super,
1254 SuperPlus,
1256 Unknown,
1258}
1259
1260impl PortSpeed {
1261 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 pub fn default_max_packet_size_ep0(&self) -> u16 {
1275 match self {
1276 Self::Low => 8,
1277 Self::Full => 8, Self::High => 64,
1279 Self::Super | Self::SuperPlus => 512,
1280 Self::Unknown => 8,
1281 }
1282 }
1283}
1284
1285#[derive(Debug, Clone, Copy)]
1291pub struct XhciPort {
1292 pub number: u8,
1294 pub connected: bool,
1296 pub enabled: bool,
1298 pub speed: PortSpeed,
1300 pub powered: bool,
1302 pub resetting: bool,
1304}
1305
1306impl XhciPort {
1307 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#[derive(Debug, Clone, Copy)]
1327pub struct XhciCapabilities {
1328 pub cap_length: u8,
1330 pub hci_version: u16,
1332 pub max_slots: u8,
1334 pub max_intrs: u16,
1336 pub max_ports: u8,
1338 pub context_size_64: bool,
1340 pub doorbell_offset: u32,
1342 pub runtime_offset: u32,
1344}
1345
1346pub struct XhciController {
1348 mmio_base: u64,
1350 capabilities: XhciCapabilities,
1352 op_base: u64,
1354 rt_base: u64,
1356 db_base: u64,
1358 command_ring: CommandRing,
1360 event_ring: EventRing,
1362 running: bool,
1364 enabled_slots: u32,
1366}
1367
1368impl XhciController {
1369 #[cfg(target_os = "none")]
1377 pub unsafe fn new(mmio_base: u64) -> Result<Self, KernelError> {
1378 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, runtime_offset: rtsoff & !0x1F, };
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 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 #[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 pub fn capabilities(&self) -> &XhciCapabilities {
1464 &self.capabilities
1465 }
1466
1467 #[cfg(target_os = "none")]
1469 fn read_op_reg(&self, offset: usize) -> u32 {
1470 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 #[cfg(target_os = "none")]
1481 fn write_op_reg(&self, offset: usize, value: u32) {
1482 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 #[cfg(target_os = "none")]
1491 fn read_op_reg64(&self, offset: usize) -> u64 {
1492 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 #[cfg(target_os = "none")]
1503 fn write_op_reg64(&self, offset: usize, value: u64) {
1504 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 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 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 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 unsafe {
1531 core::ptr::write_volatile((self.db_base + db_offset) as *mut u32, value);
1532 }
1533 }
1534 let _ = (db_offset, value); }
1536
1537 pub fn ring_command_doorbell(&self) {
1539 self.ring_doorbell(0, 0);
1540 }
1541
1542 pub fn ring_transfer_doorbell(&self, slot_id: u8, endpoint_id: u8) {
1544 self.ring_doorbell(slot_id, endpoint_id);
1545 }
1546
1547 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 pub(crate) fn reset(&mut self) -> Result<(), KernelError> {
1564 let cmd = self.read_op_reg(op_regs::USBCMD);
1566 self.write_op_reg(op_regs::USBCMD, cmd & !usbcmd_bits::RS);
1567
1568 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 self.write_op_reg(op_regs::USBCMD, usbcmd_bits::HCRST);
1579
1580 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 self.wait_cnr_clear()?;
1591
1592 self.running = false;
1593 Ok(())
1594 }
1595
1596 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 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 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 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 pub(crate) fn set_dcbaap(&self, phys_addr: u64) {
1647 self.write_op_reg64(op_regs::DCBAAP, phys_addr);
1648 }
1649
1650 pub(crate) fn set_crcr(&self) {
1652 self.write_op_reg64(op_regs::CRCR, self.command_ring.crcr_value());
1653 }
1654
1655 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 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 let new_portsc = (portsc & !PORTSC_CHANGE_BITS) | PORTSC_PR;
1679 self.write_portsc(port, new_portsc);
1680
1681 for _ in 0..10_000 {
1683 let portsc = self.read_portsc(port);
1684 if (portsc & PORTSC_PRC) != 0 {
1685 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 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 pub(crate) fn is_running(&self) -> bool {
1709 self.running
1710 }
1711
1712 #[cfg(target_os = "none")]
1720 pub(crate) unsafe fn send_command(&mut self, trb: Trb) -> u64 {
1721 let addr = unsafe { self.command_ring.enqueue(trb) };
1723 self.ring_command_doorbell();
1724 addr
1725 }
1726
1727 #[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 #[cfg(target_os = "none")]
1739 pub(crate) unsafe fn poll_event(&mut self) -> Option<Trb> {
1740 let event = unsafe { self.event_ring.dequeue()? };
1742 let erdp = self.event_ring.erdp_value();
1744 let ir0_base = self.rt_base + rt_regs::IR0_BASE as u64;
1745 unsafe {
1747 core::ptr::write_volatile(
1748 (ir0_base + ir_regs::ERDP as u64) as *mut u64,
1749 erdp | (1 << 3), );
1751 }
1752 Some(event)
1753 }
1754
1755 #[cfg(not(target_os = "none"))]
1757 pub(crate) fn poll_event(&mut self) -> Option<Trb> {
1758 self.event_ring.dequeue()
1759 }
1760}
1761
1762#[derive(Debug, Clone, Copy)]
1768pub struct MsixCapability {
1769 pub cap_offset: u16,
1771 pub table_size: u16,
1773 pub table_bar: u8,
1775 pub table_offset: u32,
1777 pub pba_bar: u8,
1779 pub pba_offset: u32,
1781}
1782
1783#[derive(Debug, Clone, Copy)]
1785#[repr(C)]
1786pub struct MsixTableEntry {
1787 pub msg_addr_lo: u32,
1789 pub msg_addr_hi: u32,
1791 pub msg_data: u32,
1793 pub vector_control: u32,
1795}
1796
1797#[cfg(target_os = "none")]
1802pub fn configure_msix(
1803 _msix: &MsixCapability,
1804 _mmio_base: u64,
1805 _num_vectors: u16,
1806) -> Result<(), KernelError> {
1807 crate::println!("[xHCI] MSI-X configuration stub (not yet wired)");
1810 Ok(())
1811}
1812
1813#[cfg(all(target_os = "none", target_arch = "x86_64"))]
1818pub fn msix_interrupt_handler(_vector: u8) {
1819 }
1822
1823#[cfg(all(target_os = "none", target_arch = "aarch64"))]
1824pub fn msix_interrupt_handler(_irq: u32) {
1825 }
1827
1828#[cfg(all(target_os = "none", target_arch = "riscv64"))]
1829pub fn msix_interrupt_handler(_irq: u32) {
1830 }
1832
1833pub 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#[cfg(feature = "alloc")]
1846pub fn find_xhci_controllers() -> Vec<XhciPciDevice> {
1847 #[allow(unused_mut)]
1848 let mut controllers = Vec::new();
1849
1850 #[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#[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 pub bar0: u64,
1885 pub irq_line: u8,
1887}
1888
1889static XHCI_INITIALIZED: AtomicBool = AtomicBool::new(false);
1894static XHCI_CONTROLLER_COUNT: AtomicU32 = AtomicU32::new(0);
1895
1896pub fn init() {
1900 if XHCI_INITIALIZED.swap(true, Ordering::SeqCst) {
1901 return; }
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
1939pub fn is_initialized() -> bool {
1941 XHCI_INITIALIZED.load(Ordering::SeqCst)
1942}
1943
1944pub fn controller_count() -> u32 {
1946 XHCI_CONTROLLER_COUNT.load(Ordering::SeqCst)
1947}
1948
1949#[cfg(test)]
1954mod tests {
1955 #[cfg(feature = "alloc")]
1956 #[allow(unused_imports)]
1957 use alloc::vec;
1958
1959 use super::*;
1960
1961 #[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 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 trb.set_transfer_length(0x1FFFF);
2018 assert_eq!(trb.transfer_length(), 0x1FFFF);
2019
2020 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); assert_eq!(trb.status, 8); }
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 #[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(); assert_eq!(state.index, 0);
2103 assert!(!state.cycle); }
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 assert_eq!(ring.crcr_value(), 0x10001);
2121 }
2122
2123 #[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 #[test]
2160 fn test_device_descriptor_parse() {
2161 let mut data = [0u8; 18];
2162 data[0] = 18; data[1] = DESC_TYPE_DEVICE; data[2] = 0x00;
2165 data[3] = 0x03; data[4] = 0x09; data[7] = 64; data[8] = 0x34;
2169 data[9] = 0x12; data[10] = 0x78;
2171 data[11] = 0x56; data[17] = 2; 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; 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; data[1] = DESC_TYPE_CONFIGURATION; data[2] = 32;
2202 data[3] = 0; data[4] = 1; data[5] = 1; data[7] = 0x60; data[8] = 50; 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; data[1] = DESC_TYPE_ENDPOINT; data[2] = 0x81; data[3] = 0x02; data[4] = 0x00;
2225 data[5] = 0x02; data[6] = 0; 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; data[4] = 2; data[5] = 0x08; data[6] = 0x06; data[7] = 0x50; 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 #[test]
2257 fn test_is_xhci_device() {
2258 assert!(is_xhci_device(0x0C, 0x03, 0x30));
2259 assert!(!is_xhci_device(0x0C, 0x03, 0x00)); assert!(!is_xhci_device(0x0C, 0x03, 0x10)); assert!(!is_xhci_device(0x0C, 0x03, 0x20)); assert!(!is_xhci_device(0x02, 0x00, 0x00)); }
2264
2265 #[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 #[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 #[cfg(feature = "alloc")]
2295 #[test]
2296 fn test_parse_configuration_descriptors() {
2297 let mut data = vec![0u8; 32];
2299
2300 data[0] = 9;
2302 data[1] = DESC_TYPE_CONFIGURATION;
2303 data[2] = 25;
2304 data[3] = 0; data[4] = 1; data[5] = 1; data[9] = 9;
2310 data[10] = DESC_TYPE_INTERFACE;
2311 data[11] = 0; data[13] = 1; data[14] = 0x03; data[18] = 7;
2317 data[19] = DESC_TYPE_ENDPOINT;
2318 data[20] = 0x81; data[21] = 0x03; data[22] = 8;
2321 data[23] = 0; data[24] = 10; 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 #[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 assert_eq!(ring.state.index, 3);
2352 }
2353
2354 #[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 #[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}