首页/目录/全部文章

全部文章

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

笔记列表

RK3588 kernel-6.1:drivers/usb/isp1760 功能与实现要点

RK3588 kernel-6.1:drivers/usb/isp1760 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/isp1760/。模块 isp1760CONFIG_USB_ISP1760)。

1. 芯片与驱动定位

NXP ISP1760 / ISP1761 / ISP1763 为外置 USB 2.0 主机控制器(及部分型号的 设备控制器)IP,常挂在 CPU 本地总线 / FPGA / PCI 评估卡(如经 PLX9054 桥),不要求芯片自己做 DMA master:负载数据多在 控制器片内 SRAMurb 缓冲区 之间由驱动搬运(配合 PTD 调度)。

Kconfig 声明的限制

  • 不支持等时(ISO)传输不支持 OTG(代码里对 ISP1761Host/Device 切换有寄存器配置,OTG 协议栈仍为 TODO)。
  • 依赖 REGMAP_MMIO,寄存器访问统一走 regmap/regmap_field

与 RK3588:RK3588 片上 USB 一般为 DWC3/xHCI很少外挂 ISP176x。本目录适用于 NXP 兼容评估板、自定义总线上的 ISP176x 等场景。


2. 源码分层(Makefile

对象 文件 职责
公共核心 isp1760-core.c isp1760_register/unregisterisp1760_init_core(复位、总线宽度、过流极性、中断极性、1761 的 HC/DC IRQ 共用处理)、片内存储布局regmap 配置
总线胶水 isp1760-if.c platform(OF)、可选 PCI(PLX + ISP1761);解析 nxp,usb-isp176{0,1,3}bus-widthusb-dr-mode 等 → devflags
主机 isp1760-hcd.c usb_hcd + hc_driverPTD(Philips Proprietary Transfer Descriptor)ATL/INT/ISO 三段队列偏移(ISO 路径声明不可用)、片内 payloadisp1760_qh/isp1760_qtd
设备 isp1760-udc.c usb_gadgetISP1761/1763 带 DC);VBUS 轮询、EP/usb_request 队列
寄存器 isp1760-regs.h MMIO 偏移与宏
头文件 isp1760-core.hisp1760-hcd.hisp1760-udc.h struct isp1760_devicedevflags、导出 isp1760_set_pullup

编译选项:USB_ISP1760_HOST_ROLEUSB_ISP1760_HCDGADGET_ROLEUSB_ISP1761_UDCDUAL_ROLE → 二者都选。


