DriverSupport.c revision ec90508b3d3ff22a698a0446cb09d551d7466045
123c98c9417908188207408afa3f6901b8aca826aqhuang/** @file 2504214c4870e9183418014634268ce630eb5332algao Support functions to connect/disconnect UEFI Driver model Protocol 3504214c4870e9183418014634268ce630eb5332algao 423c98c9417908188207408afa3f6901b8aca826aqhuangCopyright (c) 2006 - 2008, Intel Corporation. <BR> 523c98c9417908188207408afa3f6901b8aca826aqhuangAll rights reserved. This program and the accompanying materials 623c98c9417908188207408afa3f6901b8aca826aqhuangare licensed and made available under the terms and conditions of the BSD License 723c98c9417908188207408afa3f6901b8aca826aqhuangwhich accompanies this distribution. The full text of the license may be found at 823c98c9417908188207408afa3f6901b8aca826aqhuanghttp://opensource.org/licenses/bsd-license.php 923c98c9417908188207408afa3f6901b8aca826aqhuang 1023c98c9417908188207408afa3f6901b8aca826aqhuangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1123c98c9417908188207408afa3f6901b8aca826aqhuangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1228a00297189c323096aae8e2975de94e8549613cyshang 13504214c4870e9183418014634268ce630eb5332algao**/ 1428a00297189c323096aae8e2975de94e8549613cyshang 159c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang#include "DxeMain.h" 16ec90508b3d3ff22a698a0446cb09d551d7466045eric_tian#include "Handle.h" 1728a00297189c323096aae8e2975de94e8549613cyshang 1828a00297189c323096aae8e2975de94e8549613cyshang 1928a00297189c323096aae8e2975de94e8549613cyshang// 2028a00297189c323096aae8e2975de94e8549613cyshang// Driver Support Functions 2128a00297189c323096aae8e2975de94e8549613cyshang// 22162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 23162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Connects one or more drivers to a controller. 24162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 25022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle Handle of the controller to be 26022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected. 27022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverImageHandle DriverImageHandle A pointer to an 28022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ordered list of driver image 29022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handles. 30022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param RemainingDevicePath RemainingDevicePath A pointer to 31022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the device path that specifies a 32022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child of the controller specified 33022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang by ControllerHandle. 34022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param Recursive Whether the function would be 35022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang called recursively or not. 36162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 37162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return Status code. 38162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 39162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 40022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 4128a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 4228a00297189c323096aae8e2975de94e8549613cyshangCoreConnectController ( 4328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 4428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 4528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, 4628a00297189c323096aae8e2975de94e8549613cyshang IN BOOLEAN Recursive 4728a00297189c323096aae8e2975de94e8549613cyshang ) 4828a00297189c323096aae8e2975de94e8549613cyshang{ 4928a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 5028a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS ReturnStatus; 5128a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 5228a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 5328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 5428a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 5528a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 5628a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath; 5785658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *ChildHandleBuffer; 5885658066182d23e210209299770edaef26d09085mdkinney UINTN ChildHandleCount; 5985658066182d23e210209299770edaef26d09085mdkinney UINTN Index; 60022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 6128a00297189c323096aae8e2975de94e8549613cyshang // 6228a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 6328a00297189c323096aae8e2975de94e8549613cyshang // 6428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 6528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 6628a00297189c323096aae8e2975de94e8549613cyshang return Status; 6728a00297189c323096aae8e2975de94e8549613cyshang } 6828a00297189c323096aae8e2975de94e8549613cyshang 6928a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 7028a00297189c323096aae8e2975de94e8549613cyshang 7128a00297189c323096aae8e2975de94e8549613cyshang // 7285658066182d23e210209299770edaef26d09085mdkinney // Make a copy of RemainingDevicePath to guanatee it is aligned 7328a00297189c323096aae8e2975de94e8549613cyshang // 7428a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = NULL; 7528a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 769c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath); 776c857d668cb7d2b219351be1daeec0bcd597e377qwang 786c857d668cb7d2b219351be1daeec0bcd597e377qwang if (AlignedRemainingDevicePath == NULL) { 796c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 806c857d668cb7d2b219351be1daeec0bcd597e377qwang } 8128a00297189c323096aae8e2975de94e8549613cyshang } 8228a00297189c323096aae8e2975de94e8549613cyshang 8328a00297189c323096aae8e2975de94e8549613cyshang // 8485658066182d23e210209299770edaef26d09085mdkinney // Connect all drivers to ControllerHandle 8585658066182d23e210209299770edaef26d09085mdkinney // If CoreConnectSingleController returns EFI_NOT_READY, then the number of 8685658066182d23e210209299770edaef26d09085mdkinney // Driver Binding Protocols in the handle database has increased during the call 8785658066182d23e210209299770edaef26d09085mdkinney // so the connect operation must be restarted 8828a00297189c323096aae8e2975de94e8549613cyshang // 8985658066182d23e210209299770edaef26d09085mdkinney do { 9085658066182d23e210209299770edaef26d09085mdkinney ReturnStatus = CoreConnectSingleController ( 91e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ControllerHandle, 92e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang DriverImageHandle, 93e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang AlignedRemainingDevicePath 94e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ); 9585658066182d23e210209299770edaef26d09085mdkinney } while (ReturnStatus == EFI_NOT_READY); 9685658066182d23e210209299770edaef26d09085mdkinney 9785658066182d23e210209299770edaef26d09085mdkinney // 9885658066182d23e210209299770edaef26d09085mdkinney // Free the aligned copy of RemainingDevicePath 9985658066182d23e210209299770edaef26d09085mdkinney // 10085658066182d23e210209299770edaef26d09085mdkinney if (AlignedRemainingDevicePath != NULL) { 10185658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (AlignedRemainingDevicePath); 10228a00297189c323096aae8e2975de94e8549613cyshang } 10328a00297189c323096aae8e2975de94e8549613cyshang 10428a00297189c323096aae8e2975de94e8549613cyshang // 10528a00297189c323096aae8e2975de94e8549613cyshang // If recursive, then connect all drivers to all of ControllerHandle's children 10628a00297189c323096aae8e2975de94e8549613cyshang // 10785658066182d23e210209299770edaef26d09085mdkinney if (Recursive) { 10885658066182d23e210209299770edaef26d09085mdkinney // 10985658066182d23e210209299770edaef26d09085mdkinney // Acquire the protocol lock on the handle database so the child handles can be collected 11085658066182d23e210209299770edaef26d09085mdkinney // 11185658066182d23e210209299770edaef26d09085mdkinney CoreAcquireProtocolLock (); 11285658066182d23e210209299770edaef26d09085mdkinney 11385658066182d23e210209299770edaef26d09085mdkinney // 11485658066182d23e210209299770edaef26d09085mdkinney // Make sure the DriverBindingHandle is valid 11585658066182d23e210209299770edaef26d09085mdkinney // 11685658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (ControllerHandle); 11785658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 11885658066182d23e210209299770edaef26d09085mdkinney // 11985658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 12085658066182d23e210209299770edaef26d09085mdkinney // 12185658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 12285658066182d23e210209299770edaef26d09085mdkinney 12385658066182d23e210209299770edaef26d09085mdkinney return ReturnStatus; 12485658066182d23e210209299770edaef26d09085mdkinney } 12585658066182d23e210209299770edaef26d09085mdkinney 12685658066182d23e210209299770edaef26d09085mdkinney 12785658066182d23e210209299770edaef26d09085mdkinney // 12885658066182d23e210209299770edaef26d09085mdkinney // Count ControllerHandle's children 12985658066182d23e210209299770edaef26d09085mdkinney // 13085658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 13185658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 132022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 133022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 13485658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 13585658066182d23e210209299770edaef26d09085mdkinney OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 13685658066182d23e210209299770edaef26d09085mdkinney if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 13785658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 13885658066182d23e210209299770edaef26d09085mdkinney } 13985658066182d23e210209299770edaef26d09085mdkinney } 14085658066182d23e210209299770edaef26d09085mdkinney } 14185658066182d23e210209299770edaef26d09085mdkinney 14285658066182d23e210209299770edaef26d09085mdkinney // 14385658066182d23e210209299770edaef26d09085mdkinney // Allocate a handle buffer for ControllerHandle's children 14485658066182d23e210209299770edaef26d09085mdkinney // 1459c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE)); 1466c857d668cb7d2b219351be1daeec0bcd597e377qwang if (ChildHandleBuffer == NULL) { 147fa3c419fec30282afb85a788cb71e12fd1a51804qwang CoreReleaseProtocolLock (); 1486c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 1496c857d668cb7d2b219351be1daeec0bcd597e377qwang } 15085658066182d23e210209299770edaef26d09085mdkinney 15185658066182d23e210209299770edaef26d09085mdkinney // 15285658066182d23e210209299770edaef26d09085mdkinney // Fill in a handle buffer with ControllerHandle's children 15385658066182d23e210209299770edaef26d09085mdkinney // 15485658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 15585658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 156022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 157022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 15885658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 15928a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 16028a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 16185658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; 16285658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 16385658066182d23e210209299770edaef26d09085mdkinney } 16485658066182d23e210209299770edaef26d09085mdkinney } 16585658066182d23e210209299770edaef26d09085mdkinney } 16685658066182d23e210209299770edaef26d09085mdkinney 16785658066182d23e210209299770edaef26d09085mdkinney // 16885658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 16985658066182d23e210209299770edaef26d09085mdkinney // 17085658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 17185658066182d23e210209299770edaef26d09085mdkinney 17285658066182d23e210209299770edaef26d09085mdkinney // 17385658066182d23e210209299770edaef26d09085mdkinney // Recursively connect each child handle 17485658066182d23e210209299770edaef26d09085mdkinney // 17585658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < ChildHandleCount; Index++) { 17685658066182d23e210209299770edaef26d09085mdkinney CoreConnectController ( 17785658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[Index], 17885658066182d23e210209299770edaef26d09085mdkinney NULL, 17985658066182d23e210209299770edaef26d09085mdkinney NULL, 18085658066182d23e210209299770edaef26d09085mdkinney TRUE 181022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ); 18285658066182d23e210209299770edaef26d09085mdkinney } 18385658066182d23e210209299770edaef26d09085mdkinney 18485658066182d23e210209299770edaef26d09085mdkinney // 18585658066182d23e210209299770edaef26d09085mdkinney // Free the handle buffer of ControllerHandle's children 18685658066182d23e210209299770edaef26d09085mdkinney // 18785658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (ChildHandleBuffer); 18885658066182d23e210209299770edaef26d09085mdkinney } 18985658066182d23e210209299770edaef26d09085mdkinney 19028a00297189c323096aae8e2975de94e8549613cyshang return ReturnStatus; 19128a00297189c323096aae8e2975de94e8549613cyshang} 19228a00297189c323096aae8e2975de94e8549613cyshang 193162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 194162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 195162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Add Driver Binding Protocols from Context Driver Image Handles to sorted 196162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Driver Binding Protocol list. 197162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 198022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandle Handle of the driver binding 199022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol. 200022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding 201022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocols 202022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param SortedDriverBindingProtocols The sorted protocol list. 203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleCount Driver Binding Handle Count. 204022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleBuffer The buffer of driver binding 205022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol to be modified. 206022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param IsImageHandle Indicate whether 207022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBindingHandle is an image 208022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handle 209162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 210162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return None. 211162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 212162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 21328a00297189c323096aae8e2975de94e8549613cyshangVOID 21428a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol ( 21528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverBindingHandle, 216022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN OUT UINTN *NumberOfSortedDriverBindingProtocols, 21728a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, 21828a00297189c323096aae8e2975de94e8549613cyshang IN UINTN DriverBindingHandleCount, 219adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN OUT EFI_HANDLE *DriverBindingHandleBuffer, 220adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN BOOLEAN IsImageHandle 22128a00297189c323096aae8e2975de94e8549613cyshang ) 22228a00297189c323096aae8e2975de94e8549613cyshang{ 22328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 22428a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 22528a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 22628a00297189c323096aae8e2975de94e8549613cyshang 22728a00297189c323096aae8e2975de94e8549613cyshang // 22828a00297189c323096aae8e2975de94e8549613cyshang // Make sure the DriverBindingHandle is valid 22928a00297189c323096aae8e2975de94e8549613cyshang // 23028a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (DriverBindingHandle); 23128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 23228a00297189c323096aae8e2975de94e8549613cyshang return; 23328a00297189c323096aae8e2975de94e8549613cyshang } 23428a00297189c323096aae8e2975de94e8549613cyshang 23528a00297189c323096aae8e2975de94e8549613cyshang // 236adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle 237adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list 238adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 239adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (IsImageHandle) { 240adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 241adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Loop through all the Driver Binding Handles 242adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 243adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney for (Index = 0; Index < DriverBindingHandleCount; Index++) { 244adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 245adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle 246adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 247adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 248adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 249adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney &gEfiDriverBindingProtocolGuid, 250e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 251adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 25270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (EFI_ERROR (Status) || DriverBinding == NULL) { 25370279390ba9a0774e020af36120f8b9ba1c217dbmdkinney continue; 25470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney } 25570279390ba9a0774e020af36120f8b9ba1c217dbmdkinney 256adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 257adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If the ImageHandle associated with DriverBinding matches DriverBindingHandle, 258adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // then add the DriverBindingProtocol[Index] to the sorted list 259adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 260adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (DriverBinding->ImageHandle == DriverBindingHandle) { 261adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney AddSortedDriverBindingProtocol ( 262adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 263022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NumberOfSortedDriverBindingProtocols, 264adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney SortedDriverBindingProtocols, 265adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleCount, 266adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 267adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 268adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 269adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 270adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 271adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney return; 272adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 273adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney 274adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 27528a00297189c323096aae8e2975de94e8549613cyshang // Retrieve the Driver Binding Protocol from DriverBindingHandle 27628a00297189c323096aae8e2975de94e8549613cyshang // 27728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 27828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle, 27928a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 280e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 28128a00297189c323096aae8e2975de94e8549613cyshang ); 28228a00297189c323096aae8e2975de94e8549613cyshang // 28328a00297189c323096aae8e2975de94e8549613cyshang // If DriverBindingHandle does not support the Driver Binding Protocol then return 28428a00297189c323096aae8e2975de94e8549613cyshang // 28528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBinding == NULL) { 28628a00297189c323096aae8e2975de94e8549613cyshang return; 28728a00297189c323096aae8e2975de94e8549613cyshang } 28828a00297189c323096aae8e2975de94e8549613cyshang 28928a00297189c323096aae8e2975de94e8549613cyshang // 29028a00297189c323096aae8e2975de94e8549613cyshang // See if DriverBinding is already in the sorted list 29128a00297189c323096aae8e2975de94e8549613cyshang // 29285658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { 29328a00297189c323096aae8e2975de94e8549613cyshang if (DriverBinding == SortedDriverBindingProtocols[Index]) { 29428a00297189c323096aae8e2975de94e8549613cyshang return; 29528a00297189c323096aae8e2975de94e8549613cyshang } 29628a00297189c323096aae8e2975de94e8549613cyshang } 29728a00297189c323096aae8e2975de94e8549613cyshang 29828a00297189c323096aae8e2975de94e8549613cyshang // 29928a00297189c323096aae8e2975de94e8549613cyshang // Add DriverBinding to the end of the list 30028a00297189c323096aae8e2975de94e8549613cyshang // 30185658066182d23e210209299770edaef26d09085mdkinney if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { 30285658066182d23e210209299770edaef26d09085mdkinney SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; 30385658066182d23e210209299770edaef26d09085mdkinney } 30428a00297189c323096aae8e2975de94e8549613cyshang *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; 30528a00297189c323096aae8e2975de94e8549613cyshang 30628a00297189c323096aae8e2975de94e8549613cyshang // 30728a00297189c323096aae8e2975de94e8549613cyshang // Mark the cooresponding handle in DriverBindingHandleBuffer as used 30828a00297189c323096aae8e2975de94e8549613cyshang // 30928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 31028a00297189c323096aae8e2975de94e8549613cyshang if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { 31128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index] = NULL; 31228a00297189c323096aae8e2975de94e8549613cyshang } 31328a00297189c323096aae8e2975de94e8549613cyshang } 31428a00297189c323096aae8e2975de94e8549613cyshang} 315022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 316162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 317162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 318162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Connects a controller to a driver. 319162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 320022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle Handle of the controller to be 321022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected. 322022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ContextDriverImageHandles DriverImageHandle A pointer to an 323022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ordered list of driver image 324022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handles. 325022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param RemainingDevicePath RemainingDevicePath A pointer to 326022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the device path that specifies a 327022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child of the controller 328022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang specified by ControllerHandle. 329022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 330022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 331022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected to ControllerHandle. 332022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES No enough system resources to 333022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang complete the request. 334022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_NOT_FOUND No drivers were connected to 335162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ControllerHandle. 336162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 337162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 338022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 33928a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 34028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 34128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, 342022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 34328a00297189c323096aae8e2975de94e8549613cyshang ) 34428a00297189c323096aae8e2975de94e8549613cyshang{ 34528a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 34628a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 34728a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverImageHandle; 34828a00297189c323096aae8e2975de94e8549613cyshang EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; 34928a00297189c323096aae8e2975de94e8549613cyshang EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; 35028a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 35128a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 35270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney UINTN NewDriverBindingHandleCount; 35370279390ba9a0774e020af36120f8b9ba1c217dbmdkinney EFI_HANDLE *NewDriverBindingHandleBuffer; 35428a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 35528a00297189c323096aae8e2975de94e8549613cyshang UINTN NumberOfSortedDriverBindingProtocols; 35628a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; 35728a00297189c323096aae8e2975de94e8549613cyshang UINT32 HighestVersion; 35828a00297189c323096aae8e2975de94e8549613cyshang UINTN HighestIndex; 35928a00297189c323096aae8e2975de94e8549613cyshang UINTN SortIndex; 36028a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN OneStarted; 36128a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverFound; 36228a00297189c323096aae8e2975de94e8549613cyshang 36328a00297189c323096aae8e2975de94e8549613cyshang // 36428a00297189c323096aae8e2975de94e8549613cyshang // Initialize local variables 36528a00297189c323096aae8e2975de94e8549613cyshang // 36628a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 36728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 36828a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols = 0; 36928a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = NULL; 37028a00297189c323096aae8e2975de94e8549613cyshang 37128a00297189c323096aae8e2975de94e8549613cyshang // 37228a00297189c323096aae8e2975de94e8549613cyshang // Get list of all Driver Binding Protocol Instances 37328a00297189c323096aae8e2975de94e8549613cyshang // 37428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 375022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 376022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 37728a00297189c323096aae8e2975de94e8549613cyshang NULL, 378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &DriverBindingHandleCount, 37928a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleBuffer 38028a00297189c323096aae8e2975de94e8549613cyshang ); 38128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) { 38228a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 38328a00297189c323096aae8e2975de94e8549613cyshang } 38428a00297189c323096aae8e2975de94e8549613cyshang 38528a00297189c323096aae8e2975de94e8549613cyshang // 38628a00297189c323096aae8e2975de94e8549613cyshang // Allocate a duplicate array for the sorted Driver Binding Protocol Instances 38728a00297189c323096aae8e2975de94e8549613cyshang // 3889c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount); 38928a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols == NULL) { 39028a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 39128a00297189c323096aae8e2975de94e8549613cyshang return EFI_OUT_OF_RESOURCES; 39228a00297189c323096aae8e2975de94e8549613cyshang } 39328a00297189c323096aae8e2975de94e8549613cyshang 39428a00297189c323096aae8e2975de94e8549613cyshang // 39528a00297189c323096aae8e2975de94e8549613cyshang // Add Driver Binding Protocols from Context Driver Image Handles first 39628a00297189c323096aae8e2975de94e8549613cyshang // 39728a00297189c323096aae8e2975de94e8549613cyshang if (ContextDriverImageHandles != NULL) { 39828a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) { 39928a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 40028a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles[Index], 401022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 40228a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 40328a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 404adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 405adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 40628a00297189c323096aae8e2975de94e8549613cyshang ); 40728a00297189c323096aae8e2975de94e8549613cyshang } 40828a00297189c323096aae8e2975de94e8549613cyshang } 40928a00297189c323096aae8e2975de94e8549613cyshang 41028a00297189c323096aae8e2975de94e8549613cyshang // 41128a00297189c323096aae8e2975de94e8549613cyshang // Add the Platform Driver Override Protocol drivers for ControllerHandle next 41228a00297189c323096aae8e2975de94e8549613cyshang // 41328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateProtocol ( 414022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiPlatformDriverOverrideProtocolGuid, 415022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NULL, 416e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &PlatformDriverOverride 41728a00297189c323096aae8e2975de94e8549613cyshang ); 41828a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { 41928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 42028a00297189c323096aae8e2975de94e8549613cyshang do { 42128a00297189c323096aae8e2975de94e8549613cyshang Status = PlatformDriverOverride->GetDriver ( 42228a00297189c323096aae8e2975de94e8549613cyshang PlatformDriverOverride, 42328a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 42428a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 42528a00297189c323096aae8e2975de94e8549613cyshang ); 42628a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 42728a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 42828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 429022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 43028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 43128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 432adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 433adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 43428a00297189c323096aae8e2975de94e8549613cyshang ); 43528a00297189c323096aae8e2975de94e8549613cyshang } 43628a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 43728a00297189c323096aae8e2975de94e8549613cyshang } 43828a00297189c323096aae8e2975de94e8549613cyshang 43928a00297189c323096aae8e2975de94e8549613cyshang // 44028a00297189c323096aae8e2975de94e8549613cyshang // Get the Bus Specific Driver Override Protocol instance on the Controller Handle 44128a00297189c323096aae8e2975de94e8549613cyshang // 442adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 443022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle, 444022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiBusSpecificDriverOverrideProtocolGuid, 445e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &BusSpecificDriverOverride 44628a00297189c323096aae8e2975de94e8549613cyshang ); 44728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { 44828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 44928a00297189c323096aae8e2975de94e8549613cyshang do { 45028a00297189c323096aae8e2975de94e8549613cyshang Status = BusSpecificDriverOverride->GetDriver ( 45128a00297189c323096aae8e2975de94e8549613cyshang BusSpecificDriverOverride, 45228a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 45328a00297189c323096aae8e2975de94e8549613cyshang ); 45428a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 45528a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 45628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 457022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 45828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 45928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 460adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 461adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 46228a00297189c323096aae8e2975de94e8549613cyshang ); 46328a00297189c323096aae8e2975de94e8549613cyshang } 46428a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 46528a00297189c323096aae8e2975de94e8549613cyshang } 46628a00297189c323096aae8e2975de94e8549613cyshang 46728a00297189c323096aae8e2975de94e8549613cyshang // 46828a00297189c323096aae8e2975de94e8549613cyshang // Then add all the remaining Driver Binding Protocols 46928a00297189c323096aae8e2975de94e8549613cyshang // 47028a00297189c323096aae8e2975de94e8549613cyshang SortIndex = NumberOfSortedDriverBindingProtocols; 47128a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 47228a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 47328a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 474022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 47528a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 47628a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 477adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 478adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 47928a00297189c323096aae8e2975de94e8549613cyshang ); 48028a00297189c323096aae8e2975de94e8549613cyshang } 48128a00297189c323096aae8e2975de94e8549613cyshang 48228a00297189c323096aae8e2975de94e8549613cyshang // 48328a00297189c323096aae8e2975de94e8549613cyshang // Free the Driver Binding Handle Buffer 48428a00297189c323096aae8e2975de94e8549613cyshang // 48528a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 48628a00297189c323096aae8e2975de94e8549613cyshang 48728a00297189c323096aae8e2975de94e8549613cyshang // 48885658066182d23e210209299770edaef26d09085mdkinney // If the number of Driver Binding Protocols has increased since this function started, then return 48985658066182d23e210209299770edaef26d09085mdkinney // EFI_NOT_READY, so it will be restarted 49085658066182d23e210209299770edaef26d09085mdkinney // 49170279390ba9a0774e020af36120f8b9ba1c217dbmdkinney Status = CoreLocateHandleBuffer ( 492022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 493022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 49470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney NULL, 495022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NewDriverBindingHandleCount, 49670279390ba9a0774e020af36120f8b9ba1c217dbmdkinney &NewDriverBindingHandleBuffer 49770279390ba9a0774e020af36120f8b9ba1c217dbmdkinney ); 49870279390ba9a0774e020af36120f8b9ba1c217dbmdkinney CoreFreePool (NewDriverBindingHandleBuffer); 49970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (NewDriverBindingHandleCount > DriverBindingHandleCount) { 50085658066182d23e210209299770edaef26d09085mdkinney // 50185658066182d23e210209299770edaef26d09085mdkinney // Free any buffers that were allocated with AllocatePool() 50285658066182d23e210209299770edaef26d09085mdkinney // 50385658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (SortedDriverBindingProtocols); 50485658066182d23e210209299770edaef26d09085mdkinney 50585658066182d23e210209299770edaef26d09085mdkinney return EFI_NOT_READY; 50685658066182d23e210209299770edaef26d09085mdkinney } 50785658066182d23e210209299770edaef26d09085mdkinney 50885658066182d23e210209299770edaef26d09085mdkinney // 50928a00297189c323096aae8e2975de94e8549613cyshang // Sort the remaining DriverBinding Protocol based on their Version field from 51028a00297189c323096aae8e2975de94e8549613cyshang // highest to lowest. 51128a00297189c323096aae8e2975de94e8549613cyshang // 51228a00297189c323096aae8e2975de94e8549613cyshang for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { 51328a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; 51428a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = SortIndex; 51528a00297189c323096aae8e2975de94e8549613cyshang for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { 51628a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { 51728a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[Index]->Version; 51828a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = Index; 51928a00297189c323096aae8e2975de94e8549613cyshang } 52028a00297189c323096aae8e2975de94e8549613cyshang } 52128a00297189c323096aae8e2975de94e8549613cyshang if (SortIndex != HighestIndex) { 52228a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[SortIndex]; 52328a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; 52428a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[HighestIndex] = DriverBinding; 52528a00297189c323096aae8e2975de94e8549613cyshang } 52628a00297189c323096aae8e2975de94e8549613cyshang } 52728a00297189c323096aae8e2975de94e8549613cyshang 52828a00297189c323096aae8e2975de94e8549613cyshang // 52928a00297189c323096aae8e2975de94e8549613cyshang // Loop until no more drivers can be started on ControllerHandle 53028a00297189c323096aae8e2975de94e8549613cyshang // 53128a00297189c323096aae8e2975de94e8549613cyshang OneStarted = FALSE; 53228a00297189c323096aae8e2975de94e8549613cyshang do { 53328a00297189c323096aae8e2975de94e8549613cyshang 53428a00297189c323096aae8e2975de94e8549613cyshang // 53528a00297189c323096aae8e2975de94e8549613cyshang // Loop through the sorted Driver Binding Protocol Instances in order, and see if 536022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // any of the Driver Binding Protocols support the controller specified by 53728a00297189c323096aae8e2975de94e8549613cyshang // ControllerHandle. 53828a00297189c323096aae8e2975de94e8549613cyshang // 53928a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = NULL; 54028a00297189c323096aae8e2975de94e8549613cyshang DriverFound = FALSE; 54128a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { 54228a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index] != NULL) { 54328a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[Index]; 54428a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Supported( 545022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 54628a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 54728a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 54828a00297189c323096aae8e2975de94e8549613cyshang ); 54928a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 55028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[Index] = NULL; 55128a00297189c323096aae8e2975de94e8549613cyshang DriverFound = TRUE; 55228a00297189c323096aae8e2975de94e8549613cyshang 55328a00297189c323096aae8e2975de94e8549613cyshang // 55428a00297189c323096aae8e2975de94e8549613cyshang // A driver was found that supports ControllerHandle, so attempt to start the driver 55528a00297189c323096aae8e2975de94e8549613cyshang // on ControllerHandle. 55628a00297189c323096aae8e2975de94e8549613cyshang // 557adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney PERF_START (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 55828a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Start ( 559022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 56028a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 56128a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 56228a00297189c323096aae8e2975de94e8549613cyshang ); 563adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney PERF_END (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 56428a00297189c323096aae8e2975de94e8549613cyshang 56528a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 56628a00297189c323096aae8e2975de94e8549613cyshang // 56728a00297189c323096aae8e2975de94e8549613cyshang // The driver was successfully started on ControllerHandle, so set a flag 56828a00297189c323096aae8e2975de94e8549613cyshang // 56928a00297189c323096aae8e2975de94e8549613cyshang OneStarted = TRUE; 57028a00297189c323096aae8e2975de94e8549613cyshang } 57128a00297189c323096aae8e2975de94e8549613cyshang } 57228a00297189c323096aae8e2975de94e8549613cyshang } 57328a00297189c323096aae8e2975de94e8549613cyshang } 57428a00297189c323096aae8e2975de94e8549613cyshang } while (DriverFound); 57528a00297189c323096aae8e2975de94e8549613cyshang 57628a00297189c323096aae8e2975de94e8549613cyshang // 57728a00297189c323096aae8e2975de94e8549613cyshang // Free any buffers that were allocated with AllocatePool() 57828a00297189c323096aae8e2975de94e8549613cyshang // 57928a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (SortedDriverBindingProtocols); 58028a00297189c323096aae8e2975de94e8549613cyshang 58128a00297189c323096aae8e2975de94e8549613cyshang // 58228a00297189c323096aae8e2975de94e8549613cyshang // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. 58328a00297189c323096aae8e2975de94e8549613cyshang // 58428a00297189c323096aae8e2975de94e8549613cyshang if (OneStarted) { 58528a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 586022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 58728a00297189c323096aae8e2975de94e8549613cyshang 58828a00297189c323096aae8e2975de94e8549613cyshang // 58928a00297189c323096aae8e2975de94e8549613cyshang // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS 59028a00297189c323096aae8e2975de94e8549613cyshang // 59128a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 59228a00297189c323096aae8e2975de94e8549613cyshang if (IsDevicePathEnd (RemainingDevicePath)) { 59328a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 59428a00297189c323096aae8e2975de94e8549613cyshang } 595022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 59628a00297189c323096aae8e2975de94e8549613cyshang 59728a00297189c323096aae8e2975de94e8549613cyshang // 59828a00297189c323096aae8e2975de94e8549613cyshang // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND 59928a00297189c323096aae8e2975de94e8549613cyshang // 60028a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 60128a00297189c323096aae8e2975de94e8549613cyshang} 60228a00297189c323096aae8e2975de94e8549613cyshang 60328a00297189c323096aae8e2975de94e8549613cyshang 604162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 605162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 606162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Disonnects a controller from a driver 607162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 608022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle ControllerHandle The handle of 609022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the controller from which 610022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang driver(s) are to be 611022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected. 612022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverImageHandle DriverImageHandle The driver to 613022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnect from ControllerHandle. 614022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ChildHandle ChildHandle The handle of the 615022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child to destroy. 616022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 617022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 618022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected from the controller. 619022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS On entry, no drivers are managing 620022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle. 621022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS DriverImageHandle is not NULL, 622022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and on entry DriverImageHandle is 623022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang not managing ControllerHandle. 624022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid 625022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang EFI_HANDLE. 626022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, 627022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and it is not a valid EFI_HANDLE. 628022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it 629022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang is not a valid EFI_HANDLE. 630022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES There are not enough resources 631022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang available to disconnect any 632022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang drivers from ControllerHandle. 633022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_DEVICE_ERROR The controller could not be 634022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected because of a device 635162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang error. 636162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 637162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 638022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 63928a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 64028a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController ( 64128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 64228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverImageHandle OPTIONAL, 64328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ChildHandle OPTIONAL 64428a00297189c323096aae8e2975de94e8549613cyshang ) 64528a00297189c323096aae8e2975de94e8549613cyshang{ 64628a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 64728a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 64828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverImageHandleBuffer; 64928a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *ChildBuffer; 65028a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 65128a00297189c323096aae8e2975de94e8549613cyshang UINTN HandleIndex; 65228a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverImageHandleCount; 65328a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildrenToStop; 65428a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildBufferCount; 65528a00297189c323096aae8e2975de94e8549613cyshang UINTN StopCount; 65628a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Duplicate; 65728a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ChildHandleValid; 65828a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverImageHandleValid; 65928a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 66028a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 66128a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 66228a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 66328a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 66428a00297189c323096aae8e2975de94e8549613cyshang 66528a00297189c323096aae8e2975de94e8549613cyshang // 66628a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 66728a00297189c323096aae8e2975de94e8549613cyshang // 66828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 66928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 67028a00297189c323096aae8e2975de94e8549613cyshang return Status; 67128a00297189c323096aae8e2975de94e8549613cyshang } 67228a00297189c323096aae8e2975de94e8549613cyshang 67328a00297189c323096aae8e2975de94e8549613cyshang // 67428a00297189c323096aae8e2975de94e8549613cyshang // Make sure ChildHandle is valid if it is not NULL 67528a00297189c323096aae8e2975de94e8549613cyshang // 67628a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 67728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ChildHandle); 67828a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 67928a00297189c323096aae8e2975de94e8549613cyshang return Status; 68028a00297189c323096aae8e2975de94e8549613cyshang } 68128a00297189c323096aae8e2975de94e8549613cyshang } 68228a00297189c323096aae8e2975de94e8549613cyshang 68328a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 68428a00297189c323096aae8e2975de94e8549613cyshang 68528a00297189c323096aae8e2975de94e8549613cyshang // 68628a00297189c323096aae8e2975de94e8549613cyshang // Get list of drivers that are currently managing ControllerHandle 68728a00297189c323096aae8e2975de94e8549613cyshang // 68828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = NULL; 689022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandleCount = 1; 690022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 69128a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandle == NULL) { 69228a00297189c323096aae8e2975de94e8549613cyshang // 69328a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 69428a00297189c323096aae8e2975de94e8549613cyshang // 69528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 69628a00297189c323096aae8e2975de94e8549613cyshang 69728a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 69828a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 69928a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 700022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 701022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 70228a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 70328a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 70428a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 70528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 70628a00297189c323096aae8e2975de94e8549613cyshang } 70728a00297189c323096aae8e2975de94e8549613cyshang } 70828a00297189c323096aae8e2975de94e8549613cyshang } 70928a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 710022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 71128a00297189c323096aae8e2975de94e8549613cyshang // 71228a00297189c323096aae8e2975de94e8549613cyshang // If there are no drivers managing this controller, then return EFI_SUCCESS 71328a00297189c323096aae8e2975de94e8549613cyshang // 71428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleCount == 0) { 71528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 71628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 71728a00297189c323096aae8e2975de94e8549613cyshang } 71828a00297189c323096aae8e2975de94e8549613cyshang 7199c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount); 72028a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer == NULL) { 72128a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 72228a00297189c323096aae8e2975de94e8549613cyshang goto Done; 72328a00297189c323096aae8e2975de94e8549613cyshang } 72428a00297189c323096aae8e2975de94e8549613cyshang 72528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 72628a00297189c323096aae8e2975de94e8549613cyshang 72728a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 72828a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 72928a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 730022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 731022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 73228a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 73328a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 73428a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 73528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 73628a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index< DriverImageHandleCount; Index++) { 73728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { 73828a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 73928a00297189c323096aae8e2975de94e8549613cyshang break; 74028a00297189c323096aae8e2975de94e8549613cyshang } 74128a00297189c323096aae8e2975de94e8549613cyshang } 74228a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 74328a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; 74428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 74528a00297189c323096aae8e2975de94e8549613cyshang } 74628a00297189c323096aae8e2975de94e8549613cyshang } 74728a00297189c323096aae8e2975de94e8549613cyshang } 74828a00297189c323096aae8e2975de94e8549613cyshang } 74928a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 75028a00297189c323096aae8e2975de94e8549613cyshang } 75128a00297189c323096aae8e2975de94e8549613cyshang 75228a00297189c323096aae8e2975de94e8549613cyshang StopCount = 0; 75328a00297189c323096aae8e2975de94e8549613cyshang for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { 75428a00297189c323096aae8e2975de94e8549613cyshang 75528a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 75628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; 75728a00297189c323096aae8e2975de94e8549613cyshang } 75828a00297189c323096aae8e2975de94e8549613cyshang 75928a00297189c323096aae8e2975de94e8549613cyshang // 76028a00297189c323096aae8e2975de94e8549613cyshang // Get the Driver Binding Protocol of the driver that is managing this controller 76128a00297189c323096aae8e2975de94e8549613cyshang // 76228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol ( 763022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandle, 764022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 76528a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 76628a00297189c323096aae8e2975de94e8549613cyshang ); 76728a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 76828a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 76928a00297189c323096aae8e2975de94e8549613cyshang goto Done; 77028a00297189c323096aae8e2975de94e8549613cyshang } 77128a00297189c323096aae8e2975de94e8549613cyshang 77228a00297189c323096aae8e2975de94e8549613cyshang // 77328a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 77428a00297189c323096aae8e2975de94e8549613cyshang // 77528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = FALSE; 77628a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 77728a00297189c323096aae8e2975de94e8549613cyshang 77828a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 77928a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 78028a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 781022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 782022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 78328a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 78428a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 78528a00297189c323096aae8e2975de94e8549613cyshang if (OpenData->AgentHandle == DriverImageHandle) { 78628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 78728a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 788022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 78928a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 79028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = TRUE; 79128a00297189c323096aae8e2975de94e8549613cyshang } 79228a00297189c323096aae8e2975de94e8549613cyshang } 79328a00297189c323096aae8e2975de94e8549613cyshang } 79428a00297189c323096aae8e2975de94e8549613cyshang } 79528a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 79628a00297189c323096aae8e2975de94e8549613cyshang 79728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleValid) { 79828a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = FALSE; 79928a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = NULL; 80028a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount != 0) { 8019c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount); 80228a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer == NULL) { 80328a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 80428a00297189c323096aae8e2975de94e8549613cyshang goto Done; 80528a00297189c323096aae8e2975de94e8549613cyshang } 80628a00297189c323096aae8e2975de94e8549613cyshang 80728a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 80828a00297189c323096aae8e2975de94e8549613cyshang 80928a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 81028a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 81128a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 812022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 813022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 81428a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 81528a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 81628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == DriverImageHandle) && 81728a00297189c323096aae8e2975de94e8549613cyshang ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { 81828a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 81928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < ChildBufferCount; Index++) { 82028a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer[Index] == OpenData->ControllerHandle) { 82128a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 82228a00297189c323096aae8e2975de94e8549613cyshang break; 82328a00297189c323096aae8e2975de94e8549613cyshang } 82428a00297189c323096aae8e2975de94e8549613cyshang } 82528a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 82628a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; 82728a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == ChildBuffer[ChildBufferCount]) { 82828a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = TRUE; 82928a00297189c323096aae8e2975de94e8549613cyshang } 83028a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 83128a00297189c323096aae8e2975de94e8549613cyshang } 83228a00297189c323096aae8e2975de94e8549613cyshang } 83328a00297189c323096aae8e2975de94e8549613cyshang } 83428a00297189c323096aae8e2975de94e8549613cyshang } 83528a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 83628a00297189c323096aae8e2975de94e8549613cyshang } 83728a00297189c323096aae8e2975de94e8549613cyshang 83828a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == NULL || ChildHandleValid) { 83928a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 0; 84028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 84128a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount > 0) { 84228a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 84328a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 1; 84428a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); 84528a00297189c323096aae8e2975de94e8549613cyshang } else { 84628a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = ChildBufferCount; 84728a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); 84828a00297189c323096aae8e2975de94e8549613cyshang } 84928a00297189c323096aae8e2975de94e8549613cyshang } 85028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { 85128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); 85228a00297189c323096aae8e2975de94e8549613cyshang } 85328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 85428a00297189c323096aae8e2975de94e8549613cyshang StopCount++; 85528a00297189c323096aae8e2975de94e8549613cyshang } 85628a00297189c323096aae8e2975de94e8549613cyshang } 85728a00297189c323096aae8e2975de94e8549613cyshang 85828a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer != NULL) { 85928a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (ChildBuffer); 86028a00297189c323096aae8e2975de94e8549613cyshang } 86128a00297189c323096aae8e2975de94e8549613cyshang } 86228a00297189c323096aae8e2975de94e8549613cyshang } 86328a00297189c323096aae8e2975de94e8549613cyshang 86428a00297189c323096aae8e2975de94e8549613cyshang if (StopCount > 0) { 86528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 86628a00297189c323096aae8e2975de94e8549613cyshang } else { 86728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 86828a00297189c323096aae8e2975de94e8549613cyshang } 869022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 870022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangDone: 87128a00297189c323096aae8e2975de94e8549613cyshang 87228a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 87328a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverImageHandleBuffer); 87428a00297189c323096aae8e2975de94e8549613cyshang } 87528a00297189c323096aae8e2975de94e8549613cyshang 87628a00297189c323096aae8e2975de94e8549613cyshang return Status; 87728a00297189c323096aae8e2975de94e8549613cyshang} 878