RK3588 kernel-6.1 drivers/usb/core 详细分析 1. 范围与源码基准
目录 :rk3588/kernel-6.1/drivers/usb/core/
产物 :与 CONFIG_USB 对应的核心模块 usbcore (通常模块名为 usbcore)。
Makefile 编译列表 (节选):
1 2 3 4 5 6 7 8 usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o usbcore-y += devio.o notify.o generic.o quirks.o devices.o usbcore-y += phy.o port.o usbcore-$(CONFIG_OF) += of.o usbcore-$(CONFIG_USB_PCI) += hcd-pci.o usbcore-$(CONFIG_ACPI) += usb-acpi.o
本文按 文件职责 、相互关系 、典型调用链 说明;更完整的 枚举步骤与 Hub 函数级追踪 可与同目录 rk3588-kernel-6.1-USB总线枚举匹配与数据传输分析.md 对照阅读。
2. 设计目标:usbcore 在内核 USB 主机栈中的位置 usbcore 不是某一种 USB 设备的「功能驱动」,而是 主机侧通用层 :
层次
主要职责
接口级驱动 (如 usb-storage)
绑定 usb_interface,完成类协议与上层子系统对接
usbcore(本目录)
设备模型、URB、同步消息封装、Hub 逻辑、HCD 框架、描述符解析、sysfs/usbfs、电源与异常策略
具体 HCD (drivers/usb/host/、dwc3 等)
寄存器、调度环、DMA、硬件中断
分层原则 (hcd.c 头部注释概括):错误检查、URB 与设备跟踪、虚拟 Root Hub 的共性逻辑尽量留在 usbcore;只有必须区分硬件的部分才下沉到各 hc_driver 。
3. 模块依赖关系(逻辑) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 usb_register() / 设备枚举 │ ┌──────────────┼──────────────┐ ▼ ▼ ▼ driver.c hub.c generic.c (匹配/probe) (拓扑/枚举) (选配置/通用设备侧) │ │ │ └──────────────┼──────────────┘ ▼ urb.c ◄──► message.c(同步封装) │ ▼ hcd.c ◄──► buffer.c(DMA 缓冲) │ ▼ 各 HCD(ehci/xhci/dwc3-host…)
用户态旁路 :devio.c 实现 usbfs (历史上 /proc/bus/usb,现为 /dev/bus/usb/BBB/DDD ),可在无内核类驱动时直接提交 URB(需权限)。
4. 逐文件说明 4.1 usb.c — 「USB 库」与杂项辅助 文件头明确:不是带回调的驱动,而是一组通用辅助例程 。
典型内容包括:
usb_disabled() / nousb :内核命令行或模块参数层面关闭 USB。
自动挂起默认延时 (CONFIG_PM 下 usb_autosuspend_delay)。
usb_find_common_endpoints() / _reverse :在给定 altsetting 中查找首个或末个 bulk-in/out、interrupt-in/out,供驱动简化端点发现。
其它散布的字符串、描述符、电源相关辅助(与 config.c、generic.c 协同)。
定位 :上层驱动常用的 工具函数集合 ,减轻重复解析描述符的代码。
4.2 hcd.c — Host Controller Driver 框架与 Root Hub 核心职责:
struct usb_hcd / struct hc_driver 生命周期
典型入口:usb_add_hcd() / usb_remove_hcd() (HCD 驱动在 probe 中调用)。
虚拟 Root Hub
USB2/3/3.1 等 Root Hub 设备描述符 静态表;软件模拟 Hub 行为,使上层 hub 驱动 能以统一方式处理根端口与外置 Hub。
URB 与总线的桥接
如 usb_hcd_giveback_urb() :HCD 完成传输后将 URB 交回 usbcore(触发完成回调)。
usb_hcd_unmap_urb_for_dma() 等与 DMA 映射协作。
端口 resume、RH 状态轮询
例如 usb_hcd_poll_rh_status() 、usb_hcd_{start,end}_port_resume() 。
总线号管理
usb_bus_idr 、全局 usb_hcds_loaded 位图等。
设计要点 :把「所有主机控制器都要做的事」收拢到此文件,减少各 HCD 复制粘贴 ;硬实时寄存器操作仍在具体 HCD。
4.3 hub.c — Hub 驱动与设备枚举主干 体积最大,承担 USB 即插即用 的核心:
Hub 作为内核里的 usb_driver :匹配 Hub 接口,管理 struct usb_hub 。
hub_wq 工作队列 :hub_event() 路径处理端口状态变化、供电、速度协商、TT 等,避免在硬中断里做重逻辑。
枚举关键步骤 (与 usb_device 生命周期紧密耦合):端口连接/断开、debounce、分配设备号、复位、读描述符、usb_new_device() 一带的设备注册等。
Hub 特性 :MTT、TT buffer、电源管理、大量 quirks (特定厂商 Hub 行为)。
导出符号 :如 usb_hub_claim_port / usb_hub_release_port 、usb_root_hub_lost_power 等供电源或其它子系统使用。
原理 :无论 Root Hub 还是外置 Hub,端口上的设备发现与状态机 都收敛到 Hub 子系统,从而 接口驱动不必关心「设备怎样被挂上总线」 。
4.4 urb.c — URB 生命周期与提交入口
分配/释放 :usb_alloc_urb() / usb_free_urb() ,引用计数 kref ,可选 URB_FREE_BUFFER 连带释放传输缓冲。
初始化 :usb_init_urb() 、各类 usb_fill_*_urb() (control/bulk/int/isoc)。
锚点 :usb_anchor_* ,便于驱动批量跟踪或取消一组 URB。
核心入口 :usb_submit_urb() —— 校验设备状态、端点类型、wMaxPacketSize、SuperSpeed isoc 突发等,然后转入 HCD 队列;usb_kill_urb() / usb_unlink_urb() 用于同步取消或异步unlink。
原理 :URB 是主机侧异步 I/O 原语 ;usbcore 在此集中做 一致性校验 ,减轻各 HCD 重复判断。
4.5 message.c — 同步传输与控制路径
usb_start_wait_urb() :提交 URB 后用 completion 阻塞等待(带超时则 usb_kill_urb() )。
usb_control_msg() 及一组 usb_control_msg_* :封装 SETUP + DATA + STATUS 流程。
批量/中断等同步读写 :基于上述等待模型封装。
配置相关 :内部 cancel_async_set_config 等与 usb_set_configuration 异步路径协作。
字符串描述符 :usb_string() 等(依赖 NLS)。
注意 :注释强调 usb_control_msg() 不可中断、不适合中断上下文;中断上下文应 usb_submit_urb() 。
4.6 driver.c — USB 设备模型与驱动绑定
usb_register() / usb_deregister() (接口驱动)、usb_register_device_driver() 等。
usb_device_id 匹配 :静态表 + 动态 new_id sysfs(usb_store_new_id() )。
probe / disconnect / suspend / resume 与内核 device_driver 绑定的封装。
USB device driver(针对 whole device) 与 interface driver 的分支逻辑。
与 generic.c 、授权(authorize)、forced unbind 等协作(部分符号在 usb.h 声明)。
原理 :USB 设备常含 多接口 ,默认绝大多数驱动绑定 interface ;少数场景使用 device driver 。
4.7 config.c — 配置/接口/端点描述符解析
从 GET_DESCRIPTOR 得到的原始缓冲区walk:解析 configuration → interface → endpoint ,处理 IAD 、SuperSpeed Endpoint Companion 、SSP isoc companion 等扩展描述符。
find_next_descriptor() 等跳过未知描述符,保证前向兼容。
usb_parse_configuration() 、usb_get_configuration() (与 message.c 协作获取完整描述符树)。
限制:USB_MAXALTSETTING 、USB_MAXCONFIG 等硬上限,防止畸形描述符耗尽内核内存。
定位 :把 Chapter 9 二进制描述符变成 usb_host_config / usb_host_interface / usb_host_endpoint 等内核结构。
4.8 buffer.c — HCD 级 DMA 一致缓冲
hcd_buffer_create() / destroy() :按档位创建 dma_pool (默认最大长度档位见 pool_max[] ),供该总线上驱动共享;初始化阶段 usb_init_pool_max() 对照 ARCH_KMALLOC_MINALIGN 。
hcd_buffer_alloc() / free() :
若有 localmem_pool (局部内存池),走 gen_pool_dma_* ;
若控制器 !hcd_uses_dma ,退化为 kmalloc / kfree ,dma 填哨兵值;
否则优先命中 pool,否则 dma_alloc_coherent 。
hcd_buffer_alloc_pages() / free_pages() :页级大块路径。
原理 :小额 DMA 分配高频,用 per-HCD pool 降低 dma_alloc_coherent 碎片与开销;PIO 主机不走 DMA。
4.9 endpoint.c — 端点 sysfs
为每个 usb_host_endpoint 创建 ep_device 子设备,导出 地址、类型、方向、wMaxPacketSize、解码后的 interval 等 只读属性 。
便于调试与调试策略脚本,不参与传输调度。
4.10 sysfs.c — 设备与接口 sysfs
usb 设备节点 :厂商、产品、序列号、bConfigurationValue 读写 (切换配置)、authorized 、速度、quirks、OTG 相关等。
接口节点 :modalias 、driver 绑定链接等。
与 driver.c 的配置切换、quirks.c 标志联动密切。
4.11 devices.c — debugfs /sys/kernel/debug/usb/devices 拓扑文本
将 总线—拓扑—带宽—描述符—接口—端点—驱动名 格式化为 人类可读文本 (类 UNIX usbfs devices 的现代等价物)。
poll 支持唤醒监听进程。
适用于 lsusb -v 之外的内核视角快照 。
4.12 devio.c — usbfs(/dev/bus/usb/*/*)
struct usb_dev_state :每个打开的文件描述符对应的状态;维护异步 URB 链表、内存映射列表、mmap DMA 等。
ioctl :提交 URB、** reap **、批量释放、disconnect notify 信号、CAPTURE 权限退化等。
USB_SG_SIZE 等对大包拆分逻辑。
安全模型 :直接对外开放 USB 需要 capability;历史上多起 CVE 与此路径有关,内核在此有大量锁与校验。
4.13 file.c — USB 主设备号与 USB minor 转发
注册 USB 主字符设备 :open 时根据 minor 查找 usb_minors[] 中注册的 file_operations (通常由 usb-serial、audio 等 usb_class_driver 注册)。
usb_register_dev() / usb_deregister_dev() 的配合实现。
定位 :USB 字符设备类驱动 共用的 动态 minor 调度 ,不是 usbfs。
4.14 generic.c — USB 设备级通用驱动
usb_choose_configuration() :无专用 whole-device 驱动时,按供电、接口类(RNDIS、ActiveSync、音频 UAC3 等)启发式挑选配置。
usb_generic_driver_* :probe/disconnect/suspend/resume 钩子,让 未绑定专用 device driver 的设备仍能 选配置、绑定接口驱动 。
这是 「先看接口驱动,设备侧兜底」 的关键。
4.15 quirks.c — VID/PID 与工作区标志
静态表 + 模块参数 quirks 动态追加 USB_QUIRK_* 。
usb_detect_quirks() / usb_detect_interface_quirks() :枚举后打上 udev->quirks ,影响 message.c (如延迟控制传输)、hub 、HCD 路径。
usb_endpoint_is_ignored() :极端畸形设备上忽略某端点。
原理 :USB 生态有大量固件瑕疵,quirks 是在标准之上的必要补丁层 。
4.16 notify.c — USB 通知链
usb_register_notify() / unregister :blocking notifier ,事件如 USB_DEVICE_ADD / USB_DEVICE_REMOVE / USB_BUS_ADD / USB_BUS_REMOVE 。
典型订阅者:电源管理、桌面会话、调试工具。
4.17 phy.c / phy.h — Root Hub 多 PHY 封装
usb_phy_roothub_alloc() :从 DT phys 列表 devm_of_phy_get_by_index ,聚合多条 PHY。
usb_phy_roothub_{init,exit,pwr_on,pwr_off,set_mode} :统一遍历调用 phy_* ,保证 USB2 + USB3 PHY 等同生命周期。
HCD/platform 驱动在 probe 时按需取用,避免散落重复代码。
4.18 port.c — usb_port 设备与端口 sysfs
Hub 下每个 物理端口 对应 struct usb_port 设备(可与 peer 、USB4 等概念交互)。
disable 、链路伙伴 、component master 等与电源、Type‑C 协作的属性(依配置)。
将 端口级策略 从 hub 内部静态结构 抽到 device model ,便于 sysfs/udev。
4.19 of.c — 设备树辅助(CONFIG_OF)
usb_of_get_device_node() :按 hub 子节点 reg == port 查找挂接在该端口上的 device node 。
usb_of_has_combined_node() :判断是否 device/interface 共用 DT 节点 (单配置单接口等条件)。
usb_of_get_interface_node() :接口级节点查找。
用于 固件描述固定插入设备 (无枚举或枚举后匹配)。
4.20 hcd-pci.c — PCI USB 主机配角协同(CONFIG_USB_PCI)
Companion controller (同一 PCI slot 上 EHCI + UHCI/OHCI )之间的 handoff :防止 EHCI probe 时抢夺端口导致 companion 状态不一致。
pci_get_drvdata 遍历 for_each_companion 等逻辑。
嵌入式 RK3588 若无非 PCIe USB,此文件可能不参与链接,但属于 usbcore 对 PC 架构历史兼容 的重要部分。
4.21 usb-acpi.c — ACPI glue(CONFIG_ACPI)
usb_acpi_power_manageable() :端口是否有 ACPI 电源资源。
usb_acpi_port_lpm_incapable() :通过 _DSM 判定 USB3 U1/U2 是否应禁用(retimer 等场景)。
其它 Hub 端口 ACPI handle、功耗辅助。
4.22 usb.h — core 内部 API 头 对本目录各 .c 声明 :
sysfs 创建/删除、端点 enable/disable、usb_set_configuration 、generic driver、hub_wq kick、PM 路径、usb_device_match_id 等。
usb_get_max_power() :按速度区分 2mA / 8mA 单位。
不对外导出给用户驱动 ,仅为 drivers/usb/core 内部解耦编译单元。
4.23 hub.h Hub 驱动与其它 .c(如 port.c、usb-acpi.c )共享的结构体与内联;外部模块一般不直接 include。
4.24 ledtrig-usbport.c(CONFIG_USB_LEDS_TRIGGER_USBPORT) 将 USB 端口活动 映射到 LED trigger ,独立目标文件,非 usbcore 本体。
4.25 otg_productlist.h Hub 等使用的 OTG/HNP 相关产品列表数据(宏展开),供 hub.c include。
5. 关键调用链速查 5.1 异步传输(驱动常见路径) 1 2 3 4 5 6 usb_submit_urb() -> usb_hcd_submit_urb()(hcd.c) -> hcd->driver->urb_enqueue()(具体 HCD) … 硬件完成 … usb_hcd_giveback_urb() -> urb->complete()
5.2 枚举(简化) 1 2 3 4 hub_irq → kick hub_wq → hub_event → hub_port_connect_change → hub_port_connect → usb_new_device → usb_enumerate_device → usb_get_configuration → config.c 解析 → device_add → driver core → usb_driver.probe
5.3 同步控制传输 1 2 usb_control_msg() → usb_internal_control_msg() → usb_start_wait_urb() → usb_submit_urb() → … → completion
6. 阅读源码的建议顺序
hcd.c 头部注释 + usb_add_hcd / giveback_urb
urb.c :usb_submit_urb 校验逻辑
driver.c :注册与 match
hub.c :hub_event、hub_port_connect (可配合上文枚举文档)
config.c :描述符解析
message.c、buffer.c :同步 IO 与 DMA 缓冲策略
devio.c (若关心 usbfs 与安全模型)
7. 与仓库内其它文档的关系
文档
侧重点
rk3588-kernel-6.1-drivers-usb目录结构与分层原理.md
整个 drivers/usb 子目录地图
rk3588-kernel-6.1-USB总线枚举匹配与数据传输分析.md
枚举、匹配、URB、RK3588 DWC3/xHCI 衔接
本文
drivers/usb/core 每个编译单元职责与设计取舍
基于 rk3588/kernel-6.1/drivers/usb/core 源码阅读整理;内核版本以树内 Makefile / 符号为准。