xhcid: open hub-child port dirs before enumeration (scheme bootstrap)

open_handle_port required a PortState for every port<N> directory open,
but hub child ports have no PortState until the hub daemon triggers
attach_device via port<N>/attach — an endpoint that itself is
state-free (open_handle_attach_device). This made XhciClientHandle::new
fail with ENOENT for unenumerated hub children, deadlocking the attach
flow: usbhubd could never start enumeration for a device behind a
non-root hub (panic at startup, caught by test-usb-hub-qemu.sh).

Open the directory with the static listing when no PortState exists
yet; state-dependent subpaths (descriptors, state, configure) still
gate on the PortState being present.
This commit is contained in:
Red Bear OS
2026-07-19 09:15:33 +09:00
parent 9bbdc2cafa
commit d7f31916bc
+10 -8
View File
@@ -2481,14 +2481,16 @@ impl<const N: usize> Xhci<N> {
write!(contents, "descriptors\nendpoints\n").unwrap();
if self.slot_state(
self.port_states
.get(&port_num)
.ok_or(Error::new(ENOENT))?
.slot as usize,
) != SlotState::Configured as u8
{
write!(contents, "configure\n").unwrap();
// A hub child port has no PortState until the hub daemon
// triggers attach_device() for it via port<N>/attach — an
// endpoint that itself needs no state (open_handle_attach_device).
// Open the directory anyway so that attach flow can start the
// enumeration; state-dependent subpaths (descriptors, state,
// configure) still gate on the PortState existing.
if let Some(port_state) = self.port_states.get(&port_num) {
if self.slot_state(port_state.slot as usize) != SlotState::Configured as u8 {
write!(contents, "configure\n").unwrap();
}
}
Ok(Handle::Port(port_num, contents))