首页/目录/全部文章

全部文章

八个专题的源码、算法与协议笔记都在这里。

笔记列表

USB Core 设备模型、枚举与匹配

USB Core 设备模型、枚举与匹配

1. 对象层次

1
2
3
4
5
6
usb_bus
└─ usb_device
└─ usb_host_config
└─ usb_interface
└─ usb_host_interface (altsetting)
└─ usb_host_endpoint

一个复合设备的不同interface可分别绑定UVC、UAC、HID、CDC等驱动。

2. Hub枚举

hub.c主路径:

1
2
3
4
5
6
7
8
9
10
11
port status change
-> hub_event
-> port debounce/reset
-> usb_alloc_dev
-> address device
-> read device descriptor
-> read configurations
-> usb_new_device
-> device_add
-> authorize/configure
-> interface probe

USB2先在地址0交互再SET_ADDRESS;SuperSpeed由xHCI/Hub协议配合slot/address。

3. 描述符

config.c解析device/config/interface/endpoint及class-specific extra descriptors,执行长度、数量和duplicate检查。驱动不能信任设备给出的长度。

4. 匹配

usb_device_match()支持:

  • vendor/product;
  • device class/subclass/protocol;
  • interface class/subclass/protocol;
  • bcdDevice range;
  • driver_info。

通常使用 MODULE_DEVICE_TABLE(usb, ids)自动加载模块。

5. Probe

usb_probe_interface()

-检查授权和condition;
-runtime PM get;
-选择默认altsetting;
-调用driver probe;
-建立端点/sysfs;
-允许autosuspend。

失败时执行unbind和PM回滚。

6. Configuration

usb_set_configuration()会disable旧interfaces/endpoints、发送SET_CONFIGURATION、创建新interface devices并重新匹配。切换不是对活动I/O透明操作。

7. Altsetting

usb_set_interface()用于音视频带宽/端点布局切换。旧URB必须先停止,避免向已disable endpoint提交。

8. Disconnect

Hub检测拔出后:

1
2
3
4
5
6
usb_disconnect
-> mark not attached
-> unbind interfaces
-> kill pending activity
-> remove sysfs
-> release address/device

Driver disconnect必须同步work/URB并允许设备已物理消失。

9. Generic driver

无interface driver时,USB generic device driver负责configuration和基础PM,不等于设备功能可用。

URB、端点、DMA 与传输生命周期

URB、端点、DMA 与传输生命周期

1. URB

struct urb描述一次异步Host传输:

  • device/endpoint pipe;
  • transfer buffer/length;
  • setup packet;
  • DMA address;
  • interval;
  • ISO packet descriptors;
  • complete callback/context;
  • status/actual_length;
  • flags。

2. 提交

1
2
3
4
5
6
7
usb_submit_urb
-> 参数/设备/endpoint检查
-> PM和带宽约束
-> usb_hcd_submit_urb
-> map_urb_for_dma
-> hc_driver->urb_enqueue
-> controller ring/queue

成功后URB归USB Core/HCD异步持有,buffer在complete前不得释放或修改。

3. 完成

1
2
3
4
5
hardware IRQ
-> HCD harvest completion
-> usb_hcd_giveback_urb
-> unmap DMA
-> urb->complete

Callback可能在atomic语义下,不能睡眠;驱动通常从callback重新提交RX URB。

4. 取消

  • usb_unlink_urb():异步请求取消;
  • usb_kill_urb():同步等待callback结束;
  • usb_poison_urb():阻止再次submit直到unpoison。

Disconnect/remove通常使用kill/poison。

5. Anchor

usb_anchor_urb()把多个URB归组:

  • suspend时kill anchored;
  • disconnect统一清理;
    -等待anchor为空;
    -避免漏掉并发提交。

6. DMA

Core依据HCD DMA mask映射buffer。可使用:

-普通kmalloc buffer;
-usb_alloc_coherent()
-scatter-gather;
-预映射DMA配合URB flags。

栈内存、vmalloc和生命周期不足的buffer不能直接用于一般DMA URB。

