Skip to main content

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}