Merge branch 'xhcid_config_files' into 'main'

drivers/usb/xhcid: Load config files at runtime rather than compile time

See merge request redox-os/base!242
This commit is contained in:
Jeremy Soller
2026-04-22 15:02:26 -06:00
4 changed files with 29 additions and 17 deletions
Generated
+1
View File
@@ -2900,6 +2900,7 @@ dependencies = [
"bitflags 2.11.0",
"chashmap",
"common",
"config",
"crossbeam-channel",
"daemon",
"futures",
+2 -1
View File
@@ -82,7 +82,6 @@ base:
install-base: base $(SYSROOT)/bin/redoxfs
@mkdir -pv "$(DESTDIR)/usr/bin" "$(DESTDIR)/usr/lib/drivers"
@mkdir -pv "$(DESTDIR)/usr/lib/init.d/" "$(DESTDIR)/usr/lib/pcid.d"
# Distribute binaries
@for bin in $(BASE_BINS); do \
cp -v "$(TARGET_DIR)/$$bin" "$(DESTDIR)/usr/bin"; \
@@ -91,11 +90,13 @@ install-base: base $(SYSROOT)/bin/redoxfs
cp -v "$(TARGET_DIR)/$$bin" "$(DESTDIR)/usr/lib/drivers"; \
done
# Copy configurations
@mkdir -pv "$(DESTDIR)/usr/lib/init.d/" "$(DESTDIR)/usr/lib/pcid.d/" "$(DESTDIR)/usr/lib/xhcid.d/"
@cp -v "$(SRC_DIR)/init.d"/* "$(DESTDIR)/usr/lib/init.d/"
@find "$(SRC_DIR)/drivers" -maxdepth 3 -type f -name 'config.toml' | while read -r conf; do \
driver=$$(basename "$$(dirname "$$conf")"); \
cp -v "$$conf" "$(DESTDIR)/usr/lib/pcid.d/$$driver.toml"; \
done
@cp -v "$(SRC_DIR)/drivers/usb/xhcid/drivers.toml" "$(DESTDIR)/usr/lib/xhcid.d/"
rm -rf "$(BUILD_DIR)/initfs"
# Distribute initfs binaries
+1
View File
@@ -30,6 +30,7 @@ smallvec = { workspace = true, features = ["serde"] }
thiserror.workspace = true
toml.workspace = true
config = { path = "../../../config" }
common = { path = "../../common" }
daemon = { path = "../../../daemon" }
pcid = { path = "../../pcid" }
+25 -16
View File
@@ -11,7 +11,7 @@
//! documents are specified in the crate-level documentation.
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fs::File;
use std::fs::{self, File};
use std::sync::atomic::AtomicUsize;
use std::sync::{Arc, Mutex};
@@ -63,6 +63,8 @@ use self::scheme::EndpIfState;
pub use crate::driver_interface::PortId;
use crate::driver_interface::*;
use crate::xhci::device_enumerator::{DeviceEnumerationRequest, DeviceEnumerator};
use crate::xhci::port::PortFlags;
/// Specifies the configurable interrupt mechanism used by the xhci subsystem for registering
/// device state change notifications.
@@ -280,6 +282,7 @@ pub struct Xhci<const N: usize> {
// used for the extended capabilities, and so far none of them are mutated, and thus no lock.
base: *const u8,
drivers_config: DriversConfig,
handles: CHashMap<usize, scheme::Handle>,
next_handle: AtomicUsize,
port_states: CHashMap<PortId, PortState<N>>,
@@ -445,6 +448,25 @@ impl<const N: usize> Xhci<N> {
let (device_enumerator_sender, device_enumerator_receiver) = crossbeam_channel::unbounded();
let mut drivers_config = DriversConfig { drivers: vec![] };
for file in config::config("xhcid").expect("xhcid: Failed to read driver configs") {
let config = match fs::read(&file) {
Ok(config) => config,
Err(err) => {
println!("xhcid: Failed to read config {}: {err}", file.display());
continue;
}
};
let config = match toml::from_slice::<DriversConfig>(&config) {
Ok(config) => config,
Err(err) => {
println!("xhcid: Failed to parse config {}: {err}", file.display());
continue;
}
};
drivers_config.drivers.extend(config.drivers);
}
let mut xhci = Self {
base: address as *const u8,
@@ -460,6 +482,7 @@ impl<const N: usize> Xhci<N> {
cmd: Mutex::new(cmd),
primary_event_ring: Mutex::new(EventRing::new::<N>(cap.ac64())?),
drivers_config,
handles: CHashMap::new(),
next_handle: AtomicUsize::new(0),
port_states: CHashMap::new(),
@@ -1243,7 +1266,6 @@ impl<const N: usize> Xhci<N> {
})?;
trace!("Got config and device descriptors on port {}", port);
let drivers_usercfg: &DriversConfig = &DRIVERS_CONFIG;
for ifdesc in config_desc.interface_descs.iter() {
//TODO: support alternate settings
@@ -1264,7 +1286,7 @@ impl<const N: usize> Xhci<N> {
continue;
}
if let Some(driver) = drivers_usercfg.drivers.iter().find(|driver| {
if let Some(driver) = self.drivers_config.drivers.iter().find(|driver| {
driver.class == ifdesc.class
&& driver
.subclass()
@@ -1474,16 +1496,3 @@ impl DriverConfig {
struct DriversConfig {
drivers: Vec<DriverConfig>,
}
use crate::xhci::device_enumerator::{DeviceEnumerationRequest, DeviceEnumerator};
use crate::xhci::port::PortFlags;
use lazy_static::lazy_static;
lazy_static! {
static ref DRIVERS_CONFIG: DriversConfig = {
// TODO: Load this at runtime.
const TOML: &'static [u8] = include_bytes!("../../drivers.toml");
toml::from_slice::<DriversConfig>(TOML).expect("Failed to parse internally embedded config file")
};
}