EHCI driver
27-Dec-2002
1. Introduction
EHCI 驱动程序用于使用支持 USB 2.0 的主机控制器硬件与高速 USB 2.0 设备通信。 USB 2.0 标准与 USB 1.1 标准兼容。 它定义了三种传输速度:
- “High Speed” 480 Mbit/sec (60 MByte/sec);
- “Full Speed” 12 Mbit/sec (1.5 MByte/sec);
- “Low Speed” 1.5 Mbit/sec。
USB 1.1 仅解决全速和低速问题。 高速设备可以在 USB 1.1 系统上使用,但它们会降低 USB 1.1 的速度。
USB 1.1 设备也可用于 USB 2.0 系统。 当插入 EHCI 控制器时,它们会被提供给 USB 1.1“配套”控制器,该控制器是通常与此类设备一起使用的 OHCI 或 UHCI 控制器。 当 USB 1.1 设备插入 USB 2.0 集线器时,它们通过集线器中的“事务转换器”(TT) 与 EHCI 控制器交互,该转换器将低速或全速事务转换为高速“分割事务”,从而不会浪费传输带宽 。
在撰写本文时,该驱动程序已被证明可与以下公司(按字母顺序排列)的 EHCI 实现配合使用:Intel、NEC、Philips 和 VIA。 其他供应商正在提供其他 EHCI 实施; 您应该期望该驱动程序也能与他们一起工作。
虽然 USB 存储设备自 2001 年中期以来就已经可用(在该驱动程序的 2.4 版本上工作得相当快),但集线器自 2001 年末才可用,而其他类型的高速设备似乎处于搁置状态,直到更多系统出现 内置 USB 2.0。 此类新系统自 2002 年初就已推出,并在 2002 年下半年变得更加普遍。
请注意,USB 2.0 支持不仅仅涉及 EHCI。 它需要对 Linux-USB 核心 API 进行其他更改,包括集线器驱动程序,但这些更改并不需要真正更改暴露给 USB 设备驱动程序的基本“usbcore”API。
David Brownell dbrownell@users.sourceforge.net
2. Functionality
该驱动程序定期在 x86 硬件上进行测试,并且也已在 PPC 硬件上使用,因此大/小字节序问题应该消失。 人们相信它能够发挥所有正确的 PCI 魔力,因此即使在存在有趣的 DMA 映射问题的系统上,I/O 也能正常工作。
3. Transfer Types
在撰写本文时,驱动程序应该能够轻松处理所有控制、批量和中断传输,包括通过 USB 2.0 集线器中的事务转换器 (TT) 向 USB 1.1 设备发出的请求。 但您可能会发现错误。
高速同步 (ISO) 传输支持也可用,但在撰写本文时,还没有 Linux 驱动程序使用该支持。
通过事务转换器的全速同步传输支持尚不可用。 请注意,ISO 传输的拆分事务支持不能与高速 ISO 传输的代码共享太多代码,因为 EHCI 使用不同的数据结构来表示这些代码。 所以目前来说,大多数USB音频和视频设备都无法连接到高速总线上。
4. Driver Behavior
所有类型的传输都可以排队。 这意味着来自一个接口上的驱动程序(或通过 usbfs)的控制传输不会干扰来自另一个驱动程序的控制传输,并且中断传输可以使用一帧的周期,而不会因中断处理成本而存在数据丢失的风险。
EHCI 根集线器代码将 USB 1.1 设备移交给其配套控制器。 该驱动程序不需要了解这些驱动程序的任何信息; 已经可以工作的 OHCI 或 UHCI 驱动程序不需要仅仅因为 EHCI 驱动程序也存在而进行更改。
电源管理存在一些问题; 暂停/恢复目前表现不太正确。
此外,在调度周期性事务(中断和同步传输)时采取了一些捷径。 这些对可调度的周期性事务的数量设置了一些限制,并防止使用小于一帧的轮询间隔。
5. Use by
假设您有一个 EHCI 控制器(在 PCI 卡或主板上)并且已将此驱动程序编译为模块,请按以下方式加载:
# modprobe ehci-hcd
and remove it by:
# rmmod ehci-hcd
您还应该有一个“配套控制器”的驱动程序,例如“ohci-hcd”或“uhci-hcd”。 如果 EHCI 驱动程序出现任何问题,请删除其模块,然后该配套控制器的驱动程序将接管(以较低速度)之前由 EHCI 驱动程序处理的所有设备。
模块参数(传递给“modprobe”)包括:
log2_irq_thresh (default 0):
默认中断延迟的 Log2(以微帧为单位)。 默认值为 0,表示 1 微帧 (125 usec)。 最大值为 6,表示 2^6 = 64 个微帧。 这控制 EHCI 控制器发出中断的频率。
如果您在 2.5 内核上使用此驱动程序,并且已启用 USB 调试支持,则您将在任何 EHCI 控制器的“sysfs”目录中看到三个文件:
"async"
转储异步计划,用于控制和批量传输。 显示每个活动的 qh 和待处理的 qtd,通常每个 urb 一个 qtd。 (查看 USB 存储执行磁盘 I/O 的情况;观察请求队列!)
"periodic"
转储周期性调度,用于中断和同步传输。 不显示 qtd。
"registers"
显示控制器寄存器状态,以及
这些文件的内容可以帮助识别驱动程序问题。
设备驱动程序不应该关心它们是否在 EHCI 上运行,但它们可能需要检查“usb_device->speed == USB_SPEED_HIGH”。 高速设备可以完成全速(或低速)设备无法完成的任务,例如“高带宽”周期性(中断或ISO)传输。 此外,设备描述符中的某些值(例如定期传输的轮询间隔)在高速运行时使用不同的编码。
但是,请务必通过 USB 2.0 集线器测试设备驱动程序。 当使用事务转换器时,这些集线器报告一些故障(例如断开连接)的情况有所不同; 一些驾驶员在看到与 OHCI 或 UHCI 报告不同的故障时表现不佳。
6. Performance
USB 2.0 吞吐量由两个主要因素决定:主机控制器处理请求的速度以及设备响应请求的速度。 所有设备都遵循 480 Mbit/sec“原始传输速率”,但总吞吐量也会受到各个高速数据包之间的延迟、驱动程序智能以及整体系统负载等问题的影响。 延迟也是一个性能问题。
批量传输最常用于吞吐量存在问题的情况。 请记住,批量传输始终采用 512 字节数据包,并且一个 USB 2.0 微帧中最多可容纳 13 个数据包。 8 个 USB 2.0 微框架可装入一个 USB 1.1 框架中; 微帧为 1 毫秒/8 = 125 微秒。
因此,当硬件和设备驱动程序软件都允许时,批量传输可使用超过 50 MB/秒的速度。 周期性传输模式(同步和中断)允许更大的数据包大小,从而使您接近所引用的 480 MBit/秒传输速率。
6.1 Hardware Performance
在撰写本文时,单个 USB 2.0 设备的最大传输速率往往约为 20 MB/秒。 这当然可能会发生变化; 现在有些设备运行得更快,而另一些设备则运行得更慢。
EHCI 的第一个 NEC 实施似乎在总传输速率约为 28 MB/秒时存在硬件瓶颈。 虽然这对于 20 MB/秒的单个设备来说显然足够了,但将三个这样的设备放在一条总线上并不能获得 60 MB/秒的速度。 问题似乎是控制器硬件不会执行并发 USB 和 PCI 访问,因此每个微帧仅尝试 6 个(或可能 7 个)USB 事务,而不是 13 个。 (对于一款比其他产品早上市一年多的产品来说,这似乎是一个合理的权衡!)
预计较新的实现将改善这一点,投入更多的硅空间来解决该问题,以便新的主板芯片组将更接近 60 MB/秒的目标。 其中包括 NEC 的更新实施以及其他供应商的芯片。
主机从 EHCI 控制器接收指示请求完成的中断的最小延迟为 1 个微帧 (125 usc)。 该延迟是可调的; 有一个模块选项。 默认情况下,ehci-hcd 驱动程序使用最小延迟,这意味着如果您发出控制或批量请求,您通常可以预期它会在不到 250 usec 的时间内完成(取决于传输大小)。
6.2 Software Performance
为了获得 20 MB/秒的传输速率,Linux-USB 设备驱动程序需要保持 EHCI 队列已满。 这意味着发出大型请求,或者如果需要发出一系列小请求,则使用批量队列。 当驾驶员不这样做时,他们的表现结果就会显示出来。
在典型情况下,写出 4 KB 块的 usb_bulk_msg() 循环将浪费一半以上的 USB 2.0 带宽。 I/O 完成和驱动程序发出下一个请求之间的延迟将比 I/O 花费更长的时间。 如果同一个循环使用 16 KB 块,那就更好了; 128 KB 块的序列会减少很多浪费。
但是,与其依赖如此大的 I/O 缓冲区来提高同步 I/O 的效率,不如将多个(批量)请求排队到 HC,然后等待它们全部完成(或因错误而被取消)。 此类 URB 队列也应适用于所有 USB 1.1 HC 驱动程序。
在 Linux 2.5 内核中,定义了新的 usb_sg_*() api 调用; 他们将分散列表中的所有缓冲区排队。 它们还使用分散列表 DMA 映射(可能会应用 IOMMU)和 IRQ 减少,所有这些都将有助于使高速传输尽可能快地运行。
TBD:
中断和 ISO 传输性能问题。 这些定期传输是完全调度的,因此主要问题可能是如何触发“高带宽”模式。
TBD:
通过 sysfs uframe_periodic_max 参数可以实现超过标准 80% 的周期性带宽分配。 描述一下。