7. Transfer类型

  • Control:setup/data/status;
  • Bulk:可靠、无周期保证;
  • Interrupt:周期轮询;
  • Isochronous:预留带宽,无重传,每packet独立status。

8. 错误

常见status:

  • -EPIPE stall,可clear halt;
  • -EPROTO/-EILSEQ链路/协议;
  • -ETIMEDOUT
  • -ESHUTDOWN/-ENODEV拔出;
  • -ENOENT/-ECONNRESET取消;
  • -EOVERFLOW设备超长。

9. 同步API

usb_control_msg()usb_bulk_msg()内部仍基于URB并等待completion。不可从不能睡眠的上下文调用。

HCD、Root Hub 与 xHCI/EHCI/OHCI

HCD、Root Hub 与 xHCI/EHCI/OHCI

1. HCD抽象

usb_hcd代表控制器实例;hc_driver提供:

  • reset/start/stop;
  • urb_enqueue/dequeue;
  • endpoint_disable/reset;
  • get_frame;
  • hub_status_data/hub_control;
  • bus suspend/resume;
  • bandwidth和stream操作。

2. 注册

1
2
3
4
5
6
7
usb_create_hcd
-> map MMIO/request IRQ
-> usb_add_hcd
-> register usb_bus
-> create virtual root hub
-> start controller
-> hub thread枚举ports

Root hub不是外部USB设备,Hub class请求由HCD回调模拟。

3. xHCI

xHCI管理USB2和USB3两套logical root hubs:

  • device slots;
  • endpoint contexts;
  • command ring;
  • transfer rings/TRBs;
  • event ring;
    -interrupters;
    -streams;
    -port protocol capabilities。

DWC3 host模式创建 xhci-hcd platform子设备,把低地址xHCI寄存器窗口交给标准xHCI driver。

4. EHCI

EHCI服务USB2 High-Speed,使用QH/qTD和periodic schedule。FS/LS通过外部/根Hub Transaction Translator,或交给companion OHCI。

5. OHCI

OHCI服务USB1.1 FS/LS,使用ED/TD/HCCA。RK3588两组EHCI节点通过companion关联OHCI。

6. RK3588组合

  • DWC3 host:xHCI同时覆盖其USB2/USB3 PHY;
  • usb_host0_ehci/ohci:u2phy2;
  • usb_host1_ehci/ohci:u2phy3;
  • RK3588额外DRD1在host配置下也创建xHCI。

7. IRQ与Giveback

HCD IRQ收割完成项,先从controller queue移除,再由usbcore giveback。HCD必须避免在持有内部spinlock时调用可能重新submit的driver callback。

8. Bandwidth

Periodic endpoint在configuration/altsetting时检查带宽。xHCI计算endpoint context/ESIT payload;EHCI维护periodic schedule。

9. Root hub PM

Port suspend、remote wake、controller runtime suspend和PHY power必须协调。Root hub power/control是控制器autosuspend的重要入口。

10. 故障

