diff --git a/local/recipes/drivers/ehcid/source/src/main.rs b/local/recipes/drivers/ehcid/source/src/main.rs index 7a4cc4f0db..d5d004847b 100644 --- a/local/recipes/drivers/ehcid/source/src/main.rs +++ b/local/recipes/drivers/ehcid/source/src/main.rs @@ -113,6 +113,10 @@ enum HandleKind { Descriptor { port: usize }, Control { port: usize }, Config { port: usize }, + /// xhcid-compat: signals a class driver attached to this port (write-only stub) + Attach { port: usize }, + /// xhcid-compat: endpoint transfer handle (stub — always returns Ok(0)) + Endpoints { port: usize }, } #[derive(Clone, Debug)] @@ -562,6 +566,24 @@ impl EhciController { self.ports[port].device = Some(device); self.ports[port].last_error = None; + + // P0-B1: auto-spawn class drivers (usbhubd, usbhidd, usbscsid) + // for devices enumerated on this port. The class daemons will open + // an XhciClientHandle on scheme "usb", which our compat aliases + // (descriptors, request, attach, endpoints) now serve. + if let Some(ref dev) = self.ports[port].device { + if !dev.device_descriptor.is_empty() { + usb_core::spawn::spawn_class_driver_for_port( + dev.device_class, + dev.device_subclass, + dev.device_protocol, + "usb", + &format!("{}", port + 1), + 0, + ); + } + } + Ok(()) } @@ -1126,9 +1148,15 @@ impl EhciScheme { match (parts.next(), parts.next()) { (None, None) => Ok(HandleKind::PortDir { port }), (Some("status"), None) => Ok(HandleKind::Status { port }), - (Some("descriptor"), None) => Ok(HandleKind::Descriptor { port }), - (Some("control"), None) => Ok(HandleKind::Control { port }), + (Some("descriptor"), None) | (Some("descriptors"), None) => { + Ok(HandleKind::Descriptor { port }) + } + (Some("control"), None) | (Some("request"), None) => { + Ok(HandleKind::Control { port }) + } (Some("config"), None) => Ok(HandleKind::Config { port }), + (Some("attach"), None) => Ok(HandleKind::Attach { port }), + (Some("endpoints"), Some(_)) => Ok(HandleKind::Endpoints { port }), _ => Err(SysError::new(ENOENT)), } } @@ -1136,9 +1164,11 @@ impl EhciScheme { fn resolve_port_child(&self, port: usize, path: &str) -> SysResult { match path { "status" => Ok(HandleKind::Status { port }), - "descriptor" => Ok(HandleKind::Descriptor { port }), - "control" => Ok(HandleKind::Control { port }), + "descriptor" | "descriptors" => Ok(HandleKind::Descriptor { port }), + "control" | "request" => Ok(HandleKind::Control { port }), "config" => Ok(HandleKind::Config { port }), + "attach" => Ok(HandleKind::Attach { port }), + "endpoints" => Ok(HandleKind::PortDir { port }), // open as O_DIRECTORY, then openat into child _ => Err(SysError::new(ENOENT)), } } @@ -1257,11 +1287,12 @@ impl EhciScheme { let handle = self.handle(id)?; match &handle.kind { - HandleKind::PortDir { .. } => Ok(b"status\ndescriptor\ncontrol\nconfig\n".to_vec()), + HandleKind::PortDir { .. } => Ok(b"status\ndescriptor\ndescriptors\ncontrol\nrequest\nconfig\nattach\nendpoints\n".to_vec()), HandleKind::Status { port } => self.status_bytes(*port), HandleKind::Descriptor { port } => self.descriptor_bytes(*port), HandleKind::Control { .. } => Ok(handle.response.clone()), HandleKind::Config { port } => self.config_bytes(*port), + HandleKind::Attach { .. } | HandleKind::Endpoints { .. } => Ok(Vec::new()), } } @@ -1279,6 +1310,8 @@ impl EhciScheme { } HandleKind::Control { port } => format!("{SCHEME_NAME}:/port{}/control", port + 1), HandleKind::Config { port } => format!("{SCHEME_NAME}:/port{}/config", port + 1), + HandleKind::Attach { port } => format!("{SCHEME_NAME}:/port{}/attach", port + 1), + HandleKind::Endpoints { port } => format!("{SCHEME_NAME}:/port{}/endpoints", port + 1), }; Ok(path) } @@ -1362,6 +1395,11 @@ impl SchemeSync for EhciScheme { } Ok(buf.len()) } + HandleKind::Attach { port } => { + log::info!("ehcid: class driver attached to port {}", port + 1); + Ok(buf.len()) + } + HandleKind::Endpoints { .. } => Ok(buf.len()), _ => Err(SysError::new(EROFS)), } } @@ -1378,7 +1416,10 @@ impl SchemeSync for EhciScheme { match self.handle(id)?.kind { HandleKind::PortDir { .. } => MODE_DIR | 0o755, HandleKind::Status { .. } | HandleKind::Descriptor { .. } => MODE_FILE | 0o444, - HandleKind::Control { .. } | HandleKind::Config { .. } => MODE_FILE | 0o644, + HandleKind::Control { .. } + | HandleKind::Config { .. } + | HandleKind::Attach { .. } + | HandleKind::Endpoints { .. } => MODE_FILE | 0o644, } };