1. EHCI 概述:EHCI 控制器在 USB 2.0 体系中的角色、与 UHCI/OHCI 的异同、EHCI 驱动栈架构概览
1.1 EHCI 在 USB 2.0 体系中的核心角色
EHCI(Enhanced Host Controller Interface)是 USB 2.0 高速模式(480 Mbps)的官方主机控制器标准。在 USB 2.0 体系中,EHCI 承担以下关键职责:
- 高速传输引擎:EHCI 仅处理高速(High-Speed, 480 Mbps)事务,不直接处理全速(Full-Speed, 12 Mbps)或低速(Low-Speed, 1.5 Mbps)事务。
- 事务翻译桥接:通过配套的 Transaction Translator(TT)机制,EHCI 能够与全速/低速设备通信。TT 可以集成在 EHCI 内部(如 Intel 方案)或位于 USB 2.0 Hub 中。
- 系统内存与 USB 总线之间的 DMA 引擎:EHCI 通过周期性的 Schedule(帧列表/异步列表)直接从系统内存中读取传输描述符(qTD)和缓冲区,实现零拷贝数据传输。
关键概念: EHCI 不直接操作全速/低速设备。当系统检测到全速或低速设备时,EHCI 驱动会通过端口路由逻辑将设备“移交”给 Companion Controller(UHCI/OHCI)处理,或通过内置 TT 进行速度转换。
1.2 EHCI 与 UHCI/OHCI 的异同
USB 1.x 时代存在两种主机控制器标准:Intel 主导的 UHCI(Universal Host Controller Interface)和 Compaq/Microsoft/NEC 主导的 OHCI(Open Host Controller Interface)。EHCI 作为 USB 2.0 标准,与二者有显著差异:
| 对比维度 | UHCI | OHCI | EHCI |
|---|---|---|---|
| 支持速度 | 全速 (12 Mbps) + 低速 (1.5 Mbps) | 全速 (12 Mbps) + 低速 (1.5 Mbps) | 高速 (480 Mbps) + 通过 TT 支持全速/低速 |
| 硬件复杂度 | 低(依赖软件做更多工作) | 高(硬件管理更多细节) | 中(硬件管理调度,软件管理描述符) |
| 调度方式 | 软件维护帧列表(Frame List) | 硬件维护端点描述符(ED)链表 | 硬件维护异步列表 + 周期列表 |
| 传输描述符 | TD(Transfer Descriptor) | TD(Transfer Descriptor) | qTD(Queue Element Transfer Descriptor) |
| 寄存器数量 | 约 20 个 | 约 30 个 | 约 40 个(含扩展能力寄存器) |
| 中断处理 | 每帧中断 | 可配置中断频率 | 可配置中断频率 + 中断阈值控制 |
| 典型应用 | Intel 芯片组 | 非 Intel 芯片组(如 NEC、TI) | 所有 USB 2.0 主机控制器 |
工程实践提示: 在 Linux 内核中,UHCI 和 OHCI 驱动位于
drivers/usb/host/ 目录下,分别对应 uhci-hcd 和 ohci-hcd。EHCI 驱动为 ehci-hcd。三者通过 struct usb_hcd 抽象层统一管理,但寄存器操作和调度逻辑完全不同。
1.3 EHCI 驱动栈架构概览
EHCI 驱动栈在 Linux 内核中采用分层设计,从上到下依次为:
- USB 核心层(USB Core):提供设备枚举、配置、urb 管理、驱动匹配等通用服务。
- HCD 抽象层(Host Controller Driver):通过
struct usb_hcd和struct hc_driver接口,屏蔽不同主机控制器的差异。 - EHCI 驱动层(ehci-hcd):实现 EHCI 特有的寄存器操作、调度管理、中断处理、端口控制。
- 硬件寄存器层:直接操作 EHCI 控制器 MMIO 寄存器空间。
1.4 EHCI 驱动中的关键数据结构
在 Linux 内核 EHCI 驱动中,以下数据结构构成了驱动栈的核心:
| 数据结构 | 定义位置 | 作用 |
|---|---|---|
struct ehci_hcd |
drivers/usb/host/ehci.h |
EHCI 主机控制器实例,包含寄存器基址、调度队列、中断状态等 |
struct ehci_qh |
drivers/usb/host/ehci.h |
队列头(Queue Head),对应一个端点,包含 qTD 链表 |
struct ehci_qtd |
drivers/usb/host/ehci.h |
队列传输描述符(Queue Element Transfer Descriptor),描述一次传输 |
struct ehci_periodic |
drivers/usb/host/ehci.h |
周期调度(中断/等时传输)的帧列表管理 |
struct ehci_tt |
drivers/usb/host/ehci.h |
Transaction Translator 管理,用于全速/低速设备支持 |
常见陷阱: EHCI 的 qTD 必须 32 字节对齐,且 qTD 链表必须物理连续。在嵌入式系统中,如果使用 DMA 不连续的缓冲区,会导致 qTD 获取失败(
EHCI: qTD alloc failed)。驱动开发时务必使用 dma_alloc_coherent() 分配描述符内存。
1.5 Companion Controller 协同工作模式
在典型的 x86 芯片组中,EHCI 通常与 UHCI 或 OHCI 配对工作,形成 Companion Controller 架构:
- 端口共享:物理 USB 端口同时连接到 EHCI 和 Companion Controller。
- 速度检测:设备插入时,EHCI 检测端口状态寄存器(PORTSC)中的线状态(Line Status)位,判断设备速度。
- 端口路由:如果设备为全速或低速,EHCI 驱动通过
PORTSC.PortOwner位将端口所有权移交给 Companion Controller。 - 透明切换:对 USB 核心层和上层驱动而言,端口切换是透明的,所有操作通过 HCD 抽象层完成。
1.6 本章小结
- EHCI 是 USB 2.0 高速主机控制器标准,仅处理高速事务,通过 TT 或 Companion Controller 支持全速/低速设备。
- 与 UHCI/OHCI 相比,EHCI 在调度方式、描述符结构、寄存器数量和中断处理上存在本质差异。
- Linux EHCI 驱动栈采用分层架构:USB Core → HCD 抽象层 → EHCI 驱动层 → 硬件寄存器层。
- Companion Controller 架构通过端口所有权切换实现多速度兼容,是驱动开发中必须理解的关键机制。