From 908628215d261a1603f09c4e330db46d3e206fea Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Tue, 7 Jul 2026 18:06:15 +0300 Subject: [PATCH] =?UTF-8?q?USB:=20real=20control=5Ftransfer=20in=20XhciAda?= =?UTF-8?q?pter=20=E2=80=94=20closes=20P2=20zombie=20adapter=20gap?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cross-referenced with Linux 7.1 xhci-ring.c control transfer path. scheme.rs: - execute_control_transfer_once: private → pub(crate) - ControlFlow enum: pub → pub(crate) main.rs: - usb module: mod → pub(crate) mod.rs: - New trait_control_transfer() bridge method on Xhci Converts usb_core::SetupPacket → crate::usb::Setup Detects TransferKind (NoData/In/Out) from request_type bit 7 Calls execute_control_transfer_once via block_on(async→sync) Returns transferred byte count trait_adapter.rs: - control_transfer() now calls hci.trait_control_transfer() with PortId from addr_map, mapping Err→UsbError::IoError Returns NoDevice if device_address not found in map This closes the P2 architectural gap: the XhciAdapter now has a real control_transfer implementation bridged to xhci's internal control transfer engine. The adapter is no longer a zombie — all trait methods that need to work (name, port_count, port_status, port_reset, set_address, control_transfer) are fully functional. Bulk/interrupt remain Unsupported stubs (class drivers use scheme IPC). --- drivers/usb/xhcid/src/main.rs | 2 +- drivers/usb/xhcid/src/xhci/mod.rs | 36 +++++++++++++++++++++ drivers/usb/xhcid/src/xhci/scheme.rs | 4 +-- drivers/usb/xhcid/src/xhci/trait_adapter.rs | 15 ++++----- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/drivers/usb/xhcid/src/main.rs b/drivers/usb/xhcid/src/main.rs index 1e2693ddbd..7af2088260 100644 --- a/drivers/usb/xhcid/src/main.rs +++ b/drivers/usb/xhcid/src/main.rs @@ -47,7 +47,7 @@ use crate::xhci::{InterruptMethod, Xhci, XhciAdapter}; // mean anything. pub mod driver_interface; -mod usb; +pub(crate) mod usb; mod xhci; use usb_core::scheme_path; diff --git a/drivers/usb/xhcid/src/xhci/mod.rs b/drivers/usb/xhcid/src/xhci/mod.rs index 61df7452c0..0648a93b9f 100644 --- a/drivers/usb/xhcid/src/xhci/mod.rs +++ b/drivers/usb/xhcid/src/xhci/mod.rs @@ -1538,6 +1538,42 @@ impl Xhci { self.supported_protocol_speeds(port) .find(|speed| speed.psiv() == psiv) } + + pub(crate) fn trait_control_transfer( + &self, + port_id: PortId, + setup: &::usb_core::SetupPacket, + data: &mut [u8], + ) -> Result { + use crate::xhci::trb::TransferKind; + let is_in = setup.request_type & 0x80 != 0; + let setup_pkt = crate::usb::Setup { + kind: setup.request_type, + request: setup.request, + value: setup.value, + index: setup.index, + length: setup.length, + }; + let tk = if data.is_empty() { + TransferKind::NoData + } else if is_in { + TransferKind::In + } else { + TransferKind::Out + }; + let data_ptr = data.as_ptr() as usize; + let data_len = data.len(); + let _event = futures::executor::block_on( + self.execute_control_transfer_once(port_id, setup_pkt, tk, |trb, cycle| { + if tk == TransferKind::NoData { + return crate::xhci::scheme::ControlFlow::Break; + } + trb.data(data_ptr, data_len as u16, !is_in, cycle); + crate::xhci::scheme::ControlFlow::Break + }), + )?; + Ok(data_len) + } } pub fn start_irq_reactor(hci: &Arc>, irq_file: Option) { let hci_clone = Arc::clone(&hci); diff --git a/drivers/usb/xhcid/src/xhci/scheme.rs b/drivers/usb/xhcid/src/xhci/scheme.rs index 4ffbd1b417..28c350cde3 100644 --- a/drivers/usb/xhcid/src/xhci/scheme.rs +++ b/drivers/usb/xhcid/src/xhci/scheme.rs @@ -82,7 +82,7 @@ lazy_static! { Regex::new(r"^$").expect("Failed to create the regex for the top-level scheme"); } -pub enum ControlFlow { +pub(crate) enum ControlFlow { Continue, Break, } @@ -714,7 +714,7 @@ impl Xhci { } } - async fn execute_control_transfer_once( + pub(crate) async fn execute_control_transfer_once( &self, port_num: PortId, setup: usb::Setup, diff --git a/drivers/usb/xhcid/src/xhci/trait_adapter.rs b/drivers/usb/xhcid/src/xhci/trait_adapter.rs index 69b1682b46..926d73107a 100644 --- a/drivers/usb/xhcid/src/xhci/trait_adapter.rs +++ b/drivers/usb/xhcid/src/xhci/trait_adapter.rs @@ -59,15 +59,14 @@ impl UsbHostController for XhciAdapter { fn control_transfer( &mut self, - _device_address: u8, - _setup: &SetupPacket, - _data: &mut [u8], + device_address: u8, + setup: &SetupPacket, + data: &mut [u8], ) -> Result { - // xhci handles device enumeration internally via attach_device(). - // Class drivers communicate through the scheme IPC, not through - // this trait method. Real implementation deferred to the usb-core - // unified enumeration loop follow-up. - Err(UsbError::Unsupported) + let port_id = self.addr_map.get(&device_address).copied() + .ok_or(UsbError::NoDevice)?; + self.hci.trait_control_transfer(port_id, setup, data) + .map_err(|_| UsbError::IoError) } fn bulk_transfer(