在usb2.0主机控制器系统上一般都配置了ehci与伴随主机控制器(如ohci)两种类型的USB主机控制器。ehci处理高速设备,而伴随控制器处理全速和低速设备。
在ehci和ohci都是硬件设备,在具有pci总线的系统中,ehci和ohci都是pci总线设备,并且在pci枚举阶段被枚举,而ehci和ohci对应的驱动也在系统初始化阶段被注册。
usb2.0主机控制器系统中通过端口与usb设备连接,每个主机控制器对每个端口都有对应的端口寄存器,用来控制和查询端口状态。但ehci和ohci并会同时都能够控制、查询usb端口,因为那样必定会乱套---两个主机控制器同时操作一个端口是难以协调的。因而,如果某个端口插入的high speed设备,就让ehci来控制和、读取端口状态以支持high speed usb设备正常工作,反之如果是full / low speed的usb设备,就交由ohci来管理。
usb2.0主机控制器系统中以ohci为默认的主机控制器,这样是为了兼容usb1.x旧的协议。然而,在ehci驱动注册初始化的时候,往往会对ehci的CF域写1以将ehci设置为默认的主机控制器。这就是说,一旦有设备插入后,ehci是默认知道这个情况的家伙。
但是插入的设备到底是不是该由这个默认的ehci来处理,还得看后续的port reset过程中对设备进行判断的结果而定。
整个port reset的简单过程如下(默认CF为1,ehci拥有端口控制权):
1.插入设备后ehci开始处理这次设备的attach事件,随后驱动程序便向设备发出一个port reset请求;
2.等待50ms,驱动程序通过GetPortStatus命令请求来查看端口状态;
3.在GetPortStatus的过程中向端口的PortReset写0以结束这次端口的reset过程;
4.判断reset是否结束。在3中虽然对PortReset域写0,但是并不能立刻就能真正清除PortReset,需要不断去读PortReset域的值,如果读出来的值为0说明port reset过程顺利结束;否则继续读取判断,直到超时错误退出;
5.在port reset结束后就要来判断PortEnable域的值,如果此时PortEnable的值为1且设备处于连接状态(防止在port reset过程中设备被坏蛋给拔出了)说明这个设备是一个high speed设备,ehci继续处理;否则如果设备处于连接状态,但port enable为0则说明连接的是一个全速设备,那么此时驱动程序就需要将PortOwner域设置为1以交出ehci控制权,ohci来接管。
什么PortOwner域呢?PortOwner域是专门用来控制单个端口控制归属的域。即当ehci为默认端口控制者时,PortOwner变为1则ehci就会交出端口控制权转由ohci来接管;反之如果伴随控制器ohci拥有端口控制权,那么,PortOwner变为0时端口控制权又交还给ehci。ohci将端口控制权交还给ehci的另外一种情况就是发送一个disconnect事件,这时端口控制权也会交还给ehci。
这种PortOwnerShip的游戏规则是由一个usb2.0主机控制器中集成的一个叫做端口路由逻辑的硬件来实现,简单来讲,ehci控制端口,无非就是通过对应的端口寄存器来控制端口,而端口的上发生的事件也是反应的端口寄存器中,ehci也是通过寄存器来处理这些事件。端口路由逻辑就根据PortOwner域来控制端口寄存器对端口连接可见来实现端口控制权的。说起来有点拗口,比如,PortOwner为1,端口路由逻辑就会作用在ehci的端口寄存器上,使得端口上发生的一切事情ehci端口寄存器都不会知道。
阅读(4967) | 评论(1) | 转发(0) |