acpi-rs: eliminate all AML stubs (resource descriptors, ConnectionField, Match, Index ref)
resource.rs — implement all ~20 stubbed resource descriptor parsers:
- QWord/DWord/Word AddressSpace, IRQ, DMA, I/O, FixedI/O, FixedDMA
- StartDependentFunctions, VendorDefined (small+large)
- GPIOConnection, GenericSerialBus (I2C/SPI/UART subtypes)
- PinFunction, PinConfiguration, PinGroup, PinGroupFunction, PinGroupConfiguration
- ExtendedAddressSpace, GenericRegister
- Both large/small dispatch tables now call real parsers
- ACPI 6.5 §6.4 coverage complete, cross-referenced with ACPICA amlresrc.h
mod.rs — eliminate 3 remaining stubs:
- ConnectionField in parse_field_list: namestring + inline buffer forms
- Opcode::Match: full opcode handler with ResolveBehaviour::ByteData intercept,
10-arg OpInFlight, do_match executor with 7 match operators
- ReferenceKind::Index in do_copy_object: merged with Named/Local path
virtio-core: replace arch stubs (aarch64, riscv64) with real Error::Probe returns
usbscsid/uas: full UAS transport implementation (1006 lines) replacing
stub-heavy version — IUs, pipe detection, stream/non-stream modes,
task tag management, cross-referenced with Linux 7.1 uas.c
initnsmgr: Rc<RefCell<>> -> Arc<Mutex<>> for namespace concurrency safety
xhcid/quirks: fix comment (3 hci_version-dependent entries, not 2)
cargo check -p acpi: clean (3 pre-existing warnings only)
cargo test -p acpi --lib: 5/5 pass
This commit is contained in:
+26
-14
@@ -1,8 +1,6 @@
|
||||
use alloc::rc::Rc;
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::Debug;
|
||||
use core::mem;
|
||||
use hashbrown::HashMap;
|
||||
@@ -11,6 +9,13 @@ use log::{error, warn};
|
||||
use redox_path::RedoxPath;
|
||||
use redox_path::RedoxScheme;
|
||||
use redox_rt::proc::FdGuard;
|
||||
// Namespace state is shared between the dispatcher and (from the worker-offload
|
||||
// step) the open workers, so it uses redox_rt's Send/Sync Mutex instead of the
|
||||
// single-threaded Rc<RefCell>. NOTE: this Mutex is a spinlock -- never hold it
|
||||
// across a blocking syscall; resolve the cap_fd under the lock, clone the Arc,
|
||||
// and do the blocking openat with the lock released. See
|
||||
// local/docs/INITNSMGR-CONCURRENCY-DESIGN.md.
|
||||
use redox_rt::sync::Mutex;
|
||||
use redox_scheme::{
|
||||
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
|
||||
scheme::{SchemeState, SchemeSync},
|
||||
@@ -59,9 +64,11 @@ impl Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
// No `Debug` derive: redox_rt's Mutex wraps an UnsafeCell and is not Debug.
|
||||
// `Clone` clones the Arc (a refcount bump), not the namespace.
|
||||
#[derive(Clone)]
|
||||
struct NamespaceAccess {
|
||||
namespace: Rc<RefCell<Namespace>>,
|
||||
namespace: Arc<Mutex<Namespace>>,
|
||||
permission: NsPermissions,
|
||||
}
|
||||
|
||||
@@ -71,15 +78,15 @@ impl NamespaceAccess {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
struct SchemeRegister {
|
||||
target_namespace: Rc<RefCell<Namespace>>,
|
||||
target_namespace: Arc<Mutex<Namespace>>,
|
||||
scheme_name: String,
|
||||
}
|
||||
|
||||
impl SchemeRegister {
|
||||
fn register(&self, fd: FdGuard) -> Result<()> {
|
||||
let mut ns = self.target_namespace.borrow_mut();
|
||||
let mut ns = self.target_namespace.lock();
|
||||
if ns.schemes.contains_key(&self.scheme_name) {
|
||||
return Err(Error::new(EEXIST));
|
||||
}
|
||||
@@ -88,7 +95,7 @@ impl SchemeRegister {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
enum Handle {
|
||||
Access(NamespaceAccess),
|
||||
Register(SchemeRegister),
|
||||
@@ -122,7 +129,7 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
|
||||
fn add_namespace(&mut self, id: usize, schemes: Namespace, permission: NsPermissions) {
|
||||
let handle = Handle::Access(NamespaceAccess {
|
||||
namespace: Rc::new(RefCell::new(schemes)),
|
||||
namespace: Arc::new(Mutex::new(schemes)),
|
||||
permission,
|
||||
});
|
||||
self.handles.insert(id, handle);
|
||||
@@ -183,9 +190,9 @@ impl<'sock> NamespaceScheme<'sock> {
|
||||
Ok(scheme_fd)
|
||||
}
|
||||
|
||||
fn fork_namespace(&mut self, namespace: Rc<RefCell<Namespace>>, names: &[u8]) -> Result<usize> {
|
||||
fn fork_namespace(&mut self, namespace: Arc<Mutex<Namespace>>, names: &[u8]) -> Result<usize> {
|
||||
let new_id = self.next_id;
|
||||
let new_namespace = namespace.borrow().fork(names).map_err(|e| {
|
||||
let new_namespace = namespace.lock().fork(names).map_err(|e| {
|
||||
error!("Failed to fork namespace {}: {}", new_id, e);
|
||||
e
|
||||
})?;
|
||||
@@ -258,8 +265,13 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
flags: NewFdFlags::empty(),
|
||||
});
|
||||
}
|
||||
// STEP 1 (mechanical): the lock is held across the blocking openat
|
||||
// inside open_scheme_resource. That is safe only because this is
|
||||
// still single-threaded. STEP 3 must resolve+clone the cap_fd under
|
||||
// a short lock here and run the openat with the lock released, or
|
||||
// the spinlock would burn a worker while a provider is slow.
|
||||
_ => self.open_scheme_resource(
|
||||
&ns_access.namespace.borrow(),
|
||||
&ns_access.namespace.lock(),
|
||||
scheme.as_ref(),
|
||||
reference.as_ref(),
|
||||
flags,
|
||||
@@ -329,7 +341,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
error!("Namespace with ID {} not found", fd);
|
||||
Error::new(ENOENT)
|
||||
})?;
|
||||
let mut ns = ns_access.namespace.borrow_mut();
|
||||
let mut ns = ns_access.namespace.lock();
|
||||
|
||||
let redox_path = RedoxPath::from_absolute(path).ok_or(Error::new(EINVAL))?;
|
||||
let (scheme, reference) = redox_path.as_parts().ok_or(Error::new(EINVAL))?;
|
||||
@@ -411,7 +423,7 @@ impl<'sock> SchemeSync for NamespaceScheme<'sock> {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
let ns = ns_access.namespace.borrow();
|
||||
let ns = ns_access.namespace.lock();
|
||||
|
||||
let opaque_offset = opaque_offset as usize;
|
||||
for (i, (name, _)) in ns.schemes.iter().enumerate().skip(opaque_offset) {
|
||||
|
||||
Reference in New Issue
Block a user