1mod channel;
2mod dma;
3mod endpoint;
4mod event;
5mod hub;
6mod reg;
7mod stats;
8
9#[cfg(test)]
10mod testutil;
11
12use alloc::{boxed::Box, collections::BTreeMap, sync::Arc, vec::Vec};
13use core::{task::Poll, time::Duration};
14
15use futures::{
16 FutureExt,
17 future::{BoxFuture, poll_fn},
18};
19use reg::*;
20pub use stats::Dwc2TransferStats;
21use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
22use usb_if::{
23 descriptor::{
24 ConfigurationDescriptor, DescriptorType, DeviceDescriptor, DeviceDescriptorBase,
25 EndpointDescriptor, EndpointType,
26 },
27 endpoint::EndpointInfo,
28 err::{TransferError, USBError},
29 host::{ControlSetup, hub::Speed},
30 transfer::{Direction, Recipient, Request, RequestType},
31};
32
33use super::{
34 hub::HubOp,
35 kcore::CoreOp,
36 osal::{Kernel, KernelOp},
37};
38use crate::{
39 Mmio,
40 backend::{
41 kmod::{
42 DeviceAddressInfo,
43 dwc2::{
44 channel::{Dwc2ChannelCompletions, Dwc2PeriodicSchedule, HostChannelPool},
45 endpoint::{Dwc2Endpoint, Dwc2EndpointParams},
46 event::Dwc2EventHandler,
47 hub::Dwc2RootHub,
48 reg::Dwc2Registers,
49 stats::Dwc2Stats,
50 },
51 },
52 ty::{
53 DeviceOp, EventHandlerOp, HubParams,
54 ep::{EndpointHandle, EndpointOp},
55 },
56 },
57 err::Result,
58};
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum Dwc2UtmiWidth {
62 Eight,
63 Sixteen,
64 Auto,
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub enum Dwc2SoftResetCompletion {
70 StartBitCleared,
71 DoneBitSet,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub struct Dwc2FifoSizes {
76 pub rx_depth: u16,
77 pub non_periodic_tx_depth: u16,
78 pub periodic_tx_depth: u16,
79}
80
81impl Dwc2FifoSizes {
82 pub const fn sg2002_default() -> Self {
83 Self {
84 rx_depth: 536,
85 non_periodic_tx_depth: 32,
86 periodic_tx_depth: 768,
87 }
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
92pub struct Dwc2Quirks {
93 pub otg_host_session_override: bool,
94 pub clear_utmi_override: bool,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98pub struct Dwc2HostParams {
99 pub dma_mask: u64,
100 pub fifo: Dwc2FifoSizes,
101 pub utmi: Dwc2UtmiWidth,
102 pub soft_reset_completion: Dwc2SoftResetCompletion,
103 pub quirks: Dwc2Quirks,
104}
105
106impl Dwc2HostParams {
107 pub const fn sg2002() -> Self {
108 Self {
109 dma_mask: DWC2_DMA_MASK_32,
110 fifo: Dwc2FifoSizes::sg2002_default(),
111 utmi: Dwc2UtmiWidth::Auto,
112 soft_reset_completion: Dwc2SoftResetCompletion::DoneBitSet,
115 quirks: Dwc2Quirks {
116 otg_host_session_override: true,
117 clear_utmi_override: true,
118 },
119 }
120 }
121}
122
123#[derive(Clone, Copy)]
124pub struct Dwc2NewParams {
125 pub mmio: Mmio,
126 pub kernel: &'static dyn KernelOp,
127 pub params: Dwc2HostParams,
128}
129
130pub struct Dwc2 {
131 regs: Dwc2Registers,
132 kernel: Kernel,
133 params: Dwc2HostParams,
134 root_hub: Option<Dwc2RootHub>,
135 event_handler: Option<Dwc2EventHandler>,
136 next_addr: u8,
137 channel_pool: HostChannelPool,
138 stats: Dwc2Stats,
139}
140
141unsafe impl Send for Dwc2 {}
142unsafe impl Sync for Dwc2 {}
143
144impl Dwc2 {
145 pub fn new(params: Dwc2NewParams) -> Result<Self> {
146 if params.params.dma_mask != DWC2_DMA_MASK_32 {
147 return Err(USBError::NotSupported);
148 }
149
150 let regs = Dwc2Registers::new(params.mmio);
151 let kernel = Kernel::new(
152 dma_api::DmaDeviceInfo::new(
153 dma_api::DmaDomainId::Direct,
154 dma_api::DmaCoherency::NonCoherent,
155 dma_api::DmaConstraints::new(params.params.dma_mask),
156 ),
157 params.kernel,
158 );
159 let root_hub = Dwc2RootHub::new(regs, kernel.clone());
160 let channel_completions = Dwc2ChannelCompletions::new();
161 let stats = Dwc2Stats::new();
162 let event_handler = Dwc2EventHandler::new(regs, channel_completions.clone(), stats.clone());
163 let channel_count = regs.host_channel_count();
164 let periodic = Dwc2PeriodicSchedule::new(&kernel)
165 .map_err(|err| USBError::Other(anyhow!("DWC2 frame list allocation failed: {err}")))?;
166
167 Ok(Self {
168 regs,
169 kernel,
170 params: params.params,
171 root_hub: Some(root_hub),
172 event_handler: Some(event_handler),
173 next_addr: 1,
174 channel_pool: HostChannelPool::new(
175 channel_count,
176 channel_completions,
177 Arc::new(periodic),
178 ),
179 stats,
180 })
181 }
182
183 async fn init_controller(&mut self) -> Result<()> {
184 self.disable_irq()?;
185 self.regs.regs().gintsts.set(u32::MAX);
186 self.core_soft_reset()?;
187 log::debug!("dwc2: initial core reset complete");
188 self.force_host_mode()?;
189 log::debug!("dwc2: host mode active");
190 self.core_soft_reset()?;
191 log::debug!("dwc2: host-mode core reset complete");
192
193 if self.params.quirks.otg_host_session_override {
194 let gotgctl = self.regs.regs().gotgctl.get();
195 self.regs.regs().gotgctl.set(
196 gotgctl
197 | GOTGCTL_DBNCE_FLTR_BYPASS
198 | GOTGCTL_AVALOEN
199 | GOTGCTL_AVALOVAL
200 | GOTGCTL_VBVALOEN
201 | GOTGCTL_VBVALOVAL,
202 );
203 self.kernel.delay(Duration::from_micros(200));
204 }
205
206 self.init_gusbcfg();
207 self.regs.regs().pcgctl.set(0);
208
209 let arch = self.regs.regs().ghwcfg2.read(GHWCFG2::ARCHITECTURE);
210 let gahbcfg = build_gahbcfg_internal_dma(arch)?;
211 self.regs.regs().gahbcfg.set(gahbcfg);
212
213 if !self.regs.is_support_ddma() {
215 log::error!("dwc2: controller lacks descriptor DMA capability");
216 return Err(USBError::NotSupported);
217 }
218
219 self.regs
220 .regs()
221 .hcfg
222 .modify(HCFG::FSLSPCLKSEL::CLEAR + HCFG::DESCDMA::SET);
223 log::debug!("dwc2: descriptor DMA enabled");
224
225 let fifo = fifo_register_plan(self.params.fifo);
226 self.regs.regs().grxfsiz.set(fifo.grxfsiz);
227 self.regs.regs().gnptxfsiz.set(fifo.gnptxfsiz);
228 self.regs.regs().hptxfsiz.set(fifo.hptxfsiz);
229 self.flush_tx_fifo_all()?;
230 log::debug!("dwc2: TX FIFOs flushed");
231 self.flush_rx_fifo()?;
232 log::debug!("dwc2: RX FIFO flushed");
233
234 let channel_count = self.regs.host_channel_count();
235 self.prepare_runtime_irqs(channel_count);
236 log::debug!("dwc2: runtime IRQ state prepared");
237 self.port_power_on();
238 log::debug!("dwc2: root port powered");
239 self.kernel.delay(Duration::from_millis(20));
240 log::debug!("dwc2: controller initialization settled");
241 Ok(())
242 }
243
244 fn prepare_runtime_irqs(&self, channel_count: u8) {
245 let channel_mask = (1u32 << channel_count) - 1;
247 self.regs.regs().gintmsk.set(0);
252 self.regs.regs().gintsts.set(u32::MAX);
253 self.regs.regs().haintmsk.set(channel_mask);
254 }
255
256 fn init_gusbcfg(&self) {
257 let want_16bit = match self.params.utmi {
258 Dwc2UtmiWidth::Eight => false,
259 Dwc2UtmiWidth::Sixteen => true,
260 Dwc2UtmiWidth::Auto => self.regs.regs().ghwcfg4.read(GHWCFG4::UTMI_PHY_DATA_WIDTH) == 1,
261 };
262
263 let mut value = self.regs.regs().gusbcfg.get();
264 value &= !(GUSBCFG_TOUTCAL_MASK
265 | GUSBCFG_PHYIF16
266 | GUSBCFG_ULPI_UTMI_SEL
267 | GUSBCFG_FORCEDEVMODE);
268 value |= GUSBCFG_FORCEHOSTMODE | 0x7;
269 if want_16bit {
270 value |= GUSBCFG_PHYIF16;
271 }
272 self.regs.regs().gusbcfg.set(value);
273 }
274
275 fn wait_until(&self, stage: &'static str, ready: impl Fn() -> bool) -> Result<()> {
276 for iter in 0..DWC2_WAIT_ITERS {
277 if ready() {
278 self.stats.record_init_wait_iters(iter + 1);
279 return Ok(());
280 }
281 core::hint::spin_loop();
282 }
283 self.stats.record_init_wait_iters(DWC2_WAIT_ITERS);
284 self.stats.record_timeout();
285 log::warn!(
286 "dwc2: {stage} timed out gsnpsid={:#010x} grstctl={:#010x} gusbcfg={:#010x} \
287 gintsts={:#010x}",
288 self.regs.regs().gsnpsid.get(),
289 self.regs.regs().grstctl.get(),
290 self.regs.regs().gusbcfg.get(),
291 self.regs.regs().gintsts.get(),
292 );
293 Err(USBError::Timeout)
294 }
295
296 fn wait_ahb_idle(&self) -> Result<()> {
297 self.wait_until("AHB idle", || {
298 self.regs.regs().grstctl.get() & GRSTCTL_AHBIDLE != 0
299 })
300 }
301
302 fn core_soft_reset(&self) -> Result<()> {
303 let value = self.regs.regs().grstctl.get();
304 self.regs.regs().grstctl.set(value | GRSTCTL_CSFTRST);
305 match self.params.soft_reset_completion {
306 Dwc2SoftResetCompletion::StartBitCleared => {
307 self.wait_until("core soft reset clear", || {
308 self.regs.regs().grstctl.get() & GRSTCTL_CSFTRST == 0
309 })?;
310 }
311 Dwc2SoftResetCompletion::DoneBitSet => {
312 self.wait_until("core soft reset done", || {
313 self.regs.regs().grstctl.get() & GRSTCTL_CSFTRST_DONE != 0
314 })?;
315 let value = self.regs.regs().grstctl.get();
316 self.regs
317 .regs()
318 .grstctl
319 .set((value & !GRSTCTL_CSFTRST) | GRSTCTL_CSFTRST_DONE);
320 }
321 }
322 self.wait_ahb_idle()?;
323 self.kernel.delay(Duration::from_millis(1));
324 Ok(())
325 }
326
327 fn force_host_mode(&self) -> Result<()> {
328 let value = self.regs.regs().gusbcfg.get();
329 self.regs
330 .regs()
331 .gusbcfg
332 .set((value | GUSBCFG_FORCEHOSTMODE) & !GUSBCFG_FORCEDEVMODE);
333 self.kernel.delay(Duration::from_millis(25));
334 self.wait_until("force host mode", || {
335 self.regs.regs().gintsts.get() & GINTSTS_CURMODE_HOST != 0
336 })
337 }
338
339 fn flush_tx_fifo_all(&self) -> Result<()> {
340 self.regs
341 .regs()
342 .grstctl
343 .set(GRSTCTL_TXFFLSH | GRSTCTL_TXFNUM_ALL);
344 self.wait_until("flush all TX FIFOs", || {
345 self.regs.regs().grstctl.get() & GRSTCTL_TXFFLSH == 0
346 })?;
347 self.kernel.delay(Duration::from_micros(1));
348 Ok(())
349 }
350
351 fn flush_rx_fifo(&self) -> Result<()> {
352 self.regs.regs().grstctl.set(GRSTCTL_RXFFLSH);
353 self.wait_until("flush RX FIFO", || {
354 self.regs.regs().grstctl.get() & GRSTCTL_RXFFLSH == 0
355 })?;
356 self.kernel.delay(Duration::from_micros(1));
357 Ok(())
358 }
359
360 fn port_power_on(&self) {
361 self.regs.hprt().update_safe(|value| value | HPRT_PWR);
362 }
363
364 fn allocate_address(&mut self) -> Result<u8> {
365 if self.next_addr >= 128 {
366 return Err(USBError::SlotLimitReached);
367 }
368 let addr = self.next_addr;
369 self.next_addr += 1;
370 Ok(addr)
371 }
372
373 async fn new_device(&mut self, info: DeviceAddressInfo) -> Result<Box<dyn DeviceOp>> {
374 let channel_count = self.channel_pool.channel_count;
375 let channel_mask = (1u32 << channel_count) - 1;
376 self.channel_pool.completions.mark_connected(|| {
377 self.regs.regs().haintmsk.set(channel_mask);
378 let mask = self.regs.regs().gintmsk.get();
379 self.regs.regs().gintmsk.set(mask | DWC2_RUNTIME_GINTMSK);
380 });
381 let addr = self.allocate_address()?;
382 let mut device = Dwc2Device::new(Dwc2DeviceParams {
383 address: addr,
384 regs: self.regs,
385 kernel: self.kernel.clone(),
386 port_speed: info.port_speed,
387 channel_pool: self.channel_pool.clone(),
388 stats: self.stats.clone(),
389 })?;
390 device.init().await?;
391 Ok(Box::new(device))
392 }
393}
394
395impl CoreOp for Dwc2 {
396 fn init<'a>(&'a mut self) -> BoxFuture<'a, Result<()>> {
397 self.init_controller().boxed()
398 }
399
400 fn root_hub(&mut self) -> Box<dyn HubOp> {
401 Box::new(
402 self.root_hub
403 .take()
404 .expect("DWC2 root hub can only be taken once"),
405 )
406 }
407
408 fn new_addressed_device<'a>(
409 &'a mut self,
410 addr: DeviceAddressInfo,
411 ) -> BoxFuture<'a, Result<Box<dyn DeviceOp>>> {
412 self.new_device(addr).boxed()
413 }
414
415 fn create_event_handler(&mut self) -> Box<dyn EventHandlerOp> {
416 Box::new(
417 self.event_handler
418 .take()
419 .expect("DWC2 event handler can only be created once"),
420 )
421 }
422
423 fn enable_irq(&mut self) -> Result<()> {
424 self.regs.regs().gintmsk.set(DWC2_RUNTIME_GINTMSK);
425 Ok(())
426 }
427
428 fn disable_irq(&mut self) -> Result<()> {
429 self.regs.regs().gintmsk.set(0);
430 Ok(())
431 }
432
433 fn dwc2_transfer_stats(&self) -> Option<Dwc2TransferStats> {
434 Some(self.stats.snapshot())
435 }
436
437 fn reset_dwc2_transfer_stats(&self) {
438 self.stats.reset();
439 }
440
441 fn kernel(&self) -> &Kernel {
442 &self.kernel
443 }
444}
445
446#[derive(Debug, Clone, Copy, PartialEq, Eq)]
447pub(crate) enum Dwc2Pid {
448 Data0,
449 Data2,
450 Data1,
451 Setup,
452 MData,
453}
454
455impl Dwc2Pid {
456 const fn bits(self) -> u32 {
457 match self {
458 Self::Data0 => 0,
459 Self::Data2 => 1,
460 Self::Data1 => 2,
461 Self::Setup => 3,
462 Self::MData => 3,
463 }
464 }
465}
466
467#[derive(Debug, Clone, Copy, PartialEq, Eq)]
468pub(crate) enum Dwc2EpType {
469 Control,
470 Isochronous,
471 Bulk,
472 Interrupt,
473}
474
475impl Dwc2EpType {
476 const fn bits(self) -> u32 {
477 match self {
478 Self::Control => 0,
479 Self::Isochronous => 1,
480 Self::Bulk => 2,
481 Self::Interrupt => 3,
482 }
483 }
484}
485
486#[derive(Debug, Clone, Copy, PartialEq, Eq)]
487pub(crate) struct FifoRegisterPlan {
488 pub(crate) grxfsiz: u32,
489 pub(crate) gnptxfsiz: u32,
490 pub(crate) hptxfsiz: u32,
491}
492
493#[derive(Debug, Clone, Copy, PartialEq, Eq)]
494pub(crate) enum Dwc2TransferFault {
495 Nak,
496 Stall,
497 Ahb,
498 Xact,
499 Babble,
500 FrameOverrun,
501 DataToggle,
502 HaltedWithoutComplete,
503}
504
505pub(crate) fn build_gahbcfg_internal_dma(arch: u32) -> core::result::Result<u32, USBError> {
506 if arch != 2 {
507 return Err(USBError::NotSupported);
508 }
509 Ok((1 << 0) | (7 << 1) | (1 << 5))
510}
511
512pub(crate) fn fifo_register_plan(fifo: Dwc2FifoSizes) -> FifoRegisterPlan {
513 let rx = u32::from(fifo.rx_depth);
514 let nptx = u32::from(fifo.non_periodic_tx_depth);
515 let ptx = u32::from(fifo.periodic_tx_depth);
516 FifoRegisterPlan {
517 grxfsiz: rx,
518 gnptxfsiz: (nptx << 16) | rx,
519 hptxfsiz: (ptx << 16) | (rx + nptx),
520 }
521}
522
523pub(crate) fn hctsiz_ddma(pid: Dwc2Pid, n_descs: u32, schinfo: u32) -> u32 {
526 ((pid.bits() & 0b11) << 29) | ((n_descs.saturating_sub(1).min(0xff)) << 8) | (schinfo & 0xff)
527}
528
529pub(crate) fn hcchar(
530 device: u8,
531 endpoint: u8,
532 direction: Direction,
533 ep_type: Dwc2EpType,
534 max_packet_size: u16,
535 low_speed: bool,
536 mult: u8,
537) -> u32 {
538 let mut value = u32::from(max_packet_size.max(1)) & 0x7ff;
539 value |= (u32::from(endpoint) & 0x0f) << 11;
540 value |= (direction as u32) << 15;
541 if low_speed {
542 value |= 1 << 17;
543 }
544 value |= ep_type.bits() << 18;
545 value |= (u32::from(mult.saturating_sub(1)) & 0x3) << 20;
547 value |= (u32::from(device) & 0x7f) << 22;
548 value
549}
550
551pub(crate) fn hcint_fault(bits: u32) -> Option<Dwc2TransferFault> {
552 if bits & HCINT_STALL != 0 {
553 Some(Dwc2TransferFault::Stall)
554 } else if bits & HCINT_NAK != 0 {
555 Some(Dwc2TransferFault::Nak)
556 } else if bits & HCINT_AHBERR != 0 {
557 Some(Dwc2TransferFault::Ahb)
558 } else if bits & HCINT_XACTERR != 0 {
559 Some(Dwc2TransferFault::Xact)
560 } else if bits & HCINT_BBLERR != 0 {
561 Some(Dwc2TransferFault::Babble)
562 } else if bits & HCINT_FRMOVRN != 0 {
563 Some(Dwc2TransferFault::FrameOverrun)
564 } else if bits & HCINT_DATATGLERR != 0 {
565 Some(Dwc2TransferFault::DataToggle)
566 } else if bits & (HCINT_CHHLTD | HCINT_XFERCOMPL) != 0 {
567 None
568 } else {
569 Some(Dwc2TransferFault::HaltedWithoutComplete)
570 }
571}
572
573pub(crate) fn fault_to_transfer_error(fault: Dwc2TransferFault, hcint: u32) -> TransferError {
574 match fault {
575 Dwc2TransferFault::Stall => TransferError::Stall,
576 Dwc2TransferFault::Nak => TransferError::Other(anyhow!("DWC2 transfer NAK")),
577 Dwc2TransferFault::Ahb => TransferError::Other(anyhow!("DWC2 AHB error hcint={hcint:#x}")),
578 Dwc2TransferFault::Xact => {
579 TransferError::Other(anyhow!("DWC2 transaction error hcint={hcint:#x}"))
580 }
581 Dwc2TransferFault::Babble => {
582 TransferError::Other(anyhow!("DWC2 babble error hcint={hcint:#x}"))
583 }
584 Dwc2TransferFault::FrameOverrun => {
585 TransferError::Other(anyhow!("DWC2 frame overrun hcint={hcint:#x}"))
586 }
587 Dwc2TransferFault::DataToggle => {
588 TransferError::Other(anyhow!("DWC2 data toggle error hcint={hcint:#x}"))
589 }
590 Dwc2TransferFault::HaltedWithoutComplete => {
591 TransferError::Other(anyhow!("DWC2 halted without completion hcint={hcint:#x}"))
592 }
593 }
594}
595
596pub(crate) fn endpoint_number(address: u8) -> u8 {
597 address & 0x0f
598}
599
600pub(crate) fn endpoint_type_to_dwc2(ty: EndpointType) -> Result<Dwc2EpType> {
601 match ty {
602 EndpointType::Control => Ok(Dwc2EpType::Control),
603 EndpointType::Isochronous => Ok(Dwc2EpType::Isochronous),
604 EndpointType::Bulk => Ok(Dwc2EpType::Bulk),
605 EndpointType::Interrupt => Ok(Dwc2EpType::Interrupt),
606 }
607}
608
609pub(crate) fn dma_addr32(addr: u64) -> core::result::Result<u32, TransferError> {
610 u32::try_from(addr)
611 .map_err(|_| TransferError::Other(anyhow!("DWC2 DMA address above 32-bit mask: {addr:#x}")))
612}
613
614fn device_descriptor_base_from_bytes(data: [u8; 8]) -> DeviceDescriptorBase {
615 DeviceDescriptorBase {
616 length: data[0],
617 descriptor_type: data[1],
618 usb_version: u16::from_le_bytes([data[2], data[3]]),
619 class: data[4],
620 subclass: data[5],
621 protocol: data[6],
622 max_packet_size_0: data[7],
623 }
624}
625
626struct Dwc2Device {
627 address: u8,
628 regs: Dwc2Registers,
629 kernel: Kernel,
630 port_speed: Speed,
631 channel_pool: HostChannelPool,
632 stats: Dwc2Stats,
633 desc: Option<DeviceDescriptor>,
634 ctrl_ep: EndpointHandle,
635 config_desc: Vec<ConfigurationDescriptor>,
636 current_config_value: Option<u8>,
637 eps: BTreeMap<u8, EndpointHandle>,
638 ep_interfaces: BTreeMap<u8, u8>,
639}
640
641struct Dwc2DeviceParams {
642 address: u8,
643 regs: Dwc2Registers,
644 kernel: Kernel,
645 port_speed: Speed,
646 channel_pool: HostChannelPool,
647 stats: Dwc2Stats,
648}
649
650#[derive(Clone, Copy)]
651enum Dwc2QuiesceReason {
652 Reconfigure,
653 Disconnect,
654}
655
656unsafe impl Send for Dwc2Device {}
657
658impl Dwc2Device {
659 fn new(params: Dwc2DeviceParams) -> Result<Self> {
660 let Dwc2DeviceParams {
661 address,
662 regs,
663 kernel,
664 port_speed,
665 channel_pool,
666 stats,
667 } = params;
668 let raw = Dwc2Endpoint::new(Dwc2EndpointParams {
669 regs,
670 kernel: kernel.clone(),
671 device_address: 0,
672 port_speed,
673 info: EndpointInfo::control(),
674 channel_pool: channel_pool.clone(),
675 stats: stats.clone(),
676 })?;
677 Ok(Self {
678 address,
679 regs,
680 kernel,
681 port_speed,
682 channel_pool,
683 stats,
684 desc: None,
685 ctrl_ep: EndpointHandle::new(EndpointInfo::control(), raw),
686 config_desc: Vec::new(),
687 current_config_value: None,
688 eps: BTreeMap::new(),
689 ep_interfaces: BTreeMap::new(),
690 })
691 }
692
693 async fn init(&mut self) -> Result<()> {
694 let base = self.get_device_descriptor_base().await?;
695 self.set_address().await?;
696 self.ctrl_ep
697 .with_raw_mut::<Dwc2Endpoint, _>(|ep| ep.set_device_address(self.address));
698 self.ctrl_ep
699 .with_raw_mut::<Dwc2Endpoint, _>(|ep| ep.set_max_packet_size(base.max_packet_size_0));
700 self.kernel.delay(Duration::from_millis(10));
701
702 let desc = self.ctrl_ep.get_device_descriptor().await?;
703 self.current_config_value = Some(self.ctrl_ep.get_configuration().await?);
704 for index in 0..desc.num_configurations {
705 let config = self.ctrl_ep.get_configuration_descriptor(index).await?;
706 self.config_desc.push(config);
707 }
708 self.desc = Some(desc);
709 if let Some(config) = self.config_desc.first() {
710 self.set_configuration_inner(config.configuration_value)
711 .await?;
712 }
713 Ok(())
714 }
715
716 async fn get_device_descriptor_base(&mut self) -> Result<DeviceDescriptorBase> {
717 let mut data = [0u8; 8];
718 self.ctrl_ep
719 .get_descriptor(DescriptorType::DEVICE, 0, 0, &mut data)
720 .await?;
721 Ok(device_descriptor_base_from_bytes(data))
722 }
723
724 async fn set_address(&mut self) -> Result<()> {
725 self.ctrl_ep
726 .control_out(
727 ControlSetup {
728 request_type: RequestType::Standard,
729 recipient: Recipient::Device,
730 request: Request::SetAddress,
731 value: self.address as u16,
732 index: 0,
733 },
734 &[],
735 )
736 .await?;
737 Ok(())
738 }
739
740 async fn set_configuration_inner(&mut self, configuration_value: u8) -> Result<()> {
741 let old_endpoints = self.eps.values().cloned().collect::<Vec<_>>();
742 for endpoint in &old_endpoints {
743 endpoint.revoke();
744 }
745 if Self::quiesce_endpoints(old_endpoints.iter(), Dwc2QuiesceReason::Reconfigure)
746 .await
747 .is_err()
748 {
749 return Err(USBError::InterfaceBroken);
750 }
751 if let Err(err) = self.ctrl_ep.set_configuration(configuration_value).await {
752 for endpoint in &old_endpoints {
753 endpoint.reactivate();
754 }
755 return Err(err.into());
756 }
757 self.current_config_value = Some(configuration_value);
758 self.eps.clear();
759 self.ep_interfaces.clear();
760 Ok(())
761 }
762
763 async fn claim_interface_inner(
764 &mut self,
765 interface: u8,
766 alternate: u8,
767 ) -> Result<BTreeMap<u8, EndpointHandle>> {
768 let pending_endpoints = self.prepare_interface_endpoints(interface, alternate)?;
769 let stale_addresses = self
770 .ep_interfaces
771 .iter()
772 .filter_map(|(address, owner)| (*owner == interface).then_some(*address))
773 .collect::<Vec<_>>();
774 let old_endpoints = stale_addresses
775 .iter()
776 .filter_map(|address| self.eps.get(address).cloned())
777 .collect::<Vec<_>>();
778 for endpoint in &old_endpoints {
779 endpoint.revoke();
780 }
781 if Self::quiesce_endpoints(old_endpoints.iter(), Dwc2QuiesceReason::Reconfigure)
782 .await
783 .is_err()
784 {
785 return Err(USBError::InterfaceBroken);
786 }
787
788 if let Err(err) = self
789 .ctrl_ep
790 .control_out(
791 ControlSetup {
792 request_type: RequestType::Standard,
793 recipient: Recipient::Interface,
794 request: Request::SetInterface,
795 value: alternate as u16,
796 index: interface as u16,
797 },
798 &[],
799 )
800 .await
801 {
802 for endpoint in &old_endpoints {
803 endpoint.reactivate();
804 }
805 return Err(err.into());
806 }
807 for address in stale_addresses {
808 self.eps.remove(&address);
809 self.ep_interfaces.remove(&address);
810 }
811 for (address, endpoint) in &pending_endpoints {
812 self.eps.insert(*address, endpoint.clone());
813 self.ep_interfaces.insert(*address, interface);
814 }
815 Ok(pending_endpoints)
816 }
817
818 async fn release_interface_inner(&mut self, interface: u8) -> Result<()> {
819 let stale_addresses = self
820 .ep_interfaces
821 .iter()
822 .filter_map(|(address, owner)| (*owner == interface).then_some(*address))
823 .collect::<Vec<_>>();
824 let old_endpoints = stale_addresses
825 .iter()
826 .filter_map(|address| self.eps.get(address).cloned())
827 .collect::<Vec<_>>();
828 for endpoint in &old_endpoints {
829 endpoint.revoke();
830 }
831 if Self::quiesce_endpoints(old_endpoints.iter(), Dwc2QuiesceReason::Reconfigure)
832 .await
833 .is_err()
834 {
835 return Err(USBError::InterfaceBroken);
836 }
837 for address in stale_addresses {
838 self.eps.remove(&address);
839 self.ep_interfaces.remove(&address);
840 }
841 Ok(())
842 }
843
844 async fn disconnect_inner(&mut self) -> Result<()> {
845 let mut endpoints = self.eps.values().cloned().collect::<Vec<_>>();
846 endpoints.push(self.ctrl_ep.clone());
847 for endpoint in &endpoints {
848 endpoint.revoke();
849 }
850 if Self::quiesce_endpoints(endpoints.iter(), Dwc2QuiesceReason::Disconnect)
851 .await
852 .is_err()
853 {
854 return Err(USBError::InterfaceBroken);
855 }
856 self.eps.clear();
857 self.ep_interfaces.clear();
858 Ok(())
859 }
860
861 async fn quiesce_endpoints<'a>(
862 endpoints: impl Iterator<Item = &'a EndpointHandle>,
863 reason: Dwc2QuiesceReason,
864 ) -> Result<()> {
865 for endpoint in endpoints {
866 let request_id =
867 endpoint.with_raw_mut::<Dwc2Endpoint, _>(|raw| raw.in_flight_request_id());
868 let Some(request_id) = request_id else {
869 continue;
870 };
871 endpoint
872 .with_raw_mut::<Dwc2Endpoint, _>(|raw| raw.cancel_request(request_id))
873 .map_err(USBError::from)?;
874 poll_fn(|cx| {
875 endpoint.with_raw_mut::<Dwc2Endpoint, _>(|raw| {
876 if let Some(result) = raw.reclaim_request(request_id) {
877 return Poll::Ready(match result {
878 Ok(_) | Err(TransferError::Cancelled) => Ok(()),
879 Err(TransferError::Disconnected)
880 if matches!(reason, Dwc2QuiesceReason::Disconnect) =>
881 {
882 Ok(())
883 }
884 Err(err) => Err(USBError::from(err)),
885 });
886 }
887 raw.register_waker(request_id, cx);
888 Poll::Pending
889 })
890 })
891 .await?;
892 }
893 Ok(())
894 }
895
896 fn prepare_interface_endpoints(
897 &self,
898 interface: u8,
899 alternate: u8,
900 ) -> Result<BTreeMap<u8, EndpointHandle>> {
901 let endpoints = self
902 .find_interface_endpoints(interface, alternate)?
903 .to_vec();
904 let mut prepared = BTreeMap::new();
905 for desc in endpoints {
906 let info = EndpointInfo::from(&desc);
907 let raw = Dwc2Endpoint::new(Dwc2EndpointParams {
908 regs: self.regs,
909 kernel: self.kernel.clone(),
910 device_address: self.address,
911 port_speed: self.port_speed,
912 info,
913 channel_pool: self.channel_pool.clone(),
914 stats: self.stats.clone(),
915 })?;
916 prepared.insert(desc.address, EndpointHandle::new(info, raw));
917 }
918 Ok(prepared)
919 }
920
921 fn find_interface_endpoints(
922 &self,
923 interface: u8,
924 alternate: u8,
925 ) -> Result<&[EndpointDescriptor]> {
926 for config in &self.config_desc {
927 for iface in &config.interfaces {
928 if iface.interface_number != interface {
929 continue;
930 }
931 for alt in &iface.alt_settings {
932 if alt.alternate_setting == alternate {
933 return Ok(&alt.endpoints);
934 }
935 }
936 }
937 }
938 Err(USBError::NotFound)
939 }
940}
941
942impl DeviceOp for Dwc2Device {
943 fn id(&self) -> usize {
944 self.address as usize
945 }
946
947 fn backend_name(&self) -> &str {
948 "dwc2"
949 }
950
951 fn descriptor(&self) -> &DeviceDescriptor {
952 self.desc
953 .as_ref()
954 .expect("DWC2 device descriptor must be initialized before device publication")
955 }
956
957 fn configuration_descriptors(&self) -> &[ConfigurationDescriptor] {
958 &self.config_desc
959 }
960
961 fn ctrl_ep_ref(&self) -> &EndpointHandle {
962 &self.ctrl_ep
963 }
964
965 fn ctrl_ep_mut(&mut self) -> &mut EndpointHandle {
966 &mut self.ctrl_ep
967 }
968
969 fn claim_interface<'a>(
970 &'a mut self,
971 interface: u8,
972 alternate: u8,
973 ) -> BoxFuture<'a, Result<BTreeMap<u8, EndpointHandle>>> {
974 self.claim_interface_inner(interface, alternate).boxed()
975 }
976
977 fn release_interface<'a>(&'a mut self, interface: u8) -> BoxFuture<'a, Result<()>> {
978 self.release_interface_inner(interface).boxed()
979 }
980
981 fn set_configuration<'a>(&'a mut self, configuration_value: u8) -> BoxFuture<'a, Result<()>> {
982 self.set_configuration_inner(configuration_value).boxed()
983 }
984
985 fn disconnect(&mut self) -> BoxFuture<'_, Result<()>> {
986 self.disconnect_inner().boxed()
987 }
988
989 fn update_hub(&mut self, _params: HubParams) -> BoxFuture<'_, Result<()>> {
990 async { Ok(()) }.boxed()
991 }
992}
993
994#[cfg(test)]
995mod tests {
996 extern crate std;
997
998 use super::*;
999
1000 #[test]
1001 fn hctsiz_ddma_encodes_pid_ntd_schinfo() {
1002 assert_eq!(hctsiz_ddma(Dwc2Pid::Data0, 1, 0), 0);
1003 assert_eq!(hctsiz_ddma(Dwc2Pid::Setup, 1, 0), 3 << 29);
1004 assert_eq!(
1005 hctsiz_ddma(Dwc2Pid::Data1, 2, 0x55),
1006 (2 << 29) | (1 << 8) | 0x55
1007 );
1008 assert_eq!(hctsiz_ddma(Dwc2Pid::Data0, 256, 0), 255 << 8);
1010 assert_eq!(
1012 hctsiz_ddma(Dwc2Pid::Data2, 256, 0xff),
1013 (1 << 29) | (255 << 8) | 0xff
1014 );
1015 assert_eq!(hctsiz_ddma(Dwc2Pid::MData, 1, 0), 3 << 29);
1016 }
1017
1018 #[test]
1019 fn hcint_fault_maps_nak_stall_xact_and_bus_errors() {
1020 assert_eq!(hcint_fault(HCINT_STALL), Some(Dwc2TransferFault::Stall));
1021 assert_eq!(hcint_fault(HCINT_NAK), Some(Dwc2TransferFault::Nak));
1022 assert_eq!(hcint_fault(HCINT_XACTERR), Some(Dwc2TransferFault::Xact));
1023 assert_eq!(hcint_fault(HCINT_AHBERR), Some(Dwc2TransferFault::Ahb));
1024 assert_eq!(hcint_fault(HCINT_BBLERR), Some(Dwc2TransferFault::Babble));
1025 assert_eq!(
1026 hcint_fault(HCINT_FRMOVRN),
1027 Some(Dwc2TransferFault::FrameOverrun)
1028 );
1029 assert_eq!(
1030 hcint_fault(HCINT_DATATGLERR),
1031 Some(Dwc2TransferFault::DataToggle)
1032 );
1033 assert_eq!(hcint_fault(HCINT_CHHLTD), None);
1035 assert_eq!(hcint_fault(HCINT_CHHLTD | HCINT_XFERCOMPL), None);
1036 assert_eq!(
1038 hcint_fault(1 << 11),
1039 Some(Dwc2TransferFault::HaltedWithoutComplete)
1040 );
1041 assert_eq!(
1042 hcint_fault(0),
1043 Some(Dwc2TransferFault::HaltedWithoutComplete)
1044 );
1045 }
1046}