feat(otg): 增加 libcomposite 自动加载兜底

This commit is contained in:
mofeng-git
2026-03-28 17:06:41 +08:00
parent 1c5288d783
commit abc6bd1677
2 changed files with 41 additions and 0 deletions

View File

@@ -3,6 +3,7 @@
use std::fs::{self, File, OpenOptions}; use std::fs::{self, File, OpenOptions};
use std::io::Write; use std::io::Write;
use std::path::Path; use std::path::Path;
use std::process::Command;
use crate::error::{AppError, Result}; use crate::error::{AppError, Result};
@@ -29,6 +30,42 @@ pub fn is_configfs_available() -> bool {
Path::new(CONFIGFS_PATH).exists() Path::new(CONFIGFS_PATH).exists()
} }
/// Ensure libcomposite support is available for USB gadget operations.
///
/// This is a best-effort runtime fallback for systems where `libcomposite`
/// is built as a module and not loaded yet. It does not try to mount configfs;
/// mounting remains an explicit system responsibility.
pub fn ensure_libcomposite_loaded() -> Result<()> {
if is_configfs_available() {
return Ok(());
}
if !Path::new("/sys/module/libcomposite").exists() {
let status = Command::new("modprobe")
.arg("libcomposite")
.status()
.map_err(|e| {
AppError::Internal(format!("Failed to run modprobe libcomposite: {}", e))
})?;
if !status.success() {
return Err(AppError::Internal(format!(
"modprobe libcomposite failed with status {}",
status
)));
}
}
if is_configfs_available() {
Ok(())
} else {
Err(AppError::Internal(
"libcomposite is not available after modprobe; check configfs mount and kernel support"
.to_string(),
))
}
}
/// Find available UDC (USB Device Controller) /// Find available UDC (USB Device Controller)
pub fn find_udc() -> Option<String> { pub fn find_udc() -> Option<String> {
let udc_path = Path::new("/sys/class/udc"); let udc_path = Path::new("/sys/class/udc");

View File

@@ -397,6 +397,10 @@ impl OtgService {
return Ok(()); return Ok(());
} }
if let Err(e) = super::configfs::ensure_libcomposite_loaded() {
warn!("Failed to ensure libcomposite is available: {}", e);
}
// Check if OTG is available // Check if OTG is available
if !Self::is_available() { if !Self::is_available() {
let error = "OTG not available: ConfigFS not mounted or no UDC found".to_string(); let error = "OTG not available: ConfigFS not mounted or no UDC found".to_string();