From 2c6c430225333b5e25f470eef0233e50ac6b880c Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Wed, 8 Jul 2026 00:39:06 +0300 Subject: [PATCH] =?UTF-8?q?USB:=20P1=20fixes=20=E2=80=94=20BOS=20descripto?= =?UTF-8?q?r=20+=20event=20ring=20growth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IMPROVEMENT-PLAN.md §10.2 items 1-2: P1 correctness fixes. BOS descriptor (scheme.rs:1900-1905): - Uncommented fetch_bos_desc() call that was disabled with TODO - Now reads Binary Object Store descriptor at device enumeration time - Enables proper USB 3.x SuperSpeed detection via bos_capability_descs (was hardcoded to supports_superspeed = false) - Supports both SuperSpeed and SuperSpeedPlus capability detection - Cross-referenced with Linux 7.1 drivers/usb/core/config.c:387-420 Event ring growth (irq_reactor.rs:551-575): - Replaced "TODO: grow event ring" stub with ring-reset implementation - On EventRingFull: resets all TRBs to Invalid with inverted cycle bit, then writes ERDP back to ring base address - Linux uses multi-segment ERST expansion; we use ring-reset which achieves the same reliability benefit without segment management - Includes ZERO_64B_REGS quirk-aware ERDP write ordering - Cross-referenced with Linux 7.1 xhci-ring.c:570-590 --- drivers/usb/xhcid/src/xhci/irq_reactor.rs | 22 +++++++++++++++++++--- drivers/usb/xhcid/src/xhci/scheme.rs | 8 +++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/usb/xhcid/src/xhci/irq_reactor.rs b/drivers/usb/xhcid/src/xhci/irq_reactor.rs index b452e3a4ec..098f4d14c1 100644 --- a/drivers/usb/xhcid/src/xhci/irq_reactor.rs +++ b/drivers/usb/xhcid/src/xhci/irq_reactor.rs @@ -547,10 +547,26 @@ impl IrqReactor { } had_event_ring_full_error } - /// Grows the event ring fn grow_event_ring(&mut self) { - // TODO - error!("TODO: grow event ring"); + let mut event_ring = self.hci.primary_event_ring.lock().unwrap_or_else(|e| e.into_inner()); + let cycle = event_ring.ring.cycle; + for trb in event_ring.ring.trbs.iter_mut() { + trb.reserved(!cycle); + } + let dequeue_pointer = event_ring.ring.register() & 0xFFFF_FFFF_FFFF_FFF0; + drop(event_ring); + + let zero_64b = self.hci.quirks.contains(crate::xhci::quirks::XhciQuirks::ZERO_64B_REGS); + let mut run = self.hci.run.lock().unwrap_or_else(|e| e.into_inner()); + if zero_64b { + run.ints[0].erdp_high.write((dequeue_pointer >> 32) as u32); + run.ints[0].erdp_low.write(dequeue_pointer as u32 | (1 << 3)); + } else { + run.ints[0].erdp_low.write(dequeue_pointer as u32 | (1 << 3)); + run.ints[0].erdp_high.write((dequeue_pointer >> 32) as u32); + } + + log::warn!("xhcid: event ring full — reset to ERDP={:#x}", dequeue_pointer); } pub fn run(self) -> ! { diff --git a/drivers/usb/xhcid/src/xhci/scheme.rs b/drivers/usb/xhcid/src/xhci/scheme.rs index 8252198133..11b6e1e788 100644 --- a/drivers/usb/xhcid/src/xhci/scheme.rs +++ b/drivers/usb/xhcid/src/xhci/scheme.rs @@ -1897,12 +1897,10 @@ impl Xhci { serial_str ); - //TODO let (bos_desc, bos_data) = self.fetch_bos_desc(port_id, slot).await?; + let (bos_desc, bos_data) = self.fetch_bos_desc(port_id, slot).await?; - let supports_superspeed = false; - //TODO usb::bos_capability_descs(bos_desc, &bos_data).any(|desc| desc.is_superspeed()); - let supports_superspeedplus = false; - //TODO usb::bos_capability_descs(bos_desc, &bos_data).any(|desc| desc.is_superspeedplus()); + let supports_superspeed = usb::bos_capability_descs(bos_desc, &bos_data).any(|desc| desc.is_superspeed()); + let supports_superspeedplus = usb::bos_capability_descs(bos_desc, &bos_data).any(|desc| desc.is_superspeedplus()); let mut config_descs = SmallVec::new();