RK3588 kernel-6.1 drivers/usb/core 详细分析

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、电源与异常策略
具体 HCDdrivers/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_PMusb_autosuspend_delay)。
  • usb_find_common_endpoints() / _reverse:在给定 altsetting 中查找首个或末个 bulk-in/out、interrupt-in/out,供驱动简化端点发现。
  • 其它散布的字符串、描述符、电源相关辅助(与 config.cgeneric.c 协同)。

定位:上层驱动常用的 工具函数集合,减轻重复解析描述符的代码。


4.2 hcd.c — Host Controller Driver 框架与 Root Hub

核心职责:

  1. struct usb_hcd / struct hc_driver 生命周期
    • 典型入口:usb_add_hcd() / usb_remove_hcd()(HCD 驱动在 probe 中调用)。
  2. 虚拟 Root Hub
    • USB2/3/3.1 等 Root Hub 设备描述符静态表;软件模拟 Hub 行为,使上层 hub 驱动 能以统一方式处理根端口与外置 Hub。
  3. URB 与总线的桥接
    • usb_hcd_giveback_urb():HCD 完成传输后将 URB 交回 usbcore(触发完成回调)。
    • usb_hcd_unmap_urb_for_dma() 等与 DMA 映射协作。
  4. 端口 resume、RH 状态轮询
    • 例如 usb_hcd_poll_rh_status()usb_hcd_{start,end}_port_resume()
  5. 总线号管理
    • 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_portusb_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,处理 IADSuperSpeed Endpoint CompanionSSP isoc companion 等扩展描述符。
  • find_next_descriptor() 等跳过未知描述符,保证前向兼容。
  • usb_parse_configuration()usb_get_configuration()(与 message.c 协作获取完整描述符树)。
  • 限制:USB_MAXALTSETTINGUSB_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 / kfreedma 填哨兵值;
    • 否则优先命中 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 相关等。
  • 接口节点modaliasdriver 绑定链接等。

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、audiousb_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(如延迟控制传输)、hubHCD 路径。
  • usb_endpoint_is_ignored():极端畸形设备上忽略某端点。

原理:USB 生态有大量固件瑕疵,quirks 是在标准之上的必要补丁层


4.16 notify.c — USB 通知链

  • usb_register_notify() / unregisterblocking 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.cusb_port 设备与端口 sysfs

  • Hub 下每个 物理端口 对应 struct usb_port 设备(可与 peerUSB4 等概念交互)。
  • 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.cCONFIG_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. 阅读源码的建议顺序

  1. hcd.c 头部注释 + usb_add_hcd / giveback_urb
  2. urb.cusb_submit_urb 校验逻辑
  3. driver.c注册与 match
  4. hub.chub_eventhub_port_connect(可配合上文枚举文档)
  5. config.c:描述符解析
  6. message.cbuffer.c:同步 IO 与 DMA 缓冲策略
  7. 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 / 符号为准。

文章互动

阅读 --

留言

0 条留言

正在加载留言…