1
2
3
lsusb -t
cat /sys/kernel/debug/usb/xhci/* 2>/dev/null
dmesg | grep -Ei 'xhci|ehci|ohci|HC died|reset'

HC died通常意味着controller/clock/power/IRQ问题,而非单个class driver。

DWC3 双角色核心与 RK3588 集成

DWC3 双角色核心与 RK3588 集成

1. 文件

  • core.c:probe、PHY/clock/reset、mode、PM;
  • host.c:创建xHCI platform device;
  • gadget.c:UDC、endpoint/TRB/events;
  • ep0.c:控制端点状态机;
  • drd.c:OTG/role switch/extcon;
  • dwc3-of-simple.c:Rockchip等wrapper;
  • debugfs.c、trace。

2. MMIO分区

1
2
3
4
0x0000..0x7fff  xHCI
0xc100.. DWC3 globals
0xc700.. device registers
0xcc00.. OTG registers

Probe把xHCI区作为子设备资源,自身映射global/device区,避免重复claim。

3. Host

dwc3_host_init()创建 "xhci-hcd"

-传MMIO/IRQ;
-设置platform quirks;
-standard xHCI完成rings、root hubs和URB。

DWC3本身不重新实现Host USB协议栈。

4. Gadget

DWC3 UDC:

-注册 usb_gadget
-endpoint command配置;
-TRB ring;
-event buffer;
-EP0 SETUP/DATA/STATUS;
-connect/reset/link-state事件;
-USB2/USB3 speed。

5. DRD

dr_mode = "host"|"peripheral"|"otg"。Dual-role下role来源可为USB role switch、extcon或OTG events,dwc3_set_mode()通过work切换。

切换时需停止旧角色、reset/reconfigure core、设置PHY mode并启动新角色,不是简单改一bit。

6. RK3588 wrapper

父节点:

1
2
compatible = "rockchip,rk3588-dwc3",
"rockchip,rk3399-dwc3";

因此由dwc3-of-simple按rk3399 fallback处理clock/reset,子节点再由snps,dwc3 core probe。

7. 厂商改动

本树 dwc3_get_clocks()明确增加RK3588可选 utmipipe clocks。Host-only usbhost3_0父节点提供这两个clock;DRD0父节点只有ref/suspend/bus。

8. RK3588节点

  • usbdrd3_0 / fc000000:默认OTG,USB2 PHY0 + USBDP PHY0 U3;
  • usbhost3_0 / fcd00000:host,combo PHY2 USB3;
  • RK3588非S:usbdrd3_1 / fc400000,默认host,USB2 PHY1 + USBDP PHY1 U3。

9. Quirks

DTS禁用了部分LPM/U1/U2/PHY行为并设置parkmode等。Quirk是本BSP硬件/时序约束,不应为追求低功耗盲目删除。

10. PM

DWC3 runtime suspend需协调event buffer、PHY、clock、role和xHCI child。OTG插拔失败应同时检查parent wrapper与child PM状态。

Gadget、UDC、Composite 与 ConfigFS

Gadget、UDC、Composite 与 ConfigFS

1. 分层

1
2
3
4
5
FunctionFS / configfs / legacy gadget
-> libcomposite
-> usb_gadget API
-> UDC driver
-> controller device mode

RK3588的主要UDC是DWC3 gadget。

2. UDC

UDC driver提供:

  • gadget ops;
  • endpoint enable/disable;
  • request alloc/free/queue/dequeue;
  • pullup;
  • set_selfpowered/vbus/session;
    -start/stop gadget driver。

3. Request

usb_request是Gadget侧异步I/O:

  • buf/length/dma;
  • zero/short_not_ok;
  • status/actual;
  • complete。

Function在endpoint enable后queue RX/TX request,completion中补充队列。

4. EP0

UDC接收8-byte SETUP,Composite/function处理标准、class或vendor request。无法处理返回stall。SET_CONFIGURATION后启用functions和non-control endpoints。

5. Composite

libcomposite管理:

  • device descriptor;
  • strings;
  • configuration;
  • interface/endpoint自动分配;
  • function实例;
  • setup dispatch;
  • disconnect/reset。

6. ConfigFS

典型:

1
2
3
4
5
mount -t configfs none /sys/kernel/config
mkdir /sys/kernel/config/usb_gadget/g1
# 配置 idVendor/idProduct、strings、configs、functions
ln -s functions/acm.usb0 configs/c.1/
echo <UDC-name> > UDC

写UDC属性才真正bind并拉起soft-connect。

7. 本defconfig functions

列出ACM、Mass Storage、FunctionFS、UVC及uevent支持。是否生成某function仍取决于ConfigFS运行配置。

8. FunctionFS

用户态提供descriptors和endpoint I/O,适合ADB等复杂协议。Daemon退出会影响function启停,需处理restart。

9. Mass Storage

LUN backing file/block device必须避免被Host和本机同时挂载写入,否则文件系统损坏。只读模式更安全。

10. UVC

UVC function需正确formats/frames/streaming descriptors和带宽;SuperSpeed companion descriptor影响burst。

11. 安全

固定受控VID/PID和functions;不要在锁屏/量产默认暴露ADB、网络或可写存储;限制ConfigFS写权限。

Type-C、PD、TCPM 与 USB Role Switch

Type-C、PD、TCPM 与 USB Role Switch

1. Type-C Class

typec/class.c导出port、partner、cable、plug、orientation、roles和accessory到sysfs。它记录状态,不直接完成PD policy。

2. TCPM

TCPM是Type-C Port Manager:

-CC attach/detach;
-DRP toggle;
-source/sink状态机;
-USB PD消息;
-PDO/RDO协商;
-hard/soft reset;
-power/data/VCONN role swap;
-altmode discovery。

TCPC driver通过 tcpc_dev读写CC、polarity、VBUS、PD TX/RX。

3. TCPCI

TCPCI是标准寄存器接口。Defconfig列出:

  • TCPCI core;
  • HUSB311;
  • FUSB302;
    -DP Alt Mode。

具体板型只会使用DTS/硬件存在的controller。

4. Role Switch

usb_role_switch提供:

1
2
3
USB_ROLE_NONE
USB_ROLE_HOST
USB_ROLE_DEVICE

Connector/TCPM设置role,DWC3 consumer callback执行模式切换。

5. 数据角色与电源角色

Data Host/Device不等同Power Source/Sink。PD允许:

-DFP+Source;
-UFP+Sink;
-经role swap形成其它组合。

VBUS控制必须遵循协商和过流保护。

6. Orientation和Mux

CC polarity控制SuperSpeed lane翻转;mux/retimer选择USB3或DP Alt Mode。RK3588 USBDP PHY同时承载USB3/DP lanes,需与Type-C mux/DP bridge协调。

7. Extcon

旧平台可用extcon报告USB/USB_HOST;新设计偏向connector graph+role switch。DWC3厂商分支可能同时支持两者,避免重复状态源。

8. DTS

完整链路通常包括:

1
2
3
4
5
6
7
I2C TCPC
-> connector node
-> source PDOs/sink PDOs
-> ports graph
-> DWC3 role-switch
-> PHY/mux/DP
-> VBUS regulator

9. 故障

-只能充电无数据:role/USB2 D+/D-;
-USB2可用USB3失败:orientation/mux/SS PHY;
-反插失败:polarity;
-host无供电:VBUS regulator/PD source;
-角色抖动:CC、电阻、debounce或两套role provider冲突。

10. 安全

PD可请求高电压/功率,必须使用合规TCPC和regulator限制;Alt Mode和USB data authorization需独立策略。

USB 存储、UAS、串口与常用类驱动

USB 存储、UAS、串口与常用类驱动

1. usb-storage

storage/usb.c绑定Mass Storage interface,建立 us_data并注册SCSI host。分层:

1
2
3
4
SCSI command
-> protocol handler
-> transport BOT/CBI
-> USB bulk/control URB

2. BOT

Bulk-Only Transport:

1
CBW -> optional data -> CSW

命令串行、错误时clear halt/reset recovery。unusual_devs.h处理大量设备quirk。

3. UAS

UAS基于USB streams和SCSI task management,支持多命令并行,通常在USB3性能更好。设备/桥接固件有缺陷时会通过quirk退回BOT。

4. 存储安全

拔盘前flush/unmount;掉电、UAS reset或VBUS不足会造成I/O错误。不要仅用峰值吞吐评估稳定性。

5. USB Serial

usb-serial.c提供core:

-usb_serial/port;
-tty driver;
-probe/attach;
-read/write URBs;
-throttle;
-termios;
-disconnect。

专用drivers处理vendor control、baud、modem status。

6. Defconfig串口

列出generic、CP210x、FTDI、Keyspan、PL2303、OTI6858、Qualcomm、Sierra和Option。Modem设备常有多个interfaces,Option/QMI/WDM需正确分工。

7. ACM

CDC ACM导出 /dev/ttyACM*,与vendor USB serial的 /dev/ttyUSB*不同。

8. WDM

CDC WDM承载management messages,常与移动宽带网络driver配合。

9. HID/UVC/UAC/Network

这些class主要位于:

  • HID:drivers/hid/usbhid/
  • UVC:drivers/media/usb/uvc/
  • Audio:sound/usb/
  • USB Ethernet:drivers/net/usb/

它们依赖usbcore但不在 drivers/usb目录,目录分析不能遗漏这一边界。

10. Driver override

手工unbind/bind或driver_override适合调试;错误绑定可能让原class driver失去interface,量产不应依赖不稳定sysfs脚本。

USB 电源管理、Autosuspend 与远程唤醒

USB 电源管理、Autosuspend 与远程唤醒

1. 层级

1
2
3
4
5
interface runtime PM
-> usb_device autosuspend
-> hub port suspend
-> root hub/HCD runtime PM
-> PHY/clock/power domain

任一活跃child都可能阻止上层suspend。

2. Autosuspend

USB Core维护usage count、last_busy、autosuspend delay和disable depth。Driver需声明supports_autosuspend并正确使用:

  • usb_autopm_get_interface*()
  • usb_autopm_put_interface*()
  • usb_mark_last_busy()

3. Sysfs

1
2
3
cat /sys/bus/usb/devices/1-1/power/control
cat /sys/bus/usb/devices/1-1/power/autosuspend_delay_ms
cat /sys/bus/usb/devices/1-1/power/wakeup

on禁用runtime autosuspend,auto允许;临时改为on只用于定位。

4. Remote wake

设备、configuration、driver、hub、HCD和平台IRQ链均需支持。启用sysfs wakeup不代表PHY/board已经满足。

5. Suspend流程

Interface drivers先suspend并停止URB;随后device/port和HCD suspend。Resume顺序反向。reset_resume用于设备掉电/失去state后的重新初始化。

6. Persist

系统休眠中供电丢失时设备会disappear/re-enumerate。CONFIG_USB_DEFAULT_PERSIST在本defconfig明确关闭;个别device可通过persist属性控制,但仅适合能保持身份/state的设备。

7. DWC3

需要协调:

-xHCI child或UDC;
-event buffers;
-UTMI/PIPE clocks;
-USB2/USB3 PHY;
-DWC3 core runtime PM;
-role switch;
-PD/Type-C;
-RK3588 USB power domain。

8. VBUS

Host suspend不等于必须关VBUS。关VBUS会导致disconnect;保留VBUS增加功耗。策略取决于wake和产品需求。

9. 常见问题

-autosuspend后设备反复reset;
-UVC/UAS高负载恢复失败;
-root hub无法suspend;
-remote wake后HC died;
-Type-C detach与runtime suspend竞态;
-PHY clock提前关闭。

10. 排查

记录每层runtime_status、usage、wakeup和DWC3/xHCI日志,避免直接全局关闭autosuspend掩盖driver引用泄漏。

RK3588 USB 控制器、PHY 与端口拓扑

RK3588 USB 控制器、PHY 与端口拓扑

1. RK3588S共同部分

Controller 地址 模式 PHY
usbdrd_dwc3_0 fc000000 OTG u2phy0_otg + usbdp_phy0_u3
usb_host0_ehci/ohci fc800000/fc840000 USB2 Host u2phy2_host
usb_host1_ehci/ohci fc880000/fc8c0000 USB2 Host u2phy3_host
usbhost_dwc3_0 fcd00000 Host combphy2_psu USB3

所有SoC级节点默认disabled,由板级启用。

2. 完整RK3588附加

rk3588.dtsi增加:

Controller 地址 默认模式 PHY
usbdrd_dwc3_1 fc400000 Host u2phy1_otg + usbdp_phy1_u3

因此RK3588与RK3588S端口数量/高速lane能力不同。

3. USB2 PHY

rockchip,rk3588-usb2phy位于GRF simple-mfd:

  • PHY0服务DRD0;
  • PHY1仅完整RK3588服务DRD1;
  • PHY2/3服务两组EHCI/OHCI;
    -输出480MHz clock;
    -含OTG/host child;
    -负责line-state、VBUS/id等检测和suspend。

实现位于 drivers/phy/rockchip/phy-rockchip-inno-usb2.c,不在drivers/usb。

4. USBDP PHY

PHY0/1是USB3+DisplayPort combo PHY:

  • U3 child给DWC3;
    -DP child给DisplayPort;
    -共享lanes/PLL/GRF;
    -Type-C orientation和Alt Mode影响lane模式。

父与所用child都必须enabled。

5. Combo PHY2

combphy2_psu PHY_TYPE_USB3usbhost_dwc3_0提供USB3 lane。该DWC3节点没有列USB2 PHY,按本DTS是独立SuperSpeed host路径;对应物理接口的USB2线路需由板级其它Host controller拓扑承担。

CombPHY2是USB3/PCIe/SATA共享的组合PHY。板级若把该lane分配给PCIe或SATA,就必须禁用相应USB3 host路径,不能仅凭SoC节点存在推断端口可用。

6. EHCI/OHCI Companion

每组EHCI节点引用对应OHCI companion:

  • High-Speed交EHCI;
    -Full/Low-Speed交OHCI;
    -共享USB2 PHY/物理端口。

7. DWC3 clocks/reset

DRD wrapper提供ref/suspend/bus;host3_0还提供utmi/php/pipe。子DWC3有power domain和controller reset。

8. VBUS

SoC节点不等于connector供电完成。板级还需 regulator-fixed、GPIO enable、Type-C TCPC或USB PHY VBUS detection。

9. 物理端口映射

节点名不能直接等同PCB丝印USB1/USB2。最终映射必须结合板级DTS、原理图、hub和connector graph确认。

RK3588 USB Device Tree 与板级配置

RK3588 USB Device Tree 与板级配置

1. 启用规则

必须同时启用完整链路:

1
2
3
4
5
6
7
controller wrapper
+ DWC3 child / EHCI/OHCI
+ PHY parent
+ PHY port child
+ power domain/clocks/resets
+ VBUS regulator
+ connector/TCPC/role source

漏一个节点常表现为probe defer、PHY missing或只支持USB2。

2. EVB示例

rk3588-evb.dtsi启用:

  • u2phy0/1 OTG;
  • u2phy2/3 host;
    -两组EHCI/OHCI;
    -USBDP PHY0/1的DP和U3 child;
    -DRD0、DRD1;
    -host3_0;
    -DRD0覆盖为OTG。

RK3588S EVB没有DRD1/PHY1。

3. DWC3

1
2
3
4
5
6
&usbdrd3_0 { status = "okay"; };

&usbdrd_dwc3_0 {
dr_mode = "otg";
status = "okay";
};

父wrapper和子core都必须enabled。

4. USB2 Host

EHCI和OHCI应成对启用,且对应 u2phyN_host enabled。只开EHCI可能丢失FS/LS设备。

5. USB3 PHY

DRD0需:

1
2
&usbdp_phy0 { status = "okay"; };
&usbdp_phy0_u3 { status = "okay"; };

DP child是否启用取决于同一PHY是否承载DP。

6. Type-C

OTG Type-C还需:

-TCPC I2C node;
-connector capabilities/PDO;
-interrupt GPIO;
-VBUS regulator;
-orientation/mux graph;
-DWC3 usb-role-switch或BSP支持的extcon;
-DP endpoint graph。

具体板型可能用FUSB302、HUSB311或其它芯片。

7. Fixed Host口

固定Type-A Host无需PD,但需要正确VBUS enable和过流设计。不要把dr_mode="host"当作自动供电。

8. Maximum speed

可用 maximum-speed = "high-speed"限制到USB2以定位SS问题。它是诊断/产品约束,不修复PHY、lane或SI缺陷。

9. Quirks

保留SoC .dtsi中的 snps,*quirk,除非有芯片版本、TRM和回归测试支持修改。

10. Binding差异

本树 rockchip,dwc3.yaml没有列 rockchip,rk3588-dwc3,且描述的是较旧的扁平DWC3节点/ref_clk命名;RK3588 DTS实际使用父wrapper(rk3588-dwc3, rk3399-dwc3)加snps,dwc3子节点,并用ref/suspend/bus。因此 dtbs_check可能暴露厂商binding滞后,不能据schema缺项删除运行所需节点,应同步修订binding并核对driver。

11. 最终DT

1
2
dtc -I fs -O dts /sys/firmware/devicetree/base > running.dts
grep -n -E 'usb@|usbdrd|usb2-phy|usbdp|typec|connector' running.dts

板级include覆盖很多,运行DTB是最终事实。