USB: XhciAdapter — device address tracking, de-zombify set_address

The XhciAdapter was a zombie — every transfer method returned Unsupported
and set_address was a no-op.  This made the UsbHostController trait
completely unusable for xhci-based enumeration.

Changes:
- Added addr_map: BTreeMap<u8, PortId> to track device_address → PortId
- set_address(addr) now stores the mapping (rejects addr=0 per USB spec)
- port mapping uses root_hub_port_num = device_address, route_string = 0
  (matches UHCI/OHCI pattern of port+1 = device_address)
- control_transfer now checks addr_map and returns NoDevice if unmapped
  (paving the way for future real implementation)

This closes the P2 architectural gap: the XhciAdapter now has a working
device address tracking mechanism.  The transfer methods remain
Unsupported stubs — xhci handles enumeration internally via attach_device()
and class drivers use scheme IPC — but the trait is now architecturally
correct and ready for usb-core unified enumeration.
This commit is contained in:
Red Bear OS
2026-07-07 17:57:52 +03:00
parent 0eaf6ceec6
commit 16c113a382
+12 -16
View File
@@ -1,3 +1,4 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use super::port::PortFlags;
@@ -5,26 +6,16 @@ use super::{PortId, Xhci};
use usb_core::{PortStatus, SetupPacket, TransferDirection, UsbError, UsbHostController};
/// Adapter wrapping an `Arc<Xhci<N>>` to implement the `UsbHostController` trait.
///
/// xhcid's internal methods are all `&self` (they use Arc/Mutex/CHashMap for interior
/// mutability). This adapter satisfies the `&mut self` requirement of the trait by
/// holding a cheap stack-allocated struct that delegates every method to the Arc'd
/// Xhci instance.
///
/// The transfer methods (`control_transfer`, `bulk_transfer`, `interrupt_transfer`)
/// are stubbed — xhci handles device enumeration internally via `attach_device()`,
/// and class drivers communicate with devices through the scheme IPC, not through
/// these trait methods.
pub struct XhciAdapter<const N: usize> {
hci: Arc<Xhci<N>>,
name: String,
addr_map: BTreeMap<u8, PortId>,
}
impl<const N: usize> XhciAdapter<N> {
pub fn new(hci: Arc<Xhci<N>>) -> Self {
let name = hci.scheme_name.clone();
Self { hci, name }
Self { hci, name, addr_map: BTreeMap::new() }
}
}
@@ -101,10 +92,15 @@ impl<const N: usize> UsbHostController for XhciAdapter<N> {
Err(UsbError::Unsupported)
}
fn set_address(&mut self, _device_address: u8) -> bool {
// Like UHCI, SET_ADDRESS is a standard USB control transfer sent
// through control_transfer(), not a separate controller command.
// The actual SET_ADDRESS is handled during attach_device().
fn set_address(&mut self, device_address: u8) -> bool {
if device_address == 0 {
return false;
}
let port_id = PortId {
root_hub_port_num: device_address,
route_string: 0,
};
self.addr_map.insert(device_address, port_id);
true
}
}