三種不同形式的Driver, 在這裡會說明有關Start() function的演算法. Driver的Start() function實作方式會影響到Supported() function的實作方式.
EFI_DRIVER_BINDING_PROTOCOL的所有Service需要共同合作才能確保所有資源的開啟與配置可以在Stop()中釋放掉.
第一種演算法是一個簡單的Device Driver, 它並不會建立任何額外的Handles. 它只會將一個或多個Protocol加到一個已經存在的Handle.
第二種是一個簡單的Bus Driver, 它會在第一次呼叫Start()的時候, 建立所有的Child Handle. 它不會為了Bus Controller附加任何額外的Protocol到Handle裡面.
第三種是一個比較進階的Bus Driver, 它可以在呼叫Start()時候只建立一個Child Handle. 也可以一次建立所有的Child Handle. 同樣地, 它不會為了Bus Controller附加任何額外的Protocol到Handle裡面.
Device Driver
1. 用OpenProtocol()去開啟所有需要的Protocol. 如果這個Driver允許開啟的Protocol可以和其他Driver共用. 那麼它就應該使用EFI_OPEN_PROTOCOL_BY_DRIVER參數去開啟. 如果Driver不允許開啟的Protocol和其他Driver共用的話, 那麼它就應該使用EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE的參數去開啟. 相同的參數可以用在Supported().
2. 如果在第一步時, 呼叫任何一個OpenProtocol()後, 發生錯誤的話, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將錯誤的狀態碼回傳回去.
3. 忽略傳入的參數RemainingDevicePath.
4. 初始化ControllerHandle指定的Device. 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將EFI_DEVICE_ERROR回傳回去.
5. 配置以及初始化所有這個Driver會需要用到的資料結構, 以便管理ControllerHandle指定的Device. 這包含了Public Protocol的空間以及任何額外Private Data Structure的空間, 這些資料都是與ControllerHandle有關連的. 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將EFI_OUT_OF_RESOURCES回傳回去.
6. 使用InstallProtocolInterface()去安裝所有新的Protocol介面到ControllerHandle. 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將InstallProtocolInterface()的錯誤回傳回去.
7. 完成之後回傳EFI_SUCCESS.
Bus Driver在第一次呼叫Start()時, 會建立所有的Child Handles.
1. 用OpenProtocol()去開啟所有需要的Protocol. 如果這個Driver允許開啟的Protocol可以和其他Driver共用. 那麼它就應該使用EFI_OPEN_PROTOCOL_BY_DRIVER參數去開啟. 如果Driver不允許開啟的Protocol和其他Driver共用的話, 那麼它就應該使用EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE的參數去開啟. 相同的參數可以用在Supported().
2. 如果在第一步時, 呼叫任何一個OpenProtocol()後, 發生錯誤的話, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將錯誤的狀態碼回傳回去.
3. 忽略傳入的參數RemainingDevicePath.
4. 初始化ControllerHandle指定的Device. 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將EFI_DEVICE_ERROR回傳回去.
5. 搜尋Bus Controller所指定ControllerHandle的所有Child Device.
6. 如果Bus需要它, 配置資源給Bus Controller所指定ControllerHandle的所有Child Device.
7. 針對每個ControllerHandle的Child C開始FOR迴圈
8. 配置以及初始化這個Driver需要管理Child Device的所有資料結構. 這包含了與Child C有關的Public Protocol的空間以及任何額外Private Data Structure的空間, 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且將EFI_OUT_OF_RESOURCES回傳回去.
9. 如果Bus Driver建立了Device Path給Child Device, 接著會根據附加在ControllerHandle的Device Path建立Device Path給Child C.
10. 初始化Child Device C. 如果有錯誤發生, 那麼就必須要透過CloseProtocol()關掉所有在第一步開啟的Protocol, 並且返回EFI_DEVICE_ERROR錯誤.
11. 建立一個Handle給C, 並安裝一個Protocol Interface給Child Device C. 這可能會包含EFI_DEVICE_PATH_PROTOCOL.
12. 呼叫OpenProtocol()並傳入EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER參數來代表Child C.
13. 結束迴圈.
14. 返回EFI_SUCCESS.
沒有留言:
張貼留言