EHCI协议中规定有几种数据模型:
Periodic Frame List
Asynchronous List Queue Head Pointer
Isochronous (High-Speed) Transfer Descriptor (iTD)
Split Transaction Isochronous Transfer Descriptor (siTD)
Queue Element Transfer Descriptor (qTD)
Queue Head
Periodic Frame Span Traversal Node (FSTN)
以上数据模型(或称数据结构)就是EHCI的关键,具体的定义可以查找EHCI 的spec (Enhanced Host Controller Interface Specification for Universal Serial Bus)。EHCI控制器驱动实出上就是对这几种据结构的管理与操作。
EHCI控制器以协议的形式将这些数据模型规范下来,方案驱动设计者设计出通用的驱动,也方便非驱动设计者重用己有的驱动代码。要做到这一点,EHCI对硬件部份也需要作出一些必要的规定,这就是硬件对软件的接口--寄存器。
<>中对寄存器的序列及功能作了详细的定义,主要有以下三部份:
PCI Configuration Registers (USB)
Host Controller Capability Registers
Host Controller Operational Registers
PCI Configuration Registers的定义我们不必太关心,arm中一般不会有这一部份,我们需要详细了解的是Host Controller Capability Registers 和Host Controller Operational Registers这两大板块,
Enhanced Host Controller Capability Registers
Offset | Size | Mnemonic | Power Well | Register Name | |
00h | 1 | CAPLENGTH | Capability Register Length | ||
01h | 1 | Reserved | N/A | ||
02h | 2 | HCIVERSION | Interface Version Number | ||
04h | 4 | HCSPARAMS | Structural Parameters | ||
08h | 4 | HCCPARAMS | Capability Parameters | ||
0Ch | 8 | HCSP-PORTROUTE | Companion Port Route Description |
Host Controller Operational Registers
Offset | Mnemonic | Register Name | Power Well | ||
00h | USBCMD | USB Command | |||
04h | USBSTS | USB Status | |||
08h | USBINTR | USB Interrupt Enable | |||
0ch | FRINDEX | USB Frame Index | |||
10h | CTRLDSSEGMENT | 4G Segment Selector | |||
14h | PERIODICLISTBASE | Frame List Base Address | |||
18h | ASYNCLISTADDR | Next Asynchronous List Address | |||
1C-3F | Reserved | ||||
40H | CONFIGFLAG | Configured Flag Register | |||
44H | PORTSC(1-N_PORTS) | Port Status/Control |
在一些主芯片的spec中,USB主控制器的部份就介绍得很简单,大多数只是像我这样简单的说一下USB主控制器的标准,再列一下寄存器的序列,然后让读者去查找<这样的文档。
上表中标成红色的寄存器是我们需要主要关注的,echi主控制器会以此为入口,对各种数据模型进行调度。
主控制器的调度主要分为两大数,一类可以称为时间片的调度,多数控制器会以此种调度为主,另一种则是异步(Asynchronous)调度。
USB协议中把USB的传输类型分为控制传输,批量传输,中断传输,等时传输。这几种传输类型的定义其实是逻辑上的。我们知道,USB的物理数据通道就一条(D+/D-),要怎样才能达到USB协议中这几种传输类型的要求呢,这就要看主控制器是如何调度的了。
在EHCI中,把等时传输和中断传输都用进间片调度来控制。请看下图:
所谓的分时调度,就是把每秒的时间分为若干片(一般是1024/256等),每一个时间片(Frame)处理一组(一般是ISO数据)数据。
CPU会把ISO数据和INT数据建立一张表放在内核中,而ECHI的寄存器FRINDEX则会跟踪这个表,每一个时间片加-,FRINDEX所指之处,控制器就会把这处指针所指向的数据结构中的数据送到总线上去。整个过程看起来有点像是CPU的调度。
有了时间片的调度,其实控制器就可以完成所有的功能,但为了方便用户的使用,控制器还提拱了另一种调度来处理实时性要求不是很强的数据。
这种调试一般叫做异步调度,也就是AsyncListAddr发威的时候了,CPU把块传输和控制传输的数据按协议要求的数据结构在内存中安排好并建立一个链表,AsyncListAddr则会跟踪这个链表,控制器则把AsyncListAddr所指向的数据搬运到USB总线上去。
异步调度比ISO调度要简单得多了。至于异步调试和同步调度之间如何协调,EHCI控制器会处理这个问题,再也不用软件来操心了。
有了以上的简章介绍,我们知道EHCI的规范中对寄存器,数据结构和控制方式都有了详细的规定,linux是怎样执行这个规定的呢。
注:转载请注明出处 datangsoc@hotmail.com