Skip to main content

crab_usb/backend/kmod/dwc2/
mod.rs

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/// Hardware signal that confirms a DWC2 core soft reset has completed.
68#[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            // SG2002 exposes the post-4.20a CSFTRST_DONE handshake even
113            // though its GSNPSID revision field reports an older value.
114            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        // 硬件不具备 DDMA 能力时直接拒绝,
214        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        // channel_count 已钳制到 2..=16,`1 << 16 − 1` 即为全 16 位 HAINTMSK。
246        let channel_mask = (1u32 << channel_count) - 1;
247        // The caller registers the controller IRQ before initialization, but
248        // only `CoreOp::enable_irq` publishes runtime events. Clear stale
249        // status while masked so port power-on cannot re-enter half-built HCD
250        // state through PRTINT/HCHINT.
251        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
523/// HCTSIZ 的 DDMA 编码:PID + NTD(描述符数 − 1)+ SCHINFO。
524/// XFERSIZE/PKTCNT 在 Descriptor DMA 模式不使用(Linux 同)。
525pub(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    // MULTICNT = mult − 1(ISO/INT 多事务计数)。
546    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        // NTD 8 位截断。
1009        assert_eq!(hctsiz_ddma(Dwc2Pid::Data0, 256, 0), 255 << 8);
1010        // ISO MC 编码:DATA2=1、MDATA=3。
1011        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        // CHHLTD(± XFERCOMPL)是正常通道终止,不是故障。
1034        assert_eq!(hcint_fault(HCINT_CHHLTD), None);
1035        assert_eq!(hcint_fault(HCINT_CHHLTD | HCINT_XFERCOMPL), None);
1036        // 非完成位(如 BNA)没有 CHHLTD/XFERCOMPL → 无完成暂停。
1037        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}