diff --git a/drivers/usb/xhcid/src/xhci/mod.rs b/drivers/usb/xhcid/src/xhci/mod.rs index eb7e162f52..b27de564ff 100644 --- a/drivers/usb/xhcid/src/xhci/mod.rs +++ b/drivers/usb/xhcid/src/xhci/mod.rs @@ -449,8 +449,13 @@ impl Xhci { // Create the command ring with 4096 / 16 (TRB size) entries, so that it uses all of the // DMA allocation (which is at least a 4k page). + let ac64 = if quirks.contains(crate::xhci::quirks::XhciQuirks::NO_64BIT_SUPPORT) { + false + } else { + cap.ac64() + }; let entries_per_page = PAGE_SIZE / mem::size_of::(); - let cmd = Ring::new::(cap.ac64(), entries_per_page, true)?; + let cmd = Ring::new::(ac64, entries_per_page, true)?; let (irq_reactor_sender, irq_reactor_receiver) = crossbeam_channel::unbounded(); @@ -467,11 +472,11 @@ impl Xhci { dbs: Arc::new(Mutex::new(dbs)), run: Mutex::new(run), - dev_ctx: DeviceContextList::new(cap.ac64(), max_slots)?, + dev_ctx: DeviceContextList::new(ac64, max_slots)?, scratchpad_buf_arr: None, // initialized in init() cmd: Mutex::new(cmd), - primary_event_ring: Mutex::new(EventRing::new::(cap.ac64())?), + primary_event_ring: Mutex::new(EventRing::new::(ac64)?), handles: CHashMap::new(), next_handle: AtomicUsize::new(0), port_states: CHashMap::new(), @@ -963,7 +968,7 @@ impl Xhci { if buf_count == 0 { return Ok(()); } - let scratchpad_buf_arr = ScratchpadBufferArray::new::(self.cap.ac64(), buf_count)?; + let scratchpad_buf_arr = ScratchpadBufferArray::new::(self.ac64_effective(), buf_count)?; self.dev_ctx.dcbaa[0] = scratchpad_buf_arr.register() as u64; debug!( "Setting up {} scratchpads, at {:#0x}", @@ -1025,19 +1030,28 @@ impl Xhci { ((self.dev_ctx.contexts[slot].slot.d.read() & SLOT_CONTEXT_STATE_MASK) >> SLOT_CONTEXT_STATE_SHIFT) as u8 } + /// Returns effective 64-bit addressing capability, respecting NO_64BIT_SUPPORT quirk. + fn ac64_effective(&self) -> bool { + if self.quirks.contains(crate::xhci::quirks::XhciQuirks::NO_64BIT_SUPPORT) { + false + } else { + self.cap.ac64() + } + } + pub unsafe fn alloc_dma_zeroed_raw(_ac64: bool) -> Result> { // TODO: ac64 Ok(Dma::zeroed()?.assume_init()) } pub unsafe fn alloc_dma_zeroed(&self) -> Result> { - Self::alloc_dma_zeroed_raw(self.cap.ac64()) + Self::alloc_dma_zeroed_raw(self.ac64_effective()) } pub unsafe fn alloc_dma_zeroed_unsized_raw(_ac64: bool, count: usize) -> Result> { // TODO: ac64 Ok(Dma::zeroed_slice(count)?.assume_init()) } pub unsafe fn alloc_dma_zeroed_unsized(&self, count: usize) -> Result> { - Self::alloc_dma_zeroed_unsized_raw(self.cap.ac64(), count) + Self::alloc_dma_zeroed_unsized_raw(self.ac64_effective(), count) } pub async fn attach_device(&self, port_id: PortId) -> syscall::Result<()> { @@ -1356,7 +1370,7 @@ impl Xhci { } } - let mut ring = Ring::new::(self.cap.ac64(), 16, true)?; + let mut ring = Ring::new::(self.ac64_effective(), 16, true)?; { input_context.add_context.write(1 << 1 | 1); // Enable the slot (zeroth bit) and the control endpoint (first bit).