2. UDC驱动核心数据结构
在 USB Gadget 框架中,UDC(USB Device Controller)驱动层通过三个核心数据结构完成对底层硬件、设备控制器以及上层功能的抽象。理解 struct usb_gadget、struct usb_udc 和 struct usb_gadget_driver 的成员与作用,是进行 UDC 驱动移植和枚举流程分析的基础。
usb_udc 管理一个物理 UDC 控制器实例;该控制器实例通过 usb_gadget 暴露给 Gadget 功能层;usb_gadget_driver 则代表一个具体的 Gadget 功能(如 ECM、ACM、Mass Storage),三者通过注册与绑定机制协同工作。
2.1 struct usb_gadget:设备控制器抽象
struct usb_gadget 是 UDC 硬件控制器的软件抽象,它代表一个 USB 设备端控制器实例。该结构体包含了控制器的状态、能力、操作接口以及与系统其他部分的连接信息。
2.1.1 主要成员与作用
| 成员名 | 类型 | 作用描述 |
|---|---|---|
ops |
struct usb_gadget_ops * |
指向控制器操作函数集,包括 get_frame、wakeup、set_selfpowered、vbus_session、pullup 等硬件级操作。 |
ep0 |
struct usb_ep * |
指向端点 0(控制端点)的实例,用于枚举过程中的控制传输。 |
eps |
struct list_head |
链表头,挂载该控制器所有可用的端点(struct usb_ep),供 Gadget 功能驱动遍历和申请。 |
speed |
enum usb_device_speed |
记录当前协商的 USB 总线速度(USB_SPEED_HIGH/LOW/FULL/SUPER)。 |
max_speed |
enum usb_device_speed |
控制器硬件支持的最高速度能力。 |
state |
enum usb_device_state |
USB 设备状态机当前状态(如 USB_STATE_NOTATTACHED、USB_STATE_POWERED、USB_STATE_DEFAULT、USB_STATE_ADDRESS、USB_STATE_CONFIGURED)。 |
name |
const char * |
控制器名称,通常与设备树中匹配的 compatible 字符串或平台设备名一致。 |
dev |
struct device |
内嵌的通用设备结构体,用于设备模型管理、sysfs 属性导出等。 |
udc |
struct usb_udc * |
反向指针,指向管理该 gadget 的 UDC 核心层实例。 |
sg_supported |
unsigned |
标志位,指示控制器是否支持 scatter-gather DMA 传输。 |
is_otg |
unsigned |
标志位,指示控制器是否支持 OTG(On-The-Go)规范。 |
2.1.2 struct usb_gadget 与控制器操作集关系
下图展示了 struct usb_gadget 与 struct usb_gadget_ops 之间的引用关系,以及 ops 中关键回调函数的作用。
2.2 struct usb_udc:UDC 核心管理层
struct usb_udc 是 UDC 核心层(drivers/usb/gadget/udc/core.c)用于管理所有已注册 UDC 控制器的数据结构。它封装了 struct usb_gadget,并增加了与 Gadget 功能驱动绑定、sysfs 属性管理、电源管理等高层逻辑。
struct usb_gadget,然后调用 usb_add_gadget_udc() 将其注册到核心层。核心层会自动创建对应的 struct usb_udc 实例并加入全局链表。
2.2.1 主要成员与作用
| 成员名 | 类型 | 作用描述 |
|---|---|---|
gadget |
struct usb_gadget * |
指向该 UDC 实例所管理的底层 gadget 控制器。 |
driver |
struct usb_gadget_driver * |
指向当前绑定到该 UDC 的 Gadget 功能驱动。为 NULL 时表示未绑定。 |
dev |
struct device |
内嵌设备结构体,用于在 sysfs 中创建 /sys/bus/udc/devices/ 下的设备节点。 |
list |
struct list_head |
全局链表节点,用于将本 UDC 实例加入 udc_list 全局链表。 |
vbus |
bool |
VBUS 状态标志,表示 USB 总线是否提供电源。 |
connected |
bool |
连接状态标志,表示设备是否已连接到主机。 |
allow_connect |
bool |
控制是否允许物理连接。用于软件可控的 D+ 上拉电阻管理。 |
2.2.2 UDC 注册与全局管理流程
下图展示了 UDC 驱动从 probe 到注册完成,以及 Gadget 功能驱动绑定过程中,struct usb_udc 所扮演的核心角色。
2.3 struct usb_gadget_driver:Gadget 功能驱动抽象
struct usb_gadget_driver 代表一个具体的 USB Gadget 功能实现,例如 ECM(以太网控制模型)、ACM(抽象控制模型)、Mass Storage、HID 等。它定义了功能驱动的生命周期回调、描述符管理以及事件处理接口。
2.3.1 主要成员与作用
| 成员名 | 类型 | 作用描述 |
|---|---|---|
function |
char * |
功能名称字符串,如 "g_ether"、"g_serial"、"g_mass_storage"。 |
max_speed |
enum usb_device_speed |
该功能驱动支持的最高 USB 速度。 |
setup |
int (*)(struct usb_gadget *, const struct usb_ctrlrequest *) |
处理主机发来的标准/类/厂商请求。这是枚举过程中最核心的回调,负责解析 Setup 包并返回响应。 |
disconnect |
void (*)(struct usb_gadget *) |
当主机断开连接或 VBUS 掉电时调用,用于清理资源。 |
bind |
int (*)(struct usb_gadget *, struct usb_gadget_driver *) |
绑定回调,在功能驱动与 UDC 绑定时调用。功能驱动在此函数中分配端点、注册回调、初始化功能状态。 |
unbind |
void (*)(struct usb_gadget *, struct usb_gadget_driver *) |
解绑回调,在功能驱动与 UDC 解绑时调用,用于释放资源。 |
suspend |
void (*)(struct usb_gadget *) |
挂起回调,当总线进入挂起状态时调用。 |
resume |
void (*)(struct usb_gadget *) |
恢复回调,当总线从挂起状态恢复时调用。 |
reset |
void (*)(struct usb_gadget *) |
复位回调,当主机发出总线复位信号时调用。 |
driver |
struct device_driver |
内嵌的通用设备驱动结构体,用于驱动模型注册和 sysfs 属性管理。 |
2.3.2 Gadget 功能驱动注册与绑定代码示例
以下代码展示了典型的 Gadget 功能驱动注册过程,重点突出 struct usb_gadget_driver 各回调的赋值与注册函数调用。
/* 定义 Gadget 功能驱动实例 */
static struct usb_gadget_driver my_gadget_driver = {
.function = "g_my_function",
.max_speed = USB_SPEED_HIGH,
.bind = my_gadget_bind,
.unbind = my_gadget_unbind,
.setup = my_gadget_setup,
.disconnect = my_gadget_disconnect,
.suspend = my_gadget_suspend,
.resume = my_gadget_resume,
.reset = my_gadget_reset,
.driver = {
.name = "g_my_function",
.owner = THIS_MODULE,
},
};
/* 模块初始化函数 */
static int __init my_gadget_init(void)
{
int ret;
/* 注册 Gadget 功能驱动到 UDC 核心层 */
ret = usb_gadget_register_driver(&my_gadget_driver);
if (ret)
pr_err("Failed to register gadget driver: %d\n", ret);
return ret;
}
module_init(my_gadget_init);
/* 模块退出函数 */
static void __exit my_gadget_exit(void)
{
usb_gadget_unregister_driver(&my_gadget_driver);
}
module_exit(my_gadget_exit);
2.4 三大核心数据结构关系总结
下表从层次、职责、生命周期三个维度对比 struct usb_gadget、struct usb_udc 和 struct usb_gadget_driver 的差异与联系。
| 对比维度 | struct usb_gadget | struct usb_udc | struct usb_gadget_driver |
|---|---|---|---|
| 所属层次 | UDC 硬件抽象层 | UDC 核心管理层 | Gadget 功能驱动层 |
| 主要职责 | 封装硬件控制器状态与操作 | 管理 UDC 注册、绑定、sysfs | 实现具体 USB 功能逻辑 |
| 生命周期 | 由 UDC 驱动 probe/release 管理 | 由 usb_add/remove_gadget_udc 管理 | 由 usb_gadget_register/unregister_driver 管理 |
| 与硬件关系 | 直接对应一个物理控制器 | 间接管理,通过 gadget 指针 | 与硬件无关,纯软件功能 |
| 关键关联 | udc 指针指向 usb_udc | gadget 指针指向 usb_gadget | 通过 udc_bind_to_driver 绑定到 usb_udc |
2.5 枚举过程中的数据结构协作
在 USB 设备枚举过程中,三个核心数据结构协同工作,完成从主机复位到配置完成的完整流程。下图展示了枚举关键阶段的数据流与回调关系。