3. 初始化与寄存器模型(isp1760-core.c

  1. isp1760_registerdevm_kzalloc struct isp1760_device(内含 isp1760_hcd + isp1760_udc)。
  2. ISP1760_FLAG_ISP1763 选用 1763176xregmap_configREG_FIELD 表(1763 的 DC 为 8-bit 寄存器 / 16-bit 值 等不同形态)。
  3. devm_ioremap_resource 单一 mem 窗口;HCDC 各自 devm_regmap_init_mmio(基地址相同,访问特性不同)。
  4. isp1760_init_core:可选 GPIO 复位软件复位所有模块HW Mode Control(数据线宽度、模拟/数字过流、DREQ/DACK、中断 电平/边沿)。
  5. ISP1761:临时关闭 DC 全局中断、打开 HW_COMN_IRQISP176x_HC_OTG_CTRLISP1760_FLAG_PERIPHERAL_EN主机(VBUS 驱动)外设(关闭 OTG、下拉控制) 间写死一路(注释:真正 OTG 待完成)。
  6. 若编译 HCDisp1760_hcd_register;若芯片支持且编译 UDCisp1760_udc_register(失败则撤销 HCD)。

片内 RAM 布局isp176x_memory_conf(约 60 KB,多块 256/1024/8192)与 isp1763_memory_conf(约 20 KB)供 HCD 做 slot/payload 管理。


4. 主机实现要点(isp1760-hcd.c

  • 对接 usbcore 的标准入口:urb_enqueueroot hub、端口状态位等。
  • 调度核心为硬件 PTDstruct ptd,多 DW 编码长度、设备地址、PID、分组类型、split、数据区偏移、toggle/ping/NAK/CERR、ACTIVE/错误位等),写入芯片 ISO/INT/ATL 银行等偏移(如 PTD_OFFSETATL_PTD_OFFSETPAYLOAD_OFFSET)。
  • 软件侧 isp1760_qh(每活跃 endpoint)挂 isp1760_qtd 链表,状态机 QTD_ENQUEUEDQTD_PAYLOAD_ALLOCQTD_XFER_STARTED → complete/retire
  • 文件头注释:ISO、OTG 不可用;中断缺省 低电平有效

5. 设备实现要点(isp1760-udc.c

  • usb_gadget/usb_ep,请求 isp1760_request
  • 通过 regmap_field 读写 DC 寄存器;必要时 regmap_raw_* 访问 FIFO。
  • isp1760_set_pullup(core 导出)控制 D+ 上拉
  • VBUS:定时器周期 ISP1760_VBUS_POLL_INTERVAL 轮询(非 OTG HNP 完整实现)。

6. 平台绑定(isp1760-if.c

  • OFnxp,usb-isp1760 / isp1761 / isp1763bus-widthusb-dr-modeperipheral 时置 ISP1760_FLAG_PERIPHERAL_ENanalog-ocdack-polaritydreq-polarity 等。
  • PCI:针对 PLX 9054 一类表项,检测 scratch、配置 PLX 中断路由isp1760_register 使用 resource[3] 映射区。

7. 小结

维度 内容
对上接口 Host:usb_hcd;Device(1761/1763):usb_gadget
传输 控制/批量/中断为主;ISO 未支持
数据通路 PTD + 片内 payload RAM;非典型 PCI DMA 形态
双角色 主要通过 DT + PERIPHERAL_EN 与寄存器固定 HC/DC 角色;非完整 OTG

调试时可结合 debugfs(HCD 内可选)与 usbmon(主机 URB)观察枚举与传输;移植新板级重点核对 bus-width、中断极性、复位 GPIO、usb-dr-mode

RK3588 kernel-6.1:drivers/usb/misc 功能与实现要点

RK3588 kernel-6.1:drivers/usb/misc 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/misc/。该目录在 drivers/usb/Makefile 中作为 misc 子目录引入,收录 不适配 storage/serial/class 等大类 的杂项 USB 设备或辅助代码。

官方说明见各 Kconfig 条目及 Documentation/usb/ 中与测试、EZUSB、usbmon 等交叉引用的文档。


1. 目录职责(为何存在)

杂项驱动的共同点通常是:

  • 非标准类绑定:不走单一 USB Class(或仅用_VENDOR 协议),需要专用 usb_driver + usb_control_msg/usb_bulk_msg 或少量 urb
  • 辅助其它驱动:例如 固件下载后重新枚举,交给 snd-usb-audiouvcvideo 等。
  • 板级/芯片配套:板载 Hub 上电、HSIC 桥片寄存器、Microchip Hub SMBus 配置等。
  • 测试与认证usbtestEHSETLink Layer Test 等配合特定固件或治具。

它们共享内核 USB 核心 APIstruct usb_driverusb_submit_urbusb_autopm),但彼此之间 无统一框架,逐一阅读 probe/ioctl/sysfs 即可。


2. 按功能分类(与 Makefile 对应)

2.1 固件加载 / 二次枚举

选项 文件 要点
USB_EMI26/USB_EMI62 emi26.cemi62.c Emagic 音频接口:下载固件后设备变为标准 USB Audio,由 snd-usb-audio 接管
USB_ISIGHTFW isight_firmware.c Apple iSight:加载固件后可供 UVC 栈使用
USB_EZUSB_FX2 ezusb.c Cypress FX/FX2:Vendor 控制传输写 RAMIHEX 固件8051 复位位;导出 ezusb_* 供串口等驱动复用

2.2 主机侧测试 / USB-IF 流程

选项 文件 要点
USB_TEST usbtest.c linux-usb.org/usbtest 固件配合:ioctl USBTEST_REQUEST_* 跑批量/等时/scatter、队列深度等回归
USB_EHSET_TEST_FIXTURE ehset.c Embedded Host EHSET 治具:枚举特定 VID/PID 后令下游口进入电气测试模式
USB_LINK_LAYER_TEST lvstest.c SuperSpeed Link Layer Test 专用流量

2.3 Hub / 板级 USB 扩展(与 RK3588 板级可能相关)

选项 文件 要点
USB_ONBOARD_HUB onboard_usb_hub.c(+ onboard_usb_hub_pdevs.c 离散板载 Hubregulator/GPIO 复位、上电时序;通过 usb_device_driver 等与 HCD 协作延迟绑定(见 linux/usb/onboard_hub.h
USB_HUB_USB251XB usb251xb.c Microchip USB251xI2C/SMBus 配置
USB_HSIC_USB3503/USB4604 usb3503.cusb4604.c SMSC HSIC→USB2.0 等:regmap/I2C

2.4 字符设备 / 传感器 / 趣味硬件

iowarrior.cldusb.c(中断传输传感器)、legousbtower.cadutux.cyurex.cidmouse.c(指纹)、usbsevseg.cusblcd.ccytherm.ccypress_cy7c63.ctrancevibrator.c 等:多为 misc/cdevsysfs,协议各异。

2.5 熵 / 显示 / 电源

选项 文件 要点
USB_CHAOSKEY chaoskey.c 硬件 RNG:对接 hwrng/entropy
USB_APPLEDISPLAY appledisplay.c Cinema Display 背光backlight class
USB_SISUSBVGA sisusbvga/ USB→VGA(SiS):子目录独立 Kconfig/Makefile
APPLE_MFI_FASTCHARGE apple-mfi-fastcharge.c MFi 快充开关power_supply
USB_QCOM_EUD qcom_eud.c Qualcomm EUD:调试外设、USB_ROLE_SWITCH、VBUS 事件

2.6 其它

选项 文件 要点
USB_FTDI_ELAN ftdi-elan.c ELAN U132 等 USB-CardBus 适配:USB_U132_HCD(host 目录)配合
USB_USS720 uss720.c USB-并行打印桥等
BRCM_USB_PINMAP brcmstb-usb-pinmap.c Broadcom STB:USB 信号旁路到 GPIO

3. 典型实现模式(原理)

3.1 普通设备驱动

  1. MODULE_DEVICE_TABLE(usb, ...) + usb_driverprobeusb_alloc_coherent/usb_submit_urb 或同步 usb_control_msg
  2. 电源usb_mark_last_busyusb_autopm(若支持运行时挂起)。
  3. 用户态接口misc_registercdevdebugfs/sysfs

3.2 固件型(emi / isight / ezusb)

probe 中检测 RAM/CPU 停机状态Vendor 下载usb_reset_device 或期待 重新枚举probe 返回,后续由 类驱动 绑定。

3.3 测试型(usbtest)

绑定特定测试设备 VID/PID(或 GENERIC + 模块参数);ioctl 解析 usbtest_param,在内核构造 长度/队列/SGurb,统计耗时并回报。

3.4 板载 Hub(onboard_usb_hub)

Platform(OF)描述 vdd、reset GPIO、延时onboard_hub_power_on 满足上电时序 → 待 USB 子系统发现下游 usb_device 后再挂接 usb_device_driver,避免 Hub 未供电时无效枚举。


4. 与 RK3588 的关联(阅读提示)

  • 常见可能启用USB_ONBOARD_HUB(板载 RTS5411 等)、USB_HUB_USB251XB / HSIC 桥(视 BOM)。
  • 开发与认证USB_TESTEHSET/LVS 多用于 HCD/IP 验证,产品内核可裁掉。
  • 其余条目多为 特定外设或架构(如 USB_QCOM_EUDBRCM_USB_PINMAP),与 RK3588 无必然关系

5. 小结

drivers/usb/misc 不是单一子系统,而是 按 Kconfig 粒度可选的一兜小型 usb_driver:从 固件加载合规测试Hub 初始化各种小众 USB 硬件。理解方式:锁定 CONFIG_* → 打开对应 .cusb_driver 表与 probe 主路径,不必强求统一架构。

RK3588 kernel-6.1:drivers/usb/mon 功能与实现要点

RK3588 kernel-6.1:drivers/usb/mon 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/mon/。内核文档:Documentation/usb/usbmon.rst(Kconfig 中亦有指向)。

1. 驱动定位(USB Monitor / usbmon)

CONFIG_USB_MON 编译为 usbmon.ko(或内置 usbmon.o),实现 USB 流量窥探:在 urb 提交、提交失败、完成回调 等关键点抓取事件,供 debugfs(及部分二进制字符接口)读出。

观测边界:钩子插在 drivers/usb/core/hcd.cusb_hcd_submit_urb / usb_hcd_giveback_urb(近似路径)上,因此捕获的是 主机控制器栈上的 URB(设备侧驱动 ↔ HCD)。Gadget 侧 usb_request 不走这套 usbmon_urb_* 钩子(仓库内仅 hcd.c 调用 usbmon_urb_*)。


2. 文件分工

文件 职责
mon_main.c 模块 init/exit;usb_mon_register 向 usbcore 注册 usb_mon_operationsUSB_BUS_ADD/USB_BUS_REMOVE notifier;struct mon_bususb_bus 绑定;mon_reader_* 管理读者并开关 usb_bus->monitored
mon_text.c 文本格式 trace:debugfs 下可按总线打开;事件 mon_event_text;载荷 DATA_MAX=32 字节封顶(大块应用二进制接口)
mon_bin.c 二进制格式:环形缓冲、ioctlMON_IOC_*)、可携带更长 payload;mon_bin_hdr 用户可见布局
mon_stat.c 0s 类统计:读者数、事件计数、text_lost根权限,注释说明)
usb_mon.h mon_bus/mon_reader 回调原型 rnf_submit/rnf_error/rnf_complete

3. 与 usbcore 的衔接(实现原理)

3.1 注册与 hot path 门槛

include/linux/usb/hcd.h(在 CONFIG_USB_MON 时)定义 struct usb_mon_operationsusbmon_urb_submit/usbmon_urb_submit_error/usbmon_urb_complete

  • 仅当 bus->monitored != 0 时才调用 mon_ops->...,避免无监听时的开销。
  • usb_mon_registerhcd.c 末尾实现:全局 mon_ops 指针,带 mb(),故意 不在热路径持锁

3.2 HCD 调用点

hcd.cusb_hcd_submit_urb 里:DMA map / urb_enqueue 之前usbmon_urb_submit;若 urb_enqueue 失败usbmon_urb_submit_error。在 usb_hcd_giveback_urb(完成路径)调 usbmon_urb_complete

3.3 何时 monitored == 1

mon_main.c

  • 每个 usb_busmon_bus_init(Notifier USB_BUS_ADD 或模块加载时遍历已有总线)里分配 mon_bus,并 mon_text_add/mon_bin_add 创建 debugfs 节点。
  • mon_bus0:逻辑「所有总线」;有读者打开 mon_bus0 时,list_for_each 把所有已知 usb_bus->monitored 置 1。
  • 针对某一 usbNmon_bus:该总线第一个读者到来时 monitored = 1;最后一个读者离开 mon_stop 清 0。

事件分发:mon_submit 先发到 ubus->mon_bus 上的读者,再发到 mon_bus0 上的读者(全局监听重复收到同一条 URB 属于设计)。


4. 文本与二进制接口要点

  • 文本:适合人工阅读;setup 最多 8 字节;数据快照 有意限制长度以防用户态不读导致内核积压(仍有 EVENT_MAXcnt_text_lost 统计丢事件)。
  • 二进制CHUNK_SIZE 页对齐块、默认/最大缓冲 BUFF_DFL/BUFF_MAXMON_IOCX_GET/MFETCH 等批量取事件;适合抓 Bulk 等大数据。
  • 统计mon_stat.c 读取 mon_busnreaders/cnt_events/cnt_text_lost

实际挂载路径与节点命名以实现为准(常见在 /sys/kernel/debug/usbmon);权限模型依赖 debugfs 与内核 DAC,文档强调需特权以防嗅探 HID 密码等。


5. 小结

项目 说明
抓什么 主机侧 urb:submit / submit-fail / complete
不抓什么 Gadget 栈(无对应钩子)
开关 usb_bus.monitored + mon_ops 非空
扩展 新读者实现 mon_reader 三套 rnf_* 即可接入 mon_bus

调试 RK3588 主机 USB 枚举与传输时,若已启用 USB_MON,可配合 usbmon.rst 与用户态 cat/`Wireshark**(pcap)流程分析 URB 时间线。

RK3588 kernel-6.1:drivers/usb/mtu3 功能与实现要点

RK3588 kernel-6.1:drivers/usb/mtu3 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/mtu3/。模块名 mtu3CONFIG_USB_MTU3)。

1. 驱动定位

MTU3(MediaTek USB3 Dual Role Controller)是联发科 SoC 上的 USB2 + USB3(可选 Gen2)双角色控制器 Linux 驱动,在同一 SSUSB IP 上可同时具备:

  • 设备侧:自有 U3D MAC,对接 usb_gadgetmtu3_gadget*.cmtu3_core.c)。
  • 主机侧:不自建 OHCI/EHCI,而是配合 drivers/usb/host/xhci-mtk.cCONFIG_USB_XHCI_MTK),由 USB_MTU3 Kconfig select;MTU3 负责 上电、时钟、PHY、端口、DRD,再在 DT 子节点上 of_platform_populate 注册 xHCI platform 设备

与 RK3588:驱动 depends on ARCH_MEDIATEK || COMPILE_TEST。RK3588 为 Rockchip,不使用 MTU3;RK3588 主线对应 drivers/usb/dwc3 等。本文档仍以「源码阅读/IP 架构」为主。


2. Kconfig / Makefile 与编译组合

选项 作用
USB_MTU3_HOST 仅主机:编译 mtu3_plat.o + mtu3_host.o
USB_MTU3_GADGET 仅设备: mtu3_plat.o + mtu3_core.o / mtu3_gadget*.o / mtu3_qmu.o
USB_MTU3_DUAL_ROLE OTG:HOST + GADGET 全套,另编 mtu3_dr.o;依赖 EXTCONUSB_ROLE_SWITCH
USB_MTU3_DEBUG 打开 DEBUG 编译开关

MakefileCONFIG_TRACING 时增加 mtu3_trace.oDEBUG_FS 时增加 mtu3_debugfs.o


3. 数据结构与寄存器视图(mtu3.h / mtu3_hw_regs.h

3.1 struct ssusb_mtk

顶层 platform 设备私有数据:指向 struct mtu3 *u3d,映射 mac_base(设备 MAC,不含 xHCI 寄存器窗)、ippc_baseIP Power & Clock,端口开关、主机/设备掉电、复位),以及 struct phy **regulatorclocksotg_switchdr_modeis_host、端口数量与屏蔽(u2_ports/u3_ports/u2p_dis_msk/u3p_dis_msk**)、可选 mediatek,syscon-wakeup(主机 ip-sleep 唤醒)。

3.2 struct mtu3

Gadget 实例:EP 数组、TX/RX FIFO 位图(按 512B 单元 MTU3_EP_FIFO_UNIT 管理)、中断、slot(U2/U3 IP 的 FIFO 倍增系数)、u3_capable/gen2cp(USB3 Gen2 兼容,影响 MTU3_TRUNK_VERS_1003 相关 CSR 布局)。

3.3 struct otg_switch_mtk

双角色切换:regulator VBUSextcon(注释标明 deprecated,与 usb_role_switch 二选一)、desired_roledr_work(避免在原子上下文睡眠)、is_u3_drd(U3 port0 是否参与 DRD)。


4. 平台与生命周期(mtu3_plat.c

  1. 资源ioremap MAC/IPPC clk-bulkvusb33、多路 phy_init/phy_power_onreset
  2. 复位与时钟ssusb_ip_sw_resetssusb_check_clocks(轮询 PLL/MAC 稳定位)。
  3. 模式:由 usb_get_dr_mode 与 Kconfig 合成 ssusb->dr_mode;默认 is_host 在非 peripheral 时为真。
  4. 分支初始化
    • PERIPHERALssusb_gadget_init
    • HOSTssusb_host_init(内部 of_platform_populate 拉起 xHCI
    • OTG:先 Gadget,再 Host,再 ssusb_otg_switch_initmtu3_dr.c
  5. 省电pm_runtimewait_for_ip_sleep、suspend 时 关 PHY/时钟ssusb_wakeup_set 打开 syscon 唤醒 glue。

5. 主机路径(mtu3_host.c

  • host_ports_num_get:读 U3D_SSUSB_IP_XHCI_CAP 得到 U2/U3 端口数
  • ssusb_host_enable/disable:按端口掩码 PDN/使能,配置 force hostssusb_set_force_mode(..., MTU3_DR_FORCE_HOST)),必要时 port0 VBUS
  • ssusb_host_initssusb_host_setupof_platform_populate(parent_dn, ...),由 DT 子节点绑定 xhci-mtk
  • ssusb_host_suspend/resume:按端口逐个 PDN上电,并操纵 SSUSB_IP_HOST_PDN
  • 唤醒ssusb_wakeup_of_property_parse 解析 mediatek,syscon-wakeup,按 uwk_vers 写不同 PMIC/SPM 寄存器(多芯片兼容表)。

6. 双角色切换(mtu3_dr.c

  • 硬件约束:注释写明 仅 port0 支持 DRD。
  • ssusb_port0_switch:对 U2/U3 先后 PDN+DIS,再上电并 HOST_SEL 决定主机或设备。
  • switch_port_to_host/switch_port_to_device:切端口后 ssusb_check_clocks;主机路径末尾 toggle_opstateDC_SESSION + SOFT_CONN)配合链路。
  • ssusb_mode_sw_work:对比 desired_role 与当前 is_hostpm_runtime_get 后执行模式切换、停/启 GadgetxHCI 侧协作(与 usb_role_switch 回调衔接)。
  • ssusb_set_vbus:可选 regulator 供电。

7. Gadget / 核心硬件层(mtu3_core.c 等)

  • FIFOep_fifo_alloc 在位图上分配连续 512B 块;与 slotmaxpacket 对齐 power-of-two
  • 速度mtu3_speed(inactive / FS / HS / SS / SSP)。
  • 设备使能mtu3_device_enable:清 SSUSB_IP_DEV_PDN,配置 U2/U3 port0 非 HOST、可选 OTG_SEL/DUAL_MODEmtu3_device_disable 反向。
  • USB3mtu3_ss_func_setUSB3_EN → LTSSM);HS softconnectSOFT_CONN
  • 中断 / EP0:与 mtu3_gadget_ep0.c 的状态机(enum mtu3_g_ep0_state)联动。

8. QMU(mtu3_qmu.c / mtu3_qmu.h

Queue Management Unit:硬件队列 DMA,使用 GPD(General Purpose Descriptor) 环形缓冲区(struct mtu3_gpd_ring,见 struct qmu_gpd 位域说明)。入口包括 mtu3_qmu_start/stopmtu3_insert_gpdmtu3_qmu_isr。Gen2 IP 支持更长 buffer(GPD_BUF_SIZE vs GPD_BUF_SIZE_EL)。


9. 小结

维度 说明
芯片 MediaTek SSUSB:设备 U3D + 主机 xHCI(mtk glue)
对上接口 Gadget:usb_gadget;Host:usb_hcdxhci-mtk 提供
DRD Port0 U2/U3 切换 + usb_role_switch/extcon + workqueue
PHY/电源 Generic phy_*vusb33、可选 VBUS regulator
RK3588 不适用;对照阅读 dwc3 + phy-rockchip 即可

若要对照主机栈,请同时打开 drivers/usb/host/xhci-mtk.cDocumentation/devicetree/bindings/usb/mediatek,*.yaml(若树内存在)中的 SSUSB / xhci 子节点关系。

RK3588 kernel-6.1:drivers/usb/musb 功能与实现要点

RK3588 kernel-6.1:drivers/usb/musb 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/musb/。公开板级配置头:include/linux/usb/musb.h(FIFO、模式、platform_data)。

1. 驱动定位

MUSB / MHDRCMultipoint Highspeed Dual-Role Controller)是 Mentor Graphics Inventra 系列 USB2 OTG IP 的 Linux 驱动,模块名 commonly musb-hdrcMUSB_DRIVER_NAME)。

  • 主机:实现 usb_hcd,经 musb_host.c + musb_virthub.c 接入 usbcore(含软件实现的 root hub)。
  • 设备:实现 usb_gadget/usb_ep,见 musb_gadget.cmusb_gadget_ep0.c
  • 双角色:Kconfig USB_MUSB_DUAL_ROLE 同时编进主机与 Gadget;配合 DEVCTL、VBUS/ID、usb_phy/struct phy 与 glue 层 set_mode 等在主机与外设间切换。

与 RK3588:Rockchip RK3588 片上 USB 以 DWC3 / xhci 等为主流;drivers/usb/musb 无 Rockchip glue。Arm64 defconfig 里可能出现 CONFIG_USB_MUSB_SUNXI 等其它 SoC 选项,不代表 RK3588 产品路径。分析本目录仍以 IP 与软件架构 为主。


2. 构建结构(Makefile

目标 内容
musb_hdrc musb_core.o(核心 + 中断/会话)、musb_trace.o
Host / DRD musb_host.omusb_virthub.oCONFIG_USB_MUSB_HOSTDUAL_ROLE
Gadget / DRD musb_gadget.omusb_gadget_ep0.o
Debug musb_debugfs.oCONFIG_DEBUG_FS
Glue(平台一块) omap2430.oam35x.omusb_dsps.osunxi.cmediatek.cdavinci.cda8xx.ctusb6010*.cux500*.cjz4740.cmpfs.c 等,二选一/多选一 与具体 SoC 绑定
DMA musbhsdma.o(Inventra)、cppi_dma.o / musb_cppi41.o(TI)、tusb6010_omap.oux500_dma.oMUSB_PIO_ONLY 可强制纯 PIO(EP0 等路径仍靠 CPU)

Kconfig 要求 PIO 与多种 DMA 方案互斥编译,运行时也可用 use_dma=n 模块参数关闭 DMA(注释见 Kconfig)。


3. 核心抽象(musb_core.h / musb_core.c

3.1 struct musb

驱动实例的中心结构,主要包括:

  • 寄存器与 IOmregsctrl_basemusb_platform_ops 封装 索引式/扁平式 EP 寻址FIFO 读写W1C 行为差异 等。
  • 硬件端点endpoints[MUSB_C_NUM_EPS],每项为 struct musb_hw_ep(FIFO 指针、TXCSR/RXCSR、主机侧 musb_qh 队列首指针、Gadget 侧 musb_ep in/out)。
  • 主机调度队列:控制、in_bulk/out_bulkpending_listbulk_ep 指向用于批量传输的专用 HW EP。
  • DMAdma_controller(抽象 dma_channel,见 musb_dma.h)。
  • PHYxceivusb_phy)与 phy(Generic PHY),glue 可选 phy_callback
  • 模式is_hostsessionport_mode(来自 usb_get_dr_modemusb_get_mode)、OTG 定时器。
  • 工作队列/延时工作:IRQ bottom half(irq_work)、复位/resume/gadget 相关延后任务。

文件头部注释明确:硬件不做主机侧事务调度,需软件调度;多设备/hub 场景能力受限(批量端点占用、NAK、带宽记账不足等),调试时需心里有数。

3.2 struct musb_platform_ops(Glue 契约)

平台 glue 必须提供的能力包括:enable/disableep_offset/ep_selectread_fifo/write_fifo(或与默认 musb_io 组合)、可选 dma_init/dma_exitset_modeset_vbusrecover(babble)等。
quirks 位标明 TUSB6010indexed EP、各类 DMA 引擎 等,核心与 DMA 文件据此分支。

3.3 中断与会话

核心集中处理 USB/TX/RX 等中断标志,再分到主机或 Gadget;isr 可被 glue 先行过滤。ULPI 读写(musb_ulpi_read/write)通过 usb_phyio_priv 访问 MHDRC 内 ULPI .viewport。


4. 主机路径(musb_host.c

  • hcd_to_musbhcd->hcd_priv 指向 struct musb *
  • 调度模型:注释说明 控制走 EP0批量占用专用 IN/OUT 硬件 EP(理论上可扩展更多批量 EP,实现仍偏保守);中断/等时动态绑定其余 EP,调度策略偏「朴素」。
  • 队列头 musb_qh:挂 urb,配合 musb_ep_programTXCSR/RXCSR、长度、toggle(get_toggle/set_toggle 可平台定制)。
  • FIFO:主机发送前可能 musb_h_tx_flush_fifo,避免 BABBLE(注释含 AM335x 等平台已知竞态)。

musb_virthub.c:实现 root hub 端口状态、复位、resume 等与 usbcore 的交互(MUSB 端口能力与标准 EHCI/xHCI 不同,由软件 hub 适配)。


5. Gadget 路径(musb_gadget*.c

  • musb_ep 包装 usb_ep,请求为 musb_request(内嵌 usb_request)。
  • EP0 状态机enum musb_g_ep0_state(SETUP → DATA → STATUS),与主机侧 musb_h_ep0_state 对称,由核心 IRQ 与控制寄存器驱动。

6. DMA 抽象(musb_dma.h + musbhsdma.c 等)

struct dma_controller:分配通道、绑定 HW EP 与方向、处理 short packet / buffer full、在 DMA 完成中断里唤醒上层。
不同 SoC 寄存器块不同(如 Inventra HSDMA 基址 MUSB_HSDMA_BASE);Host 侧 DMA 映射由 usbcore 侧准备Gadget 侧由 gadget 框架准备(头文件注释)。


7. 小结表

维度 说明
硬件 IP Mentor Inventra USB2 OTG(多版本 HWVER)
对上接口 Host:usb_hcd;Device:usb_gadget
关键软件对象 struct musbmusb_hw_epmusb_qhDMA controller
平台差异 全部由 musb_platform_ops + glue .c 吸收(FIFO 布局、中断共享、PHY、DMA)
RK3588 无 musb glue;主线 USB 以 DWC3 等为主,本目录用于理解 Inventra/MUSB 或维护 Allwinner/TI/MediaTek 等平台

若要对照寄存器,可结合 musb_regs.h 与具体 SoC TRM;若要跟踪一次 URBmusb_urb_enqueue 到 FIFO/DMA 的路径,可从 musb_host.cmusb_urb_submit / musb_schedule 一类符号向下追。

RK3588 kernel-6.1:drivers/usb/phy 功能与实现要点

RK3588 kernel-6.1:drivers/usb/phy 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/phy/。与之配套的 struct usb_phy API 定义在 include/linux/usb/phy.h

1. 目录在内核 USB 栈里的位置

  • drivers/usb/Makefile:在 USB_SUPPORT 打开时编译 phy/
  • CONFIG_USB_PHYdrivers/usb/phy/Kconfig 中由各个收发器选项 select,并 select EXTCON,以便充电器/VBUS 等可走 extcon 链路。
  • 服务对象:主要是 USB 控制器驱动(EHCI/OHCI/MUSB/DWC2/Gadget UDC 等),而不是枚举得到的 usb_device/usb_gadget 功能驱动。控制器通过 usb_get_phy / devm_usb_get_phy* 取得收发器,在 init/shutdown/省电/OTG/供电能力 等路径调用钩子。

与 RK3588 的常见误解:Rockchip 片上 USB2/USB3 combo PHY / Inno PHY 等通常在 drivers/phy/rockchip/Linux Generic PHY 框架phy_getphy_power_on),由 dwc3ehci-platform 等通过 generic_phydrm/时钟门控 衔接。RK3588 默认配置文件不一定启用 drivers/usb/phy 里的具体芯片驱动;本目录更多是 TI/OMAP/Freescale/Marvell/Tegra 等传统收发器与 NOP ULPI 的历史集合。


2. 核心框架:phy.c

职责可以概括为三类:注册与查找事件通知充电器 / extcon 协作

2.1 全局链表与查找

  • 维护 phy_list(带 phy_lock),每个 usb_phy 通过 head 挂在链表上。
  • usb_add_phy / usb_add_phy_dev / usb_remove_phy:收发器驱动在 probe 时把自己暴露给子系统。
  • usb_get_phy(type):按 enum usb_phy_typeUSB_PHY_TYPE_USB2 / USB_PHY_TYPE_USB3)查找第一个匹配的 PHY。
  • devm_usb_get_phy_by_phandle / devm_usb_get_phy_by_node:配合 DT phys / usb-phy 绑定(OF 节点与已注册 usb_phy->dev->of_node 匹配)。
  • __of_usb_find_phy(内部):OF 节点不可用时返回 -EPROBE_DEFER,便于控制器 defer probe

2.2 usb_phy 结构与钩子(摘自 usb/phy.h

控制器与子系统真正使用的是 struct usb_phy 中的:

  • 生命周期initshutdownset_suspendset_wakeup
  • 供电set_vbusset_power(常与共存的 usb_phy_set_charger_current 结合)
  • 链路notify_connectnotify_disconnect
  • ULPIio_ops->read/writeio_priv(控制器侧 viewport,收发器寄存器经 usb_phy_io_read/write 访问)

另有 struct usb_otg *otg:部分驱动通过 usb_otg 绑定 usb_gadgetusb_hcd,在 OTG 状态机里切换角色。

2.3 原子 notifier:usb_phy_events

atomic_notifier_head notifier:收发器或 NOP 驱动在 VBUS、ID、charger、枚举完成 等时机调用 usb_phy_set_event 或直接向 notifier 广播;控制器/Gadget 栈注册 usb_register_notifier 即可异步获知线缆/角色变化。

2.4 充电器类型与 extcon:usb_add_extcon

若 PHY 设备树带 extcon phandle:

  • 若实现了 vbus_nb:按 EXTCON_USB 监听 VBUS。
  • 否则注册 type_nb,针对 EXTCON_CHG_USB_{SDP,CDP,DCP,ACA},在回调里 __usb_phy_get_charger_type,更新 chg_type/chg_stateschedule_work(chg_work)
  • 可选 id_nbEXTCON_USB_HOST(第二 extcon id_edev 或复用同一 edev)。

usb_phy_notify_charger_work:根据 USB_CHARGER_PRESENT/ABSENT 计算 usb_phy_get_charger_current,再 atomic_notifier_call_chain,并 kobject_uevent 向 userspace 上报 USB_CHARGER_STATE/USB_CHARGER_TYPE(配合 usb_phy_uevent)。

与上层:枚举后 SDP 电流协商可走 usb_phy_set_power → 内部 usb_phy_set_charger_current


3. 设备树辅助:of.c

  • of_usb_get_phy_mode(np):读 phy_type 字符串(utmi / utmi_wide / ulpi / serial / hsic),返回 enum usb_phy_interface
  • 供控制器驱动确定 MAC 与 PHY 之间的 数字接口形态(与 drivers/usb/phy 里具体收发器驱动 是正交的:一边是控制器配置,一边是外置 PHY)。

4. 典型收发器驱动(按 Makefile)

选项 文件 作用概要
NOP_USB_XCEIV phy-generic.c 「空」收发器:片内 PHY 或无需寄存器编程的外置 PHY;可提供 时钟、复位 GPIO、VBUS GPIO、供电 regulator、OTG gadget 绑定VBUS IRQ
USB_ULPI phy-ulpi.c 通过 usb_phy_io_opsULPI 寄存器(OTG/Func/IFC 等),识别 ISP1504、USB331x、TUSB1210 等 ID
USB_ULPI_VIEWPORT phy-ulpi-viewport.c viewport 的控制器(如 Chipidea)访问 ULPI 总线的通用读写
USB_GPIO_VBUS phy-gpio-vbus-usb.c 仅用 GPIO 感知 peripheral-only VBUS
USB_MXS_PHY phy-mxs-usb.c Freescale MXS
USB_TEGRA_PHY phy-tegra-usb.c Tegra USB PHY
AM335X_PHY_USB phy-am335x.c + phy-am335x-control.c AM335x
USB_ISP1301 / ISP1301_OMAP phy-isp1301.c / phy-isp1301-omap.c I²C ULPI 前端
FSL_USB2_OTG phy-fsl-usb.c Freescale OTG FSM
USB_MV_OTG phy-mv-usb.c Marvell OTG
KEYSTONE_USB_PHY phy-keystone.c Keystone(依赖 NOP)
其它 phy-twl6030-usb.cphy-omap-otg.cphy-keystone.cphy-jz4770.cphy-ab8500-usb.cphy-tahvo.c 各 PMIC/SoC 专用

4.1 NOP / Generic(phy-generic.c)——最常见的「胶水」

  • usb_phy_generic_register:无 DT 时可由别的代码注册简易 platform 设备。
  • nop_set_suspend:可选 gate PHY 时钟
  • nop_gpio_vbus_thread:GPIO VBUS 变化时更新 usb_otg stateatomic_notifier_call_chainUSB_EVENT_VBUS,并 nop_set_vbus_draw 限制从 VBUS 汲取电流。
  • usb_gen_phy_init / usb_gen_phy_shutdown:导出给组合 PHY 驱动复用(使能 vccclk复位脉冲)。

5. 与 Generic PHY(drivers/phy 的关系(概念)

drivers/usb/phy(本目录) drivers/phy/*(Generic PHY)
核心类型 struct usb_phy struct phy
典型 API usb_phy_initusb_get_phy phy_power_onphy_set_mode
DT physusb-phy phandle phy-* 绑定、#phy-cells

现代 SoC(含 RK3588)常把 SerDes/PIPE/USB2 analog 做成 phy-rockchip-*,由 DWC3 gluestruct phy *;这与 usb_phy两套并行框架,仅在个别驱动里会做桥接或共存。


6. 小结

  1. phy.cUSB 收发器类驱动 的注册中心,向控制器提供 查找、refcount(put/get)、notifier、charger/extcon、uevent
  2. of.c:从 DT 解析 phy_type,辅助控制器配置 UTMI/ULPI 等接口模式
  3. phy-*.c:把具体芯片或 SoC 段落塞进 struct usb_phy 的钩子;NOP 覆盖「几乎不编程」的常见情形;ULPI 覆盖外置并行收发器。
  4. RK3588 读者:若目标是 板级 USB bring-up,请同时查阅 drivers/phy/rockchip/drivers/usb/dwc3/drivers/usb/phy 更多是内核树里 通用 USB PHY 子系统经典嵌入式平台 的参考实现。

RK3588 kernel-6.1:drivers/usb/renesas_usbhs 功能与实现要点

RK3588 kernel-6.1:drivers/usb/renesas_usbhs 功能与实现要点

源码基准:rk3588/kernel-6.1/drivers/usb/renesas_usbhs/

1. 驱动定位与适用平台

Renesas USBHS 是瑞萨 SoC 上常见的 USB 2.0 全速/高速 控制器 IP,可在同一硬件上工作在 主机(Host)设备(Gadget/Peripheral) 角色(典型 OTG/DRD 用法由平台与 extcon/ID/VBUS 逻辑配合)。

  • CONFIG_USB_RENESAS_USBHS:核心框架(依赖 USB_GADGET,平台依赖 ARCH_RENESAS || SUPERH || COMPILE_TEST)。
  • CONFIG_USB_RENESAS_USBHS_HCD:在 drivers/usb/host/Kconfig 中启用 HCD,编译进同一目标 renesas_usbhs.o 时追加 mod_host.o
  • CONFIG_USB_RENESAS_USBHS_UDC:在 drivers/usb/gadget/udc/Kconfig 中启用 UDC,追加 mod_gadget.o

与 RK3588 的关系:RK3588 为 Rockchip,通常使用 DWC3/xHCI 等控制器;本目录代码 不会作为 RK3588 默认 USB 栈,仅在分析内核树或 COMPILE_TEST 时会被编译到。文档沿用仓库「kernel-6.1 源码索引」的命名习惯。


2. 源码模块划分(Makefile

对象 职责概要
common.c platform 驱动入口、usbhs_priv、MMIO 读写、SYSCFG/总线/VBUS、设备地址寄存器、extcon + 延迟 work 热插拔、时钟/复位/pm_runtime
mod.c Host/Gadget 模块注册usbhs_mod_info、共享 IRQ usbhs_interruptirq 回调屏蔽与分发;autonomy(无平台 notify_hotplug 时用 VBINT 自行调度热插拔)
pipe.c / pipe.h **Pipe(硬件管道)**抽象:类型、方向、运行状态、与 FIFO 绑定、DATA0/1 序列、stall、maxpacket 等
fifo.c / fifo.h **FIFO / 包(usbhs_pkt)**队列:PIO/DMA 路径、prepare/try_rundone 回调
mod_host.c usb_hcd 适配:URB ↔ pipe、usbhsh_* 结构与 pipe 复用策略
mod_gadget.c usb_gadget / usb_ep 适配、setup 与各 recipient 控制传输
rcar2.c / rcar3.c R-Car Gen2/Gen3 等平台:phy、DMAC 能力、driver_param(pipe 配置等)
rza.c / rza2.c RZ/A 系列差异化

common.c 开头的示意图概括了 mod_*pipefifo 的数据通路。


3. 分层与数据路径(实现原理)

3.1 硬件抽象:usbhs_priv + 平台回调

公开头文件 include/linux/usb/renesas_usbhs.h 定义 renesas_usbhs_platform_callback

  • hardware_init / hardware_exitpower_ctrlphy_reset
  • get_id:返回 USBHS_HOSTUSBHS_GADGET
  • get_vbus:VBUS 是否有效
  • set_vbus(主机供电)、可选 notifier(extcon 相关)

以及 renesas_usbhs_driver_param(pipe 个数、是否 USB-DMAC、runtime_pwctrldetection_delay 等),由各 SoC 的 *_plat_info 填入。

3.2 Pipe 与 FIFO

  • struct usbhs_pipe:对应控制器里的逻辑管道(非 Linux URB 一对一);带 handler(包处理)、fifo 指针、mod_private(host/gadget 私有)。
  • usbhs_pkt:挂在 pipe 的链表上,由 fifo.c 驱动实际收发(含 DMA map 控制钩子)。

3.3 中断:usbhs_interruptmod.c

  1. 读取并组装 usbhs_irq_stateINTSTS0/1BRDYSTSNRDYSTSBEMPSTS)。
  2. 按手册要求 写清除 中断位(注释强调 INTSTS0_MAGIC / INTSTS1_MAGIC 等敏感性)。
  3. 按当前模式调用 struct usbhs_mod 中的回调:设备状态(DVST)、控制阶段(CTRT)、FIFO 空/就绪(BEMP/BRDY);主机模式额外处理 ATTCH/DTCH/SIGN/SACK
  4. usbhs_irq_callback_update 根据当前 mod 动态开关 INTENB / BEMPENB / BRDYENB,避免与硬件行为冲突。

3.4 角色与热插拔:usbhsc_hotplugcommon.c

  • 通过 get_vbus / get_id 决定是否上电、选择 Host 或 Gadget,再调用对应 mod 的 start/stop
  • 若 DTS 带 extcon phandle,会用 extcon_get_state(..., EXTCON_USB_HOST)get_id 结果做一致性检查,不匹配则拒绝切入以免角色错误。
  • 从中断等上下文调用 usbhsc_schedule_notify_hotplug,用 delayed work 落到进程上下文执行(避免在中断里做复杂切换)。

Autonomy 模式mod.c):平台未提供「notify」路径时,用 VBINT 自行 schedule_delayed_work,并自带 get_vbus(读 INTSTS0 的 VBSTS),时钟常开。


4. 主机侧要点(mod_host.c

  • 通过 struct usb_hcd 接入 usbcore,注释明确写出硬件限制:
    • 可管理设备数量有限(约 9 台量级,与 DEVADDn 等一致)。
    • Pipe 数量有限且复用:多个下游设备的 endpoint 会 时分复用 同一 pipe,软件需维护各设备的 DATA0/1(见文件头部示意图与说明)。
  • usbhsh_device / usbhsh_ep:把 usb_device / usb_host_endpoint 映射到 usbhs_pipe

5. Gadget 侧要点(mod_gadget.c

  • struct usbhsg_gpriv 内嵌 usb_gadgetusbhs_mod,每个 usbhsg_uep 绑定一个 usbhs_pipe
  • 控制传输与各标准 recipient(device/interface/endpoint)由 usbhsg_recip_handle 分发表处理;状态位(started、registered、wedge、self-powered、soft-connect)配合 usb_phy/VBUS

6. 设备树匹配(common.cusbhs_of_match

兼容字符串覆盖多个瑞萨芯片与通用别名,例如:

  • renesas,usbhs-r8a7790renesas,rcar-gen2-usbhsusbhs_rcar_gen2_plat_info
  • renesas,usbhs-r8a7795renesas,rcar-gen3-usbhsusbhs_rcar_gen3_plat_info
  • renesas,rza1-usbhsrenesas,rza2-usbhs → RZ/A 平台信息

Gen2 示例(rcar2.c):通过 Generic PHYphy_init / phy_power_on,并声明 has_usb_dmachas_new_pipe_configs 等能力位。


7. 小结

维度 说明
协议层 USB 2.0 FS/HS;不实现 USB3
软件栈 Host:usb_hcd + usbcore;Device:usb_gadget + composite/功能驱动
核心抽象 Pipe + FIFO + pkt 队列;IRQ 统一入口再分发给 Host/Gadget
DRD/OTG 协作 平台 get_id/get_vbus + 可选 extcon + 延迟 work;可选 autonomy VBINT
平台差异 R-Car Gen2/3、RZ/A 通过 renesas_usbhs_platform_info 区分 PHY、DMAC、pipe 表与时序参数

若要对照寄存器级行为,需结合瑞萨 USBHS 用户手册(SYSCFG、PIPE/DCP、FIFO、中断屏蔽与清除顺序);本驱动注释中已标出若干「硬件挑剔」的写入顺序,调试 IRQ/FIFO 问题时应优先核对。

RK3588 kernel-6.1 drivers/usb/roles 代码功能与实现原理

RK3588 kernel-6.1 drivers/usb/roles 代码功能与实现原理

1. 目录与产物

路径:rk3588/kernel-6.1/drivers/usb/roles/

文件 Makefile 目标 作用
class.c roles.oCONFIG_USB_ROLE_SWITCH,模块名 roles.ko USB Role Switch 框架:注册 usb_role classusb_role_switch_registersysfslookup API
intel-xhci-usb-role-switch.c CONFIG_USB_ROLES_INTEL_XHCI(依赖 ACPI + X86 Intel Atom 等平台:MMIO DUAL_ROLE_CFG* 切换 xHCI ↔ dwc3 gadget

公开 API 声明:include/linux/usb/role.h


2. 要解决什么问题(Kconfig 语义)

同一 Type‑C / OTG 物理口可能:

  • 内部是一个 DRD 控制器(如 DWC3):控制器驱动内部切换 Host/Device;仍可通过 usb_role_switch 统一 对外接口 / sysfs / DT connection
  • Host 与 Device 是两颗独立控制器,中间经 MUX 连到连接器:需要 软件选定 数据通路接到哪一侧。

Role Switch 抽象的就是:把「当前口是 Host 还是 Device」变成可查询、可设置的内核对象,供 Type‑C(TCPM/extcon)、PMIC、电源策略USB 控制器 probe 协作。


3. 核心对象:struct usb_role_switchclass.c

内部字段要点:

  • enum usb_role roleUSB_ROLE_NONE / HOST / DEVICE
  • set(sw, role):必选,由 注册方(SoC glue、MUX 驱动等)实现 写硬件/ACPI
  • get(sw):可选;缺省时 usb_role_switch_get_role 返回 缓存的 sw->role(上次 set 成功值
  • mutex lock串行化 set/get
  • registeredunregisterset_role 返回 -EOPNOTSUPP
  • allow_userspace_control:为真时 sysfs role 可写(见下文)

可选 usb2_port / usb3_port / udc:文档说明用于指向 主机口设备UDC,便于后续 symlink(代码里仍有 TODO)。


4. 注册与 sysfs

usb_role_switch_register(parent, desc)

  • 创建子设备,名 {name}-role-switch(默认 {parent_name}-role-switch
  • classusb_role
  • device_typeusb_role_switch

属性 role

  • none / host / deviceusb_role_string
  • :仅在 allow_userspace_control 时可见(is_visible);写入经 sysfs_match_string 解析后调用 usb_role_switch_set_role
  • set_role 成功kobject_uevent(KOBJ_CHANGE),便于 udev

usb_role_switch_uevent:导出环境变量 USB_ROLE_SWITCH= 设备名。


5. 查找与模块引用

  • usb_role_switch_get(dev)
    • dev 的父 fwnodeusb-role-switch 属性 → 按 父节点switch
    • 否则 device_connection_find_match(dev, "usb-role-switch", …)
  • fwnode_usb_role_switch_get:DT graph / connection 等价路径
  • usb_role_switch_find_by_fwnode:按 switch 自身 fwnode 查找

找到后对 sw->module try_module_getputmodule_put

原理DWC2 dual-roleDWC3 drd.cType‑C 等通过 DT usb-role-switch 连接拿到 struct usb_role_switch *,在 线缆插入、TCPM 决策 时调用 usb_role_switch_set_role,与 dwc3_set_modephy_set_mode 等衔接。


6. Intel 参考驱动:intel-xhci-usb-role-switch.c

平台:Cherry Trail / Broxton 等 ACPI platform_deviceMMIO 寄存器 DUAL_ROLE_CFG0/1

  • intel_xhci_usb_set_role:按角色写 SW_IDPINSW_VBUS_VALIDDRD_CONFIG_*SW_SWITCH_EN;与 ACPI global lock 互斥(避免与 AML 竞争);轮询 CFG1 HOST_MODE 确认切换完成
  • intel_xhci_usb_get_role:读 CFG0 推导 Host/Device/NONE

通过 software_node 提供 fwnode,便于 connection 与其它驱动匹配;allow_userspace_control = true

RK3588:一般 不走该 Intel 驱动;角色切换多在 dwc3 + typec/extcon 路径完成,但若 DTS 引用 usb-role-switch,仍会用到 roles.ko 框架 API


7. 与其它目录的关系(概念)

1
2
3
4
5
6
7
8
9
10
TCPM / extcon / PMIC(策略)
│ usb_role_switch_set_role()

drivers/usb/roles/class.c

├─► SoC-specific set() ──► MUX / DRD 寄存器 / ACPI

└─► sysfs(可选用户态)

DWC3 gadget host dr_mode ► 常与 role switch 同步

8. 延伸阅读(本仓库)

文档
drivers-usb-typec分析.md
drivers-usb-dwc3详细分析.md

内核文档可参考:Documentation/driver-api/usb/usb-role-switch.rst(若树中存在)。


基于 rk3588/kernel-6.1/drivers/usb/rolesinclude/linux/usb/role.h 归纳。

RK3588 kernel-6.1 drivers/usb/serial 代码功能与实现原理

RK3588 kernel-6.1 drivers/usb/serial 代码功能与实现原理

1. 子系统定位

USB Serial 在内核里为 USB 通信设备类(CDC)以外的「USB ↔ 串口/VCP」 设备(以及大量厂商专有 Bulk 协议)提供统一框架:

  • 对上:暴露 /dev/ttyUSBn(主设备号 188,见 USB_SERIAL_TTY_MAJOR
  • 对下:通过 usb_interface → usb_serial_driver → bulk/int URB 与硬件交互

架构文档:Documentation/usb/usb-serial.rst


2. 模块划分(Makefile

目标 组成 作用
usbserialCONFIG_USB_SERIAL usb-serial.ogeneric.obus.o,可选 console.o 核心:TTY、usb_serial 生命周期、generic 读写完、usb-serial 伪总线
*_SERIAL_* ftdi_sio.opl2303.och341.o 芯片专用:probe、open/read_bulk/write_bulkioctl

专用驱动 depends on usbserial,由 MODULE_DEVICE_TABLE(usb, …) 触发 modprobe 加载 usbserial


3. 核心数据结构(概念)

  • struct usb_serial_driver<linux/usb/serial.h>):一种芯片/协议的「模板」,包含 usb_driver(绑定 usb_serial_probe)、id_table端口数calc_num_portsopen/closebulk/int callbackattach/release 等。
  • struct usb_serial:一次 USB 设备 probe 对应的 逻辑适配器,持有 devinterface、端口指针数组、type
  • struct usb_serial_port:单个 TTY 端口,内含 tty_portminor、bulk/int URB 缓冲serial 反向指针

minoridrserial_minors)分配,范围受 USB_SERIAL_TTY_MINORS(512) 限制。


4. 绑定与初始化:usb_serial_probeusb-serial.c

usbcore 匹配到某 usb_serial_driver

  1. search_serial_device 选出 type(持 table_lock)。
  2. create_serial 分配 usb_serialusb_serial_port
  3. 调用 type->probe(serial, id)(可选):子驱动拒绝则退出。
  4. find_endpoints:扫描接口 bulk in/out、interrupt,必要时包含 sibling 接口。
  5. 校验端点数量 ≥ type->num_bulk_* 等要求。
  6. calc_num_ports 或固定 type->num_ports 决定 tty 端口个数
  7. allocate_minorssetup_port_bulk_* / setup_port_interrupt_* 填充 URB
  8. device_add 注册 端口设备,使其落到 usb_serial_bus_type 上。

原理USB 接口驱动只做「发现资源 + 建 usb_serial」;真正注册 ttyUSB 发生在 端口 bus 的 probe(见下)。


5. usb_serial_bus_typebus.c

自定义 struct bus_typeusb-serial

  • match端口已绑定 port->serial->type,与 usb_serial_driver 一一对应。
  • probeusb_serial_device_probe:调用 driver->port_probe(可选),再 tty_port_register_device,打印 ttyUSB%d
  • removetty_unregister_deviceport_remove

原理:把 「端口」做成独立 device,便于 sysfs、电源管理与 TTY 设备节点 生命周期对齐。


6. TTY 路径(usb-serial.c

  • usb_serial_tty_drivertty_drivermajor 188
  • serial_installminor → usb_serial_port_get_by_minortty->driver_data = port,可选 init_termios
  • serial_opentty_port_openserial_port_activatetype->open(tty, port)(通常 usb_serial_generic_open + 提交 读 URB)。
  • serial_port_shutdowntype->closeusb_autopm_put_interface
  • 写路径serial_write → 子驱动或 generic 把数据塞进 bulk out URB
  • 读路径bulk in completetty_insert_flip_stringtty_flip_buffer_push

电源usb_autopm_get/put_interfaceruntime PM 绑定,避免休眠与 URB 竞态。


7. generic.c:默认 Bulk 读写

usb_serial_generic_open:提交 bulk IN URBusb_serial_generic_submit_read_urbs)。
usb_serial_generic_write_bulk_callback / read_bulk_callback:维护 环形缓冲/链表,与 TTY 层对接。
多数简单设备 不重写 read/write,仅靠 generic + 正确端点探测 即可工作。

CONFIG_USB_SERIAL_GENERIC:调试用的 「generic」驱动,仅绑定模块参数 vendor/product不推荐量产设备依赖


8. 专用驱动模式(以常见芯片为例)

ftdi_siopl2303ch341 等通常实现:

  • probe:波特率表、流控、私有 EEPROM/寄存器初始化。
  • open波特率、parity → USB 厂商命令 → 再 generic open
  • *自定义 read_int_callback*:调制解调器状态线 CTS/DCDtty_port_tty_wakeup / tty_schedule_flip

usb-serial-simple.c:宏批量生成 仅 VID/PID + 固定端口数usb_serial_driver,无专有协议。


9. 与其它子系统的关系

边界 说明
drivers/usb/class/cdc-acm.c CDC ACM 走另一套 TTY(/dev/ttyACM),不经过 usb-serial 核心
usbcore 枚举、URB;usb-serial 是普通 usb_driver
drivers/usb/core/file.c USB 字符设备 minor 与 ttyUSB 无关(后者由 tty_driver 注册)

10. 数据流简图

1
2
3
4
5
6
7
8
9
10
用户 read/write / termios


tty_io ──► usb_serial_tty_driver(major 188)


serial_open/write ──► usb_serial_driver::open/write


generic 或 ftdi/pl2303… ──URB──► usbcore ──► HCD

11. 延伸阅读(本仓库)

文档
drivers-usb-core详细分析.md
USB总线枚举匹配与数据传输分析.md

基于 rk3588/kernel-6.1/drivers/usb/serial 源码归纳。

RK3588 kernel-6.1 drivers/usb/storage 代码功能与实现原理

RK3588 kernel-6.1 drivers/usb/storage 代码功能与实现原理

1. 定位:两套路径(BOT vs UAS)

模块(Makefile 典型名称 作用
usb-storageCONFIG_USB_STORAGE usb-storage.ko USB Mass Storage Bulk-Only Transport(BOT) 及旧 CB/CBI 等:Bulk 管道搬运 SCSI CDB
uasCONFIG_USB_UAS uas.ko USB Attached SCSI:命令/状态/数据 多管道 + 可选 USB3 Streams,更接近原生 SCSI 异步模型

二者均依赖 SCSI 子系统;常见块设备还需 CONFIG_BLK_DEV_SD(sd 磁盘)。


2. USB Mass Storage 类规范与分层

usb.h 头部注释说明实现依据 USB Mass Storage Class,命令形态贴近 SCSI-II / ATAPI;类规范对 NAK/STALL/ACK 的语义与通用 USB 略有差异,部分设备用 中断端点 上报命令状态(CBI)。

内核内部分层(struct us_data):

层级 文件 职责
协议(Protocol) protocol.c scsi_cmnd 打成设备可接受的 CDB 长度/变体(透明 SCSI、UFI、Pad12 等),再调用传输
传输(Transport) transport.c CB/CBI/Bulk-Only:打包 URB、Bulk 收发、REQUEST_SENSE 自动 sense、复位与错误恢复
SCSI 胶水 scsiglue.c 注册 struct scsi_host_templatequeuecommandslave_configure(队列 max_hw_sectors、DMA bounce)、eh_abort / reset
设备生命周期与线程 usb.c usb_driver probe、根据接口 bInterfaceSubClass / Protocol 绑定 transport + proto_handler控制内核线程

大量 unusual_*.h / usual-tables.cVID/PID + quirks + 可选 init,覆盖不按规范暴露 SubClass/Protocol 的固件。


3. 核心数据结构:us_datausb.h

每个已绑定的 U 盘对应一块 us_data(挂在 Scsi_Host->hostdata):

  • USBpusb_devpusb_intf、缓存的 bulk/control/intr pipe
  • 传输/协议transporttransport_resetproto_handlersubclass/protocol/max_lun
  • 并发模型单命令槽 srb + completion cmnd_ready + usb_stor_control_thread
  • 缓冲iobuf(小 DMA 缓冲)、current_urbusb_sg_request
  • quirksfflags/dflagsuse_last_sector_hacks

4. 命令路径:queuecommand → 内核线程 → invoke_transport

4.1 SCSI 中层下发

scsiglue.cqueuecommand_lck(持 scsi_lock):

  • 保证 us->srb 为空(同一时间 一条 SCSI 命令);
  • us->srb = srb
  • complete(&us->cmnd_ready) 唤醒 usb-storage 线程。

4.2 控制线程 usb_stor_control_threadusb.c

循环 wait_for_completion(&cmnd_ready),取 us->srb,校验 LUN/target/方向,处理 FIX_INQUIRY 等特殊路径,否则调用:

1
2
3
4
5
else {
US_DEBUG(usb_stor_show_command(us, srb));
us->proto_handler(srb, us);
usb_mark_last_busy(us->pusb_dev);
}

协议层入口

4.3 协议层(protocol.c

  • usb_stor_transparent_scsi_command:直接 usb_stor_invoke_transport
  • usb_stor_pad12_command:CDB padding 到 12 字节(RBC/8070 等)
  • usb_stor_ufi_commandUFI 命令长度与 INQUIRY/MODE_SENSE/REQUEST_SENSE 长度裁剪

4.4 传输与会聚:usb_stor_invoke_transporttransport.c

usb_stor_invoke_transport

  1. result = us->transport(srb, us) —— Bulk-OnlyCBW → Data → CSW(或 CB/CBI 控制传输路径);
  2. 根据返回值决定是否 自动 REQUEST_SENSE、是否 端口复位
  3. 处理 last sector 等与劣质固件相关的补丁逻辑。

传输返回值语义transport.h):USB_STOR_TRANSPORT_GOOD/FAILED/NO_SENSE/ERROR,区分 命令失败USB 链路错误


5. get_transport / get_protocolusb.c

接口 bInterfaceProtocol传输

  • USB_PR_BULKBulk-Only(绝大多数 U 盘)
  • USB_PR_CB / USB_PR_CBIControl-Bulk[-Interrupt]

bInterfaceSubClass协议处理器

  • USB_SC_SCSI:透明 SCSI
  • USB_SC_UFI:软驱类 UFI
  • USB_SC_RBCUSB_SC_8020USB_SC_QICUSB_SC_8070:各类缩减/光学命令集

6. SCSI Host 与块层(scsiglue.c

  • slave_allocINQUIRY 长度 36队列 DMA 对齐
  • slave_configure:限制 单次传输扇区数(兼容弱设备;SuperSpeed 提到 2048 sectors)、PIO HCDbounce limit
  • queuecommandDEF_SCSI_QCMD 包装锁
  • 错误处理abort、bus reset、device resetus->dflags、URB unlink 协作

7. uas.c(独立于 BOT 路径)

  • 不为每个命令占用单一 usb-storage 线程;使用 usb_anchorworkqueuetag ↔ scsi_cmnd 映射(MAX_CMNDS)。
  • 命令 URB、状态 URB、数据 IN/OUT URBUAS 规范并行;可选 Bulk Streams
  • uas-detect.h:与 usb-storage 协同 探测:若设备支持 UAS 且无黑名单,优先绑定 uas 驱动(避免同一设备双驱动冲突)。

原理BOT 串行 CSW、单队列UAS 多命令流水,更适合 SSD / USB3


8. 子驱动(ums-*

alauda.cdatafab.cisd200.c 等:面向 非标准桥片,实现私有 transport/init,编译为独立 ums-*.ko,由 usb_storage_usb_ids / unusual 表挂载。


9. 其它文件

  • initializers.c:部分 unusual 设备的 probe 阶段初始化
  • debug.cCONFIG_USB_STORAGE_DEBUG
  • sierra_ms.c / option_ms.c调制解调器 / 复合设备 存储相关 quirks

10. 数据流简图(BOT)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
blk_mq / sd


SCSI mid-layer ──queuecommand──► us->srb + complete(cmnd_ready)


usb_stor_control_thread


proto_handler (protocol.c)


usb_stor_invoke_transport (transport.c)


transport = Bulk/CB ──URB──► usbcore ──► DWC3/xHCI … ──► 设备固件

11. 延伸阅读(本仓库)

文档
drivers-usb-core详细分析.md
USB总线枚举匹配与数据传输分析.md

基于 rk3588/kernel-6.1/drivers/usb/storage 源码归纳。