strat9_kernel/hardware/usb/mod.rs
1// USB subsystem
2//
3// Supports:
4// - xHCI (USB 3.0)
5// - EHCI (USB 2.0)
6// - UHCI (USB 1.1)
7// - HID devices (keyboard, mouse)
8
9pub mod ehci;
10pub mod hid;
11pub mod uhci;
12pub mod xhci;
13
14/// Performs the init operation.
15pub fn init() {
16 // Initialize controllers in order: xHCI first (USB 3.0), then EHCI (USB 2.0), then UHCI (USB 1.1)
17 // This ensures we use the fastest available controller for each device
18
19 log::info!("[USB] Initializing USB subsystem...");
20
21 // Raw E9 progress marks (logger output may be silent during early boot):
22 // 'X' xHCI done, 'E' EHCI done, 'U' UHCI done, 'H' HID init done, then
23 // availability as digit chars (xHCI, EHCI, UHCI, HID).
24 crate::e9_mark!(b'@');
25
26 // xHCI (USB 3.0) - must be initialized first as it may control EHCI
27 xhci::init();
28 crate::e9_mark!(b'X');
29
30 // EHCI (USB 2.0)
31 ehci::init();
32 crate::e9_mark!(b'E');
33
34 // UHCI (USB 1.1) - for legacy devices
35 uhci::init();
36 crate::e9_mark!(b'U');
37
38 // Initialize HID drivers after controllers are ready
39 hid::init();
40 crate::e9_mark!(b'H');
41
42 for (avail, mark) in [
43 (xhci::is_available(), b'1'),
44 (ehci::is_available(), b'2'),
45 (uhci::is_available(), b'3'),
46 (crate::hardware::usb::hid::is_available(), b'4'),
47 ] {
48 let c = if avail { mark } else { mark - 1 }; // '0'..'3' when absent
49 unsafe {
50 core::arch::asm!("out 0xe9, al", in("al") c, options(nomem, nostack));
51 }
52 }
53
54 let total_controllers = (if xhci::is_available() { 1 } else { 0 })
55 + (if ehci::is_available() { 1 } else { 0 })
56 + (if uhci::is_available() { 1 } else { 0 });
57
58 log::info!("[USB] Total USB controllers: {}", total_controllers);
59}