3. 主要场景分析
3.1. ehc如何发现设备的插拔
3.2. 如何完成提交的urb
3.3. unlink urb
3.4. ehci如何支持fs/ls设备
1.1.ehc如何发现设备的插拔
ehci_hub_status_data()会返回port的”change status”信息,hub driver会通过ehci_hub_status_data()定时查询root hub信息,当有设备插拔时候,hub driver根据查询的结果,即可发现并处理设备的插拔。
1), usbcore module的 hcd_submit_urb()会将上层的传输请求---URB通过hcd->hc_driver->urb_enqueue()传给ehci driver的
ehci_urb_enqueue()(hc_driver->urb_enqueue)*
,该函数将urb转化成HC可识别的iTD/siTD/qTD等,然后根据urb->pipe的类型以及是否HS等信息链接到periodic schedule list或者asynchronous schedule list中, 并使能HC开始传输;
2), HC发现某个URB传输完成后(一般URB结尾对应的iTD/qTD会设置IOC),会中断CPU,并设置状态位STS_INT, 导致
echi_irq()
->
ehci_work()
处理, echi_work()会扫描periodic schedule list 以及 asynchronous schedule list,发现有完成的urb,会调用ehci_urb_done()通知usb core,并导致urb->complete()被调用, ehci_urb_done()是在
qh_completions()
或者
itd_complete()
(或者sitd_complete())中调用的;
3),URB传输过程中 HC发现传输错误(STS_ERR/STS_FATAL),也会中断CPU,调用ehci_irq()来处理;
1),哪些情况下会发生unlink urb?
.上层驱动(usbcore或者更上层驱动)调用usb_unlink_urb()取消已经提交的urb;
.已经提交的urb完成后,ehci driver会自动unlink 该urb.
2),不同类型的传输如何处理unlink urb
a), unlink control/bulk urb,调用
unlink_async()
处理,两阶段处理,先从链表中删除,再通知HC更新缓冲的地址,HC更新完成后会触发STS_IAA中断,通知CPU已经安全unlink了;
1.4.ehci如何支持fs/ls设备
1), fs/ls 设备插入到root hub port,会由companion HC(uhci/ohci)发现并管理设备;
2),fs/ls 设备插入到usb 2.0 hub(not root hub),那么ehci 通过split transaction支持fs/ls 设备;
Split Transactions
[1], Ehci specification revision 1.0
[2], USB2.0 specification
[3], Fedora core 5 kernel packet (linux-2.6.15-1.2054_FC5.src.rpm)