1. 程式人生 > >UEFI中USB總線驅動的實現框架

UEFI中USB總線驅動的實現框架

安裝 spec desc 流程圖 訪問 fig span nec 有一個

本文簡單介紹一下UEFI中USB驅動的實現框架:

下圖是USBD向上層驅動提供的接口:

技術分享

1.從圖中我們可以看出,USBDI的實現主要通過調用HCDI實現 和 訪問USB_INTERFACE結構體(該結構體在總線枚舉過程中存放了device的相關信息):

(這裏為什麽是從interface獲取呢?一個device可以包含多個configuration,一個configuration可以包含多個interface,我們可以把device看成一個物理設備,而把interface看成邏輯設備,就是說interface是與driver對應的。比如說我們有一個usb設備,含有兩種邏輯功能,就表示它支持兩個interface,我們也就需要安裝兩個device驅動來分別驅動這兩個功能。所以如果上層的device驅動通過USBDI獲取相關的描述符,也就需要從對應的interface結構體中讀取就行了)

下圖是USBD中操作hub的相關接口實現:

技術分享

技術分享

1.這裏分為root hub和一般hub,root hub位於Host controller中,從上面的接口實現也可以看出來,root hub的相關操作都是直接通過調用HCDI實現的(即直接操作HC中的PORTSC寄存器);

下圖是USBD初始化的簡單流程圖:

技術分享

我們設想這樣一個鏈接結構:root hub下掛了一個hub,該hub下有掛了一個device,來分析一下初始化流程:

1.首先初始化root hub,去循環枚舉每個port,檢測到有hub存在,會去調用UsbEnumerateNewDev()(參考USB2.0 spec 9.1.2),同時註意UsbRootHubEnumeration是一個周期調用的函數,用來查詢root hub的各個端口的狀態;

2.UsbCreateInterface()會創建interface,並安裝USBDI:EFI_USB_IO_PROTOCOL,從這裏也可以看出為什麽USBDI會從interface獲取descriptor;

3.判斷port口上的device的類型,發現是hub,調用hub的初始化函數,來初始化hub;

4.hub會去註冊一個異步中斷傳輸(回調函數為UsbOnHubInterrupt())(參考前兩篇的文章,我們知道UsbOnHubInterrupt()會被周期調用,他又會導致UsbHubEnumeration()被周期調用);

5.hub發下他下面的port口上有一個device,調用UsbEnumerateNewDev(),最後調用gBS->ConnectController()去查找device的驅動並加載他。

USBD初始化完成後,會存在兩個被周期調用的函數(類似於Linux中的內核線程):

1.UsbRootHubEnumeration() - 用來查詢root hub上的端口的狀態;

2.UsbHubEnumeration() - 用來查詢hub上的端口的狀態(基於 異步中斷傳輸 實現)。

UEFI中USB總線驅動的實現框架