3. USB主机控制器类型

USB 主机控制器(Host Controller)是 USB 系统中负责管理总线事务、处理数据传输、执行协议调度的硬件单元。自 USB 1.0 到 USB 3.2/4.0,共诞生了四种主机控制器接口标准:OHCI、UHCI、EHCI 和 xHCI。理解它们的差异与 Linux 驱动栈,是调试 USB 时钟、电源、枚举失败问题的前提。

调试提示:在嵌入式 Linux 中,设备树中 compatible 属性直接决定了内核绑定哪个主机控制器驱动。选错驱动会导致时钟配置错误、DMA 无法工作甚至系统挂死。

3.1 四种主机控制器标准概览

下表从速度支持、硬件复杂度、寄存器接口、调度方式四个维度对比四种标准:

特性 OHCI UHCI EHCI xHCI
全称 Open HCI Universal HCI Enhanced HCI eXtensible HCI
USB 版本 USB 1.1 USB 1.1 USB 2.0 USB 3.x / 4.0
速度 低速/全速 (1.5/12 Mbps) 低速/全速 (1.5/12 Mbps) 高速 (480 Mbps) 超高速 (5/10/20 Gbps)
硬件复杂度 高(硬件做调度) 低(软件做调度) 中 高(支持多协议)
寄存器接口 MMIO,大端 PIO/MMIO,小端 MMIO,小端 MMIO,小端
调度方式 硬件自动调度 软件驱动调度 硬件异步列表 硬件事件环 + 命令环
Linux 驱动 ohci-hcd uhci-hcd ehci-hcd xhci-hcd
关键结论:OHCI 和 UHCI 都只支持 USB 1.1,但 OHCI 将调度逻辑固化在硬件中,UHCI 则依赖软件驱动完成帧列表管理。在嵌入式场景中,OHCI 更常见于 ARM SoC,UHCI 多见于 x86 南桥。

3.2 主机控制器架构演进与 Linux 驱动栈

Linux USB 子系统采用分层架构。主机控制器驱动(HCD)位于最底层,直接操作硬件寄存器;上层通过 usbcore 提供设备枚举、配置、传输抽象。下图展示了四种 HCD 在 Linux 内核中的位置关系:

Linux USB 主机控制器驱动栈架构 Linux USB 主机控制器驱动栈架构 用户空间 (libusb / sysfs / udev) USB 核心层 (usbcore) — 设备枚举、配置、urb 管理 ohci-hcd USB 1.1 (低速/全速) uhci-hcd USB 1.1 (软件调度) ehci-hcd USB 2.0 (高速) xhci-hcd USB 3.x / 4.0 硬件层 (SoC / PCIe / ACPI 设备树) 说明: • 嵌入式 SoC 通常集成 OHCI + EHCI 组合控制器,或单一 xHCI 控制器。 • xHCI 向后兼容 USB 2.0/1.1,可替代 OHCI/UHCI/EHCI 三合一。

3.3 各标准详细对比与 Linux 驱动实现

3.3.1 OHCI (Open Host Controller Interface)

  • 提出者:Compaq、Microsoft、National Semiconductor
  • 特点:硬件负责帧列表调度,驱动只需配置端点描述符和传输描述符(TD)。
  • 寄存器:HcRevision、HcControl、HcCommandStatus、HcInterruptStatus 等。
  • Linux 驱动:drivers/usb/host/ohci-hcd.c,依赖 ohci-platform 或 ohci-pci。
  • 设备树绑定:
usb@1c14000 {
    compatible = "allwinner,sun4i-a10-ohci", "generic-ohci";
    reg = <0x01c14000 0x400>;
    interrupts = <0 39 4>;
    clocks = <&ccu CLK_USB_OHCI>;
    resets = <&ccu RST_USB_OHCI>;
    phys = <&usbphy 1>;
    phy-names = "usb";
    status = "okay";
};

3.3.2 UHCI (Universal Host Controller Interface)

  • 提出者:Intel
  • 特点:软件驱动管理帧列表(Frame List),硬件只做最底层的总线信号收发。CPU 占用率高于 OHCI。
  • 寄存器:USBCMD、USBSTS、USBINTR、FRNUM、FLBASEADD 等。
  • Linux 驱动:drivers/usb/host/uhci-hcd.c,通常绑定 PCI 设备。
  • 典型场景:x86 南桥(ICH/PCH)中的 USB 1.1 控制器。
调试注意:UHCI 驱动依赖软件定时器轮询帧列表,如果内核 HZ 配置过低或 CPU 进入深度 idle,可能导致 USB 1.1 设备传输超时。在嵌入式 x86 平台中,建议检查 /proc/interrupts 中 UHCI 中断频率。

3.3.3 EHCI (Enhanced Host Controller Interface)

  • 提出者:Intel(USB 2.0 规范)
  • 特点:支持高速(480 Mbps),引入异步列表(Async List)和周期性列表(Periodic List)并行调度。
  • 寄存器:USBCMD、USBSTS、USBINTR、PERIODICLISTBASE、ASYNCLISTADDR 等。
  • Linux 驱动:drivers/usb/host/ehci-hcd.c,支持 ehci-platform 和 ehci-pci。
  • 兼容性:EHCI 通常与 OHCI 或 UHCI 配合,通过 Companion Controller 模式支持低速/全速设备。

3.3.4 xHCI (eXtensible Host Controller Interface)

  • 提出者:Intel(USB 3.0 规范)
  • 特点:统一支持 USB 3.x/2.0/1.1,引入事件环(Event Ring)和命令环(Command Ring)机制,支持流式传输(Streams)。
  • 寄存器:CAPLENGTH、HCSPARAMS1、HCCPARAMS1、DCBAAP、CRCR、ERSTBA 等。
  • Linux 驱动:drivers/usb/host/xhci.c + xhci-plat.c / xhci-pci.c。
  • 设备树绑定:
usb@31100000 {
    compatible = "snps,dwc3";
    reg = <0x31100000 0x10000>;
    interrupts = <0 40 4>;
    dr_mode = "host";
    clocks = <&clk USB3_CLK>, <&clk USB3_REF_CLK>;
    clock-names = "bus_early", "ref";
    phys = <&usb3_phy>;
    phy-names = "usb3-phy";
    maximum-speed = "super-speed";
    snps,dis_u2_susphy_quirk;
    snps,dis_enblslpm_quirk;
    status = "okay";
};

3.4 四种标准在 Linux 内核中的共存与选择

在 Linux 内核编译时,可以通过 make menuconfig 选择需要的主机控制器驱动:

Device Drivers  --->
  [*] USB support  --->
    <*>   Support for Host-side USB
    <*>     OHCI HCD (USB 1.1) support
    <*>     UHCI HCD (most Intel/VIA) support
    <*>     EHCI HCD (USB 2.0) support
    <*>     xHCI HCD (USB 3.0) support
    [*]       xHCI platform driver support
嵌入式选型建议:
  • 仅需 USB 2.0 高速:选择 EHCI + OHCI(兼容低速/全速)。
  • 需要 USB 3.0 超高速:选择 xHCI,可同时覆盖 USB 2.0/1.1。
  • x86 平台:通常 UHCI + EHCI + xHCI 全选,由 ACPI 表决定绑定。
  • ARM SoC:优先使用 OHCI + EHCI 组合或 xHCI(DWC3 控制器)。

3.5 主机控制器时钟与电源管理差异

四种标准对时钟和电源管理的需求不同,直接影响设备树中的 clocks 和 resets 配置:

标准 时钟需求 典型时钟频率 电源管理特性
OHCI 1 个主时钟 + 1 个 PHY 时钟 48 MHz (12 MHz 倍频) 支持挂起/恢复,无 DMA 时钟门控
UHCI 1 个 PCI 时钟 + 48 MHz 参考时钟 48 MHz 依赖 PCI PM,支持 D0/D3 状态
EHCI 1 个主时钟 + 1 个 PHY 时钟 + 可选 PLL 48 MHz / 60 MHz 支持异步列表暂停、端口电源控制
xHCI 总线时钟 + 参考时钟 + PHY 时钟 + 可选 PLL 125 MHz / 100 MHz / 24 MHz 支持 U0-U3 电源状态、LPM、PCIe D3cold

下面以 xHCI 为例,展示时钟拓扑关系:

xHCI 时钟拓扑与电源域 xHCI 时钟拓扑与电源域 PLL / 晶振 时钟分频器 bus_early 时钟 ref 参考时钟 PHY 时钟 xHCI 控制器 • bus_early:控制器核心逻辑时钟,必须最先使能。 • ref:用于 USB 帧周期(125 µs)和链路训练,频率通常为 24/48/100 MHz。

3.6 调试要点总结

  • 查看当前使用的 HCD:lsusb -t 显示驱动名称;cat /sys/kernel/debug/usb/devices 查看驱动绑定。
  • 检查时钟是否使能:cat /sys/kernel/debug/clk/clk_summary | grep usb 确认时钟树状态。
  • 常见错误:设备树中 compatible 写错导致绑定 ehci-platform 而非 ohci-platform,造成寄存器访问异常。
  • 性能瓶颈:UHCI 在 CPU 负载高时帧列表更新延迟增加,建议使用 ohci 或 xhci 替代。
实战建议:在新平台 bring-up 阶段,先在设备树中只使能 ehci 和 ohci,排除 xHCI 复杂电源状态的影响。待 USB 2.0 枚举稳定后,再开启 xHCI 支持 USB 3.0 设备。