DriverSupport.c revision bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bc
123c98c9417908188207408afa3f6901b8aca826aqhuang/** @file 2504214c4870e9183418014634268ce630eb5332algao Support functions to connect/disconnect UEFI Driver model Protocol 3504214c4870e9183418014634268ce630eb5332algao 4bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgaoCopyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR> 5cd5ebaa06dca3e6ef3c464081e6defe00d358c69hhtianThis 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 25bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @param ControllerHandle The handle of the controller to which driver(s) are to be connected. 26bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @param DriverImageHandle A pointer to an ordered list handles that support the 27bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao EFI_DRIVER_BINDING_PROTOCOL. 28bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @param RemainingDevicePath A pointer to the device path that specifies a child of the 29bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao controller specified by ControllerHandle. 30bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @param Recursive If TRUE, then ConnectController() is called recursively 31bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao until the entire tree of controllers below the controller specified 32bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao by ControllerHandle have been created. If FALSE, then 33bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao the tree of controllers is only expanded one level. 34162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 35bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. 36bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 2) No drivers were connected to ControllerHandle, but 37bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao RemainingDevicePath is not NULL, and it is an End Device 38bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao Path Node. 39bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. 40bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances 41bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao present in the system. 42bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 2) No drivers were connected to ControllerHandle. 43bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao @retval EFI_SECURITY_VIOLATION 44bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao The user has no permission to start UEFI device drivers on the device path 45bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao associated with the ControllerHandle or specified by the RemainingDevicePath. 46162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 47162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 48022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 4928a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 5028a00297189c323096aae8e2975de94e8549613cyshangCoreConnectController ( 5128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 5228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 5328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, 5428a00297189c323096aae8e2975de94e8549613cyshang IN BOOLEAN Recursive 5528a00297189c323096aae8e2975de94e8549613cyshang ) 5628a00297189c323096aae8e2975de94e8549613cyshang{ 5728a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 5828a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS ReturnStatus; 5928a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 6028a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 6128a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 6228a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 6328a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 6428a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath; 6585658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *ChildHandleBuffer; 6685658066182d23e210209299770edaef26d09085mdkinney UINTN ChildHandleCount; 6785658066182d23e210209299770edaef26d09085mdkinney UINTN Index; 68bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao UINTN HandleFilePathSize; 69bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao UINTN RemainingDevicePathSize; 70bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao EFI_DEVICE_PATH_PROTOCOL *HandleFilePath; 71bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao EFI_DEVICE_PATH_PROTOCOL *FilePath; 72bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao EFI_DEVICE_PATH_PROTOCOL *TempFilePath; 73022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 7428a00297189c323096aae8e2975de94e8549613cyshang // 7528a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 7628a00297189c323096aae8e2975de94e8549613cyshang // 7728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 7828a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 7928a00297189c323096aae8e2975de94e8549613cyshang return Status; 8028a00297189c323096aae8e2975de94e8549613cyshang } 8128a00297189c323096aae8e2975de94e8549613cyshang 82bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (gSecurity2 != NULL) { 83bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao // 84bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao // Check whether the user has permission to start UEFI device drivers. 85bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao // 86bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath); 87bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (!EFI_ERROR (Status)) { 88bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath = HandleFilePath; 89bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao TempFilePath = NULL; 90bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (RemainingDevicePath != NULL && !Recursive) { 91bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao HandleFilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); 92bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath); 93bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize); 94bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao ASSERT (TempFilePath != NULL); 95bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize); 96bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao CopyMem ((UINT8 *) TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize); 97bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath = TempFilePath; 98bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 99bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao Status = gSecurity2->FileAuthentication ( 100bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao gSecurity2, 101bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath, 102bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao NULL, 103bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 0, 104bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FALSE 105bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao ); 106bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (TempFilePath != NULL) { 107bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FreePool (TempFilePath); 108bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 109bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (EFI_ERROR (Status)) { 110bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao return Status; 111bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 112bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 113bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 114bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 11528a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 11628a00297189c323096aae8e2975de94e8549613cyshang 11728a00297189c323096aae8e2975de94e8549613cyshang // 11885658066182d23e210209299770edaef26d09085mdkinney // Make a copy of RemainingDevicePath to guanatee it is aligned 11928a00297189c323096aae8e2975de94e8549613cyshang // 12028a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = NULL; 12128a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 1229c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath); 1236c857d668cb7d2b219351be1daeec0bcd597e377qwang 1246c857d668cb7d2b219351be1daeec0bcd597e377qwang if (AlignedRemainingDevicePath == NULL) { 1256c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 1266c857d668cb7d2b219351be1daeec0bcd597e377qwang } 12728a00297189c323096aae8e2975de94e8549613cyshang } 12828a00297189c323096aae8e2975de94e8549613cyshang 12928a00297189c323096aae8e2975de94e8549613cyshang // 13085658066182d23e210209299770edaef26d09085mdkinney // Connect all drivers to ControllerHandle 13185658066182d23e210209299770edaef26d09085mdkinney // If CoreConnectSingleController returns EFI_NOT_READY, then the number of 13285658066182d23e210209299770edaef26d09085mdkinney // Driver Binding Protocols in the handle database has increased during the call 13385658066182d23e210209299770edaef26d09085mdkinney // so the connect operation must be restarted 13428a00297189c323096aae8e2975de94e8549613cyshang // 13585658066182d23e210209299770edaef26d09085mdkinney do { 13685658066182d23e210209299770edaef26d09085mdkinney ReturnStatus = CoreConnectSingleController ( 137e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ControllerHandle, 138e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang DriverImageHandle, 139e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang AlignedRemainingDevicePath 140e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ); 14185658066182d23e210209299770edaef26d09085mdkinney } while (ReturnStatus == EFI_NOT_READY); 14285658066182d23e210209299770edaef26d09085mdkinney 14385658066182d23e210209299770edaef26d09085mdkinney // 14485658066182d23e210209299770edaef26d09085mdkinney // Free the aligned copy of RemainingDevicePath 14585658066182d23e210209299770edaef26d09085mdkinney // 14685658066182d23e210209299770edaef26d09085mdkinney if (AlignedRemainingDevicePath != NULL) { 14785658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (AlignedRemainingDevicePath); 14828a00297189c323096aae8e2975de94e8549613cyshang } 14928a00297189c323096aae8e2975de94e8549613cyshang 15028a00297189c323096aae8e2975de94e8549613cyshang // 15128a00297189c323096aae8e2975de94e8549613cyshang // If recursive, then connect all drivers to all of ControllerHandle's children 15228a00297189c323096aae8e2975de94e8549613cyshang // 15385658066182d23e210209299770edaef26d09085mdkinney if (Recursive) { 15485658066182d23e210209299770edaef26d09085mdkinney // 15585658066182d23e210209299770edaef26d09085mdkinney // Acquire the protocol lock on the handle database so the child handles can be collected 15685658066182d23e210209299770edaef26d09085mdkinney // 15785658066182d23e210209299770edaef26d09085mdkinney CoreAcquireProtocolLock (); 15885658066182d23e210209299770edaef26d09085mdkinney 15985658066182d23e210209299770edaef26d09085mdkinney // 16085658066182d23e210209299770edaef26d09085mdkinney // Make sure the DriverBindingHandle is valid 16185658066182d23e210209299770edaef26d09085mdkinney // 16285658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (ControllerHandle); 16385658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 16485658066182d23e210209299770edaef26d09085mdkinney // 16585658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 16685658066182d23e210209299770edaef26d09085mdkinney // 16785658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 16885658066182d23e210209299770edaef26d09085mdkinney 16985658066182d23e210209299770edaef26d09085mdkinney return ReturnStatus; 17085658066182d23e210209299770edaef26d09085mdkinney } 17185658066182d23e210209299770edaef26d09085mdkinney 17285658066182d23e210209299770edaef26d09085mdkinney 17385658066182d23e210209299770edaef26d09085mdkinney // 17485658066182d23e210209299770edaef26d09085mdkinney // Count ControllerHandle's children 17585658066182d23e210209299770edaef26d09085mdkinney // 17685658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 17785658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 178022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 179022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 18085658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 18185658066182d23e210209299770edaef26d09085mdkinney OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 18285658066182d23e210209299770edaef26d09085mdkinney if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 18385658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 18485658066182d23e210209299770edaef26d09085mdkinney } 18585658066182d23e210209299770edaef26d09085mdkinney } 18685658066182d23e210209299770edaef26d09085mdkinney } 18785658066182d23e210209299770edaef26d09085mdkinney 18885658066182d23e210209299770edaef26d09085mdkinney // 18985658066182d23e210209299770edaef26d09085mdkinney // Allocate a handle buffer for ControllerHandle's children 19085658066182d23e210209299770edaef26d09085mdkinney // 1919c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE)); 1926c857d668cb7d2b219351be1daeec0bcd597e377qwang if (ChildHandleBuffer == NULL) { 193fa3c419fec30282afb85a788cb71e12fd1a51804qwang CoreReleaseProtocolLock (); 1946c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 1956c857d668cb7d2b219351be1daeec0bcd597e377qwang } 19685658066182d23e210209299770edaef26d09085mdkinney 19785658066182d23e210209299770edaef26d09085mdkinney // 19885658066182d23e210209299770edaef26d09085mdkinney // Fill in a handle buffer with ControllerHandle's children 19985658066182d23e210209299770edaef26d09085mdkinney // 20085658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 20185658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 202022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 20485658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 20528a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 20628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 20785658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; 20885658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 20985658066182d23e210209299770edaef26d09085mdkinney } 21085658066182d23e210209299770edaef26d09085mdkinney } 21185658066182d23e210209299770edaef26d09085mdkinney } 21285658066182d23e210209299770edaef26d09085mdkinney 21385658066182d23e210209299770edaef26d09085mdkinney // 21485658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 21585658066182d23e210209299770edaef26d09085mdkinney // 21685658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 21785658066182d23e210209299770edaef26d09085mdkinney 21885658066182d23e210209299770edaef26d09085mdkinney // 21985658066182d23e210209299770edaef26d09085mdkinney // Recursively connect each child handle 22085658066182d23e210209299770edaef26d09085mdkinney // 22185658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < ChildHandleCount; Index++) { 22285658066182d23e210209299770edaef26d09085mdkinney CoreConnectController ( 22385658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[Index], 22485658066182d23e210209299770edaef26d09085mdkinney NULL, 22585658066182d23e210209299770edaef26d09085mdkinney NULL, 22685658066182d23e210209299770edaef26d09085mdkinney TRUE 227022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ); 22885658066182d23e210209299770edaef26d09085mdkinney } 22985658066182d23e210209299770edaef26d09085mdkinney 23085658066182d23e210209299770edaef26d09085mdkinney // 23185658066182d23e210209299770edaef26d09085mdkinney // Free the handle buffer of ControllerHandle's children 23285658066182d23e210209299770edaef26d09085mdkinney // 23385658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (ChildHandleBuffer); 23485658066182d23e210209299770edaef26d09085mdkinney } 23585658066182d23e210209299770edaef26d09085mdkinney 23628a00297189c323096aae8e2975de94e8549613cyshang return ReturnStatus; 23728a00297189c323096aae8e2975de94e8549613cyshang} 23828a00297189c323096aae8e2975de94e8549613cyshang 239162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 240162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 241162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Add Driver Binding Protocols from Context Driver Image Handles to sorted 242162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Driver Binding Protocol list. 243162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 244022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandle Handle of the driver binding 245022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol. 246022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding 247022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocols 248022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param SortedDriverBindingProtocols The sorted protocol list. 249022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleCount Driver Binding Handle Count. 250022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleBuffer The buffer of driver binding 251022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol to be modified. 252022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param IsImageHandle Indicate whether 253022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBindingHandle is an image 254022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handle 255162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 256162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return None. 257162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 258162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 25928a00297189c323096aae8e2975de94e8549613cyshangVOID 26028a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol ( 26128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverBindingHandle, 262022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN OUT UINTN *NumberOfSortedDriverBindingProtocols, 26328a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, 26428a00297189c323096aae8e2975de94e8549613cyshang IN UINTN DriverBindingHandleCount, 265adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN OUT EFI_HANDLE *DriverBindingHandleBuffer, 266adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN BOOLEAN IsImageHandle 26728a00297189c323096aae8e2975de94e8549613cyshang ) 26828a00297189c323096aae8e2975de94e8549613cyshang{ 26928a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 27028a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 27128a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 27228a00297189c323096aae8e2975de94e8549613cyshang 27328a00297189c323096aae8e2975de94e8549613cyshang // 27428a00297189c323096aae8e2975de94e8549613cyshang // Make sure the DriverBindingHandle is valid 27528a00297189c323096aae8e2975de94e8549613cyshang // 27628a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (DriverBindingHandle); 27728a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 27828a00297189c323096aae8e2975de94e8549613cyshang return; 27928a00297189c323096aae8e2975de94e8549613cyshang } 28028a00297189c323096aae8e2975de94e8549613cyshang 28128a00297189c323096aae8e2975de94e8549613cyshang // 282adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle 283adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list 284adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 285adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (IsImageHandle) { 286adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 287adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Loop through all the Driver Binding Handles 288adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 289adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney for (Index = 0; Index < DriverBindingHandleCount; Index++) { 290adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 291adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle 292adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 293adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 294adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 295adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney &gEfiDriverBindingProtocolGuid, 296e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 297adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 29870279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (EFI_ERROR (Status) || DriverBinding == NULL) { 29970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney continue; 30070279390ba9a0774e020af36120f8b9ba1c217dbmdkinney } 30170279390ba9a0774e020af36120f8b9ba1c217dbmdkinney 302adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 303adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If the ImageHandle associated with DriverBinding matches DriverBindingHandle, 304adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // then add the DriverBindingProtocol[Index] to the sorted list 305adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 306adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (DriverBinding->ImageHandle == DriverBindingHandle) { 307adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney AddSortedDriverBindingProtocol ( 308adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 309022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NumberOfSortedDriverBindingProtocols, 310adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney SortedDriverBindingProtocols, 311adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleCount, 312adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 313adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 314adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 315adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 316adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 317adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney return; 318adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 319adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney 320adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 32128a00297189c323096aae8e2975de94e8549613cyshang // Retrieve the Driver Binding Protocol from DriverBindingHandle 32228a00297189c323096aae8e2975de94e8549613cyshang // 32328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 32428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle, 32528a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 326e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 32728a00297189c323096aae8e2975de94e8549613cyshang ); 32828a00297189c323096aae8e2975de94e8549613cyshang // 32928a00297189c323096aae8e2975de94e8549613cyshang // If DriverBindingHandle does not support the Driver Binding Protocol then return 33028a00297189c323096aae8e2975de94e8549613cyshang // 33128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBinding == NULL) { 33228a00297189c323096aae8e2975de94e8549613cyshang return; 33328a00297189c323096aae8e2975de94e8549613cyshang } 33428a00297189c323096aae8e2975de94e8549613cyshang 33528a00297189c323096aae8e2975de94e8549613cyshang // 33628a00297189c323096aae8e2975de94e8549613cyshang // See if DriverBinding is already in the sorted list 33728a00297189c323096aae8e2975de94e8549613cyshang // 33885658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { 33928a00297189c323096aae8e2975de94e8549613cyshang if (DriverBinding == SortedDriverBindingProtocols[Index]) { 34028a00297189c323096aae8e2975de94e8549613cyshang return; 34128a00297189c323096aae8e2975de94e8549613cyshang } 34228a00297189c323096aae8e2975de94e8549613cyshang } 34328a00297189c323096aae8e2975de94e8549613cyshang 34428a00297189c323096aae8e2975de94e8549613cyshang // 34528a00297189c323096aae8e2975de94e8549613cyshang // Add DriverBinding to the end of the list 34628a00297189c323096aae8e2975de94e8549613cyshang // 34785658066182d23e210209299770edaef26d09085mdkinney if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { 34885658066182d23e210209299770edaef26d09085mdkinney SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; 34985658066182d23e210209299770edaef26d09085mdkinney } 35028a00297189c323096aae8e2975de94e8549613cyshang *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; 35128a00297189c323096aae8e2975de94e8549613cyshang 35228a00297189c323096aae8e2975de94e8549613cyshang // 35328a00297189c323096aae8e2975de94e8549613cyshang // Mark the cooresponding handle in DriverBindingHandleBuffer as used 35428a00297189c323096aae8e2975de94e8549613cyshang // 35528a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 35628a00297189c323096aae8e2975de94e8549613cyshang if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { 35728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index] = NULL; 35828a00297189c323096aae8e2975de94e8549613cyshang } 35928a00297189c323096aae8e2975de94e8549613cyshang } 36028a00297189c323096aae8e2975de94e8549613cyshang} 361022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 362162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 363162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 364162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Connects a controller to a driver. 365162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 366022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle Handle of the controller to be 367022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected. 368022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ContextDriverImageHandles DriverImageHandle A pointer to an 369022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ordered list of driver image 370022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handles. 371022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param RemainingDevicePath RemainingDevicePath A pointer to 372022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the device path that specifies a 373022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child of the controller 374022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang specified by ControllerHandle. 375022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 376022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 377022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected to ControllerHandle. 378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES No enough system resources to 379022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang complete the request. 380022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_NOT_FOUND No drivers were connected to 381162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ControllerHandle. 382162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 383162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 384022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 38528a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 38628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 38728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, 388022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 38928a00297189c323096aae8e2975de94e8549613cyshang ) 39028a00297189c323096aae8e2975de94e8549613cyshang{ 39128a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 39228a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 39328a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverImageHandle; 39428a00297189c323096aae8e2975de94e8549613cyshang EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; 39528a00297189c323096aae8e2975de94e8549613cyshang EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; 39628a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 39728a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 39870279390ba9a0774e020af36120f8b9ba1c217dbmdkinney UINTN NewDriverBindingHandleCount; 39970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney EFI_HANDLE *NewDriverBindingHandleBuffer; 40028a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 401396e9039aec00982e98392a843635c1dcff5364dniruiyu EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride; 40228a00297189c323096aae8e2975de94e8549613cyshang UINTN NumberOfSortedDriverBindingProtocols; 40328a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; 404396e9039aec00982e98392a843635c1dcff5364dniruiyu UINT32 DriverFamilyOverrideVersion; 40528a00297189c323096aae8e2975de94e8549613cyshang UINT32 HighestVersion; 40628a00297189c323096aae8e2975de94e8549613cyshang UINTN HighestIndex; 40728a00297189c323096aae8e2975de94e8549613cyshang UINTN SortIndex; 40828a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN OneStarted; 40928a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverFound; 41028a00297189c323096aae8e2975de94e8549613cyshang 41128a00297189c323096aae8e2975de94e8549613cyshang // 41228a00297189c323096aae8e2975de94e8549613cyshang // Initialize local variables 41328a00297189c323096aae8e2975de94e8549613cyshang // 41428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 41528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 41628a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols = 0; 41728a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = NULL; 41828a00297189c323096aae8e2975de94e8549613cyshang 41928a00297189c323096aae8e2975de94e8549613cyshang // 42028a00297189c323096aae8e2975de94e8549613cyshang // Get list of all Driver Binding Protocol Instances 42128a00297189c323096aae8e2975de94e8549613cyshang // 42228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 423022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 424022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 42528a00297189c323096aae8e2975de94e8549613cyshang NULL, 426022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &DriverBindingHandleCount, 42728a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleBuffer 42828a00297189c323096aae8e2975de94e8549613cyshang ); 42928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) { 43028a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 43128a00297189c323096aae8e2975de94e8549613cyshang } 43228a00297189c323096aae8e2975de94e8549613cyshang 43328a00297189c323096aae8e2975de94e8549613cyshang // 43428a00297189c323096aae8e2975de94e8549613cyshang // Allocate a duplicate array for the sorted Driver Binding Protocol Instances 43528a00297189c323096aae8e2975de94e8549613cyshang // 4369c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount); 43728a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols == NULL) { 43828a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 43928a00297189c323096aae8e2975de94e8549613cyshang return EFI_OUT_OF_RESOURCES; 44028a00297189c323096aae8e2975de94e8549613cyshang } 44128a00297189c323096aae8e2975de94e8549613cyshang 44228a00297189c323096aae8e2975de94e8549613cyshang // 44328a00297189c323096aae8e2975de94e8549613cyshang // Add Driver Binding Protocols from Context Driver Image Handles first 44428a00297189c323096aae8e2975de94e8549613cyshang // 44528a00297189c323096aae8e2975de94e8549613cyshang if (ContextDriverImageHandles != NULL) { 44628a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) { 44728a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 44828a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles[Index], 449022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 45028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 45128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 452adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 453adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 45428a00297189c323096aae8e2975de94e8549613cyshang ); 45528a00297189c323096aae8e2975de94e8549613cyshang } 45628a00297189c323096aae8e2975de94e8549613cyshang } 45728a00297189c323096aae8e2975de94e8549613cyshang 45828a00297189c323096aae8e2975de94e8549613cyshang // 45928a00297189c323096aae8e2975de94e8549613cyshang // Add the Platform Driver Override Protocol drivers for ControllerHandle next 46028a00297189c323096aae8e2975de94e8549613cyshang // 46128a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateProtocol ( 462022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiPlatformDriverOverrideProtocolGuid, 463022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NULL, 464e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &PlatformDriverOverride 46528a00297189c323096aae8e2975de94e8549613cyshang ); 46628a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { 46728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 46828a00297189c323096aae8e2975de94e8549613cyshang do { 46928a00297189c323096aae8e2975de94e8549613cyshang Status = PlatformDriverOverride->GetDriver ( 47028a00297189c323096aae8e2975de94e8549613cyshang PlatformDriverOverride, 47128a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 47228a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 47328a00297189c323096aae8e2975de94e8549613cyshang ); 47428a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 47528a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 47628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 477022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 47828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 47928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 480adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 481adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 48228a00297189c323096aae8e2975de94e8549613cyshang ); 48328a00297189c323096aae8e2975de94e8549613cyshang } 48428a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 48528a00297189c323096aae8e2975de94e8549613cyshang } 48628a00297189c323096aae8e2975de94e8549613cyshang 48728a00297189c323096aae8e2975de94e8549613cyshang // 488396e9039aec00982e98392a843635c1dcff5364dniruiyu // Add the Driver Family Override Protocol drivers for ControllerHandle 489396e9039aec00982e98392a843635c1dcff5364dniruiyu // 490396e9039aec00982e98392a843635c1dcff5364dniruiyu while (TRUE) { 491396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestIndex = DriverBindingHandleCount; 492396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestVersion = 0; 493396e9039aec00982e98392a843635c1dcff5364dniruiyu for (Index = 0; Index < DriverBindingHandleCount; Index++) { 494396e9039aec00982e98392a843635c1dcff5364dniruiyu Status = CoreHandleProtocol ( 495396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer[Index], 496396e9039aec00982e98392a843635c1dcff5364dniruiyu &gEfiDriverFamilyOverrideProtocolGuid, 497396e9039aec00982e98392a843635c1dcff5364dniruiyu (VOID **) &DriverFamilyOverride 498396e9039aec00982e98392a843635c1dcff5364dniruiyu ); 499396e9039aec00982e98392a843635c1dcff5364dniruiyu if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) { 500396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride); 501396e9039aec00982e98392a843635c1dcff5364dniruiyu if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) { 502396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestVersion = DriverFamilyOverrideVersion; 503396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestIndex = Index; 504396e9039aec00982e98392a843635c1dcff5364dniruiyu } 505396e9039aec00982e98392a843635c1dcff5364dniruiyu } 506396e9039aec00982e98392a843635c1dcff5364dniruiyu } 507396e9039aec00982e98392a843635c1dcff5364dniruiyu 508396e9039aec00982e98392a843635c1dcff5364dniruiyu if (HighestIndex == DriverBindingHandleCount) { 509396e9039aec00982e98392a843635c1dcff5364dniruiyu break; 510396e9039aec00982e98392a843635c1dcff5364dniruiyu } 511396e9039aec00982e98392a843635c1dcff5364dniruiyu 512396e9039aec00982e98392a843635c1dcff5364dniruiyu AddSortedDriverBindingProtocol ( 513396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer[HighestIndex], 514396e9039aec00982e98392a843635c1dcff5364dniruiyu &NumberOfSortedDriverBindingProtocols, 515396e9039aec00982e98392a843635c1dcff5364dniruiyu SortedDriverBindingProtocols, 516396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleCount, 517396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer, 518396e9039aec00982e98392a843635c1dcff5364dniruiyu FALSE 519396e9039aec00982e98392a843635c1dcff5364dniruiyu ); 520396e9039aec00982e98392a843635c1dcff5364dniruiyu } 521396e9039aec00982e98392a843635c1dcff5364dniruiyu 522396e9039aec00982e98392a843635c1dcff5364dniruiyu // 52328a00297189c323096aae8e2975de94e8549613cyshang // Get the Bus Specific Driver Override Protocol instance on the Controller Handle 52428a00297189c323096aae8e2975de94e8549613cyshang // 525adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 526022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle, 527022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiBusSpecificDriverOverrideProtocolGuid, 528e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &BusSpecificDriverOverride 52928a00297189c323096aae8e2975de94e8549613cyshang ); 53028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { 53128a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 53228a00297189c323096aae8e2975de94e8549613cyshang do { 53328a00297189c323096aae8e2975de94e8549613cyshang Status = BusSpecificDriverOverride->GetDriver ( 53428a00297189c323096aae8e2975de94e8549613cyshang BusSpecificDriverOverride, 53528a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 53628a00297189c323096aae8e2975de94e8549613cyshang ); 53728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 53828a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 53928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 540022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 54128a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 54228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 543adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 544adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 54528a00297189c323096aae8e2975de94e8549613cyshang ); 54628a00297189c323096aae8e2975de94e8549613cyshang } 54728a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 54828a00297189c323096aae8e2975de94e8549613cyshang } 54928a00297189c323096aae8e2975de94e8549613cyshang 55028a00297189c323096aae8e2975de94e8549613cyshang // 55128a00297189c323096aae8e2975de94e8549613cyshang // Then add all the remaining Driver Binding Protocols 55228a00297189c323096aae8e2975de94e8549613cyshang // 55328a00297189c323096aae8e2975de94e8549613cyshang SortIndex = NumberOfSortedDriverBindingProtocols; 55428a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 55528a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 55628a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 557022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 55828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 55928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 560adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 561adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 56228a00297189c323096aae8e2975de94e8549613cyshang ); 56328a00297189c323096aae8e2975de94e8549613cyshang } 56428a00297189c323096aae8e2975de94e8549613cyshang 56528a00297189c323096aae8e2975de94e8549613cyshang // 56628a00297189c323096aae8e2975de94e8549613cyshang // Free the Driver Binding Handle Buffer 56728a00297189c323096aae8e2975de94e8549613cyshang // 56828a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 56928a00297189c323096aae8e2975de94e8549613cyshang 57028a00297189c323096aae8e2975de94e8549613cyshang // 57185658066182d23e210209299770edaef26d09085mdkinney // If the number of Driver Binding Protocols has increased since this function started, then return 57285658066182d23e210209299770edaef26d09085mdkinney // EFI_NOT_READY, so it will be restarted 57385658066182d23e210209299770edaef26d09085mdkinney // 57470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney Status = CoreLocateHandleBuffer ( 575022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 576022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 57770279390ba9a0774e020af36120f8b9ba1c217dbmdkinney NULL, 578022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NewDriverBindingHandleCount, 57970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney &NewDriverBindingHandleBuffer 58070279390ba9a0774e020af36120f8b9ba1c217dbmdkinney ); 58170279390ba9a0774e020af36120f8b9ba1c217dbmdkinney CoreFreePool (NewDriverBindingHandleBuffer); 58270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (NewDriverBindingHandleCount > DriverBindingHandleCount) { 58385658066182d23e210209299770edaef26d09085mdkinney // 58485658066182d23e210209299770edaef26d09085mdkinney // Free any buffers that were allocated with AllocatePool() 58585658066182d23e210209299770edaef26d09085mdkinney // 58685658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (SortedDriverBindingProtocols); 58785658066182d23e210209299770edaef26d09085mdkinney 58885658066182d23e210209299770edaef26d09085mdkinney return EFI_NOT_READY; 58985658066182d23e210209299770edaef26d09085mdkinney } 59085658066182d23e210209299770edaef26d09085mdkinney 59185658066182d23e210209299770edaef26d09085mdkinney // 59228a00297189c323096aae8e2975de94e8549613cyshang // Sort the remaining DriverBinding Protocol based on their Version field from 59328a00297189c323096aae8e2975de94e8549613cyshang // highest to lowest. 59428a00297189c323096aae8e2975de94e8549613cyshang // 59528a00297189c323096aae8e2975de94e8549613cyshang for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { 59628a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; 59728a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = SortIndex; 59828a00297189c323096aae8e2975de94e8549613cyshang for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { 59928a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { 60028a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[Index]->Version; 60128a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = Index; 60228a00297189c323096aae8e2975de94e8549613cyshang } 60328a00297189c323096aae8e2975de94e8549613cyshang } 60428a00297189c323096aae8e2975de94e8549613cyshang if (SortIndex != HighestIndex) { 60528a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[SortIndex]; 60628a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; 60728a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[HighestIndex] = DriverBinding; 60828a00297189c323096aae8e2975de94e8549613cyshang } 60928a00297189c323096aae8e2975de94e8549613cyshang } 61028a00297189c323096aae8e2975de94e8549613cyshang 61128a00297189c323096aae8e2975de94e8549613cyshang // 61228a00297189c323096aae8e2975de94e8549613cyshang // Loop until no more drivers can be started on ControllerHandle 61328a00297189c323096aae8e2975de94e8549613cyshang // 61428a00297189c323096aae8e2975de94e8549613cyshang OneStarted = FALSE; 61528a00297189c323096aae8e2975de94e8549613cyshang do { 61628a00297189c323096aae8e2975de94e8549613cyshang 61728a00297189c323096aae8e2975de94e8549613cyshang // 61828a00297189c323096aae8e2975de94e8549613cyshang // Loop through the sorted Driver Binding Protocol Instances in order, and see if 619022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // any of the Driver Binding Protocols support the controller specified by 62028a00297189c323096aae8e2975de94e8549613cyshang // ControllerHandle. 62128a00297189c323096aae8e2975de94e8549613cyshang // 62228a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = NULL; 62328a00297189c323096aae8e2975de94e8549613cyshang DriverFound = FALSE; 62428a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { 62528a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index] != NULL) { 62628a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[Index]; 627bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_START (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); 62828a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Supported( 629022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 63028a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 63128a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 63228a00297189c323096aae8e2975de94e8549613cyshang ); 633bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_END (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); 63428a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 63528a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[Index] = NULL; 63628a00297189c323096aae8e2975de94e8549613cyshang DriverFound = TRUE; 63728a00297189c323096aae8e2975de94e8549613cyshang 63828a00297189c323096aae8e2975de94e8549613cyshang // 63928a00297189c323096aae8e2975de94e8549613cyshang // A driver was found that supports ControllerHandle, so attempt to start the driver 64028a00297189c323096aae8e2975de94e8549613cyshang // on ControllerHandle. 64128a00297189c323096aae8e2975de94e8549613cyshang // 642bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_START (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); 64328a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Start ( 644022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 64528a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 64628a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 64728a00297189c323096aae8e2975de94e8549613cyshang ); 648bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_END (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); 64928a00297189c323096aae8e2975de94e8549613cyshang 65028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 65128a00297189c323096aae8e2975de94e8549613cyshang // 65228a00297189c323096aae8e2975de94e8549613cyshang // The driver was successfully started on ControllerHandle, so set a flag 65328a00297189c323096aae8e2975de94e8549613cyshang // 65428a00297189c323096aae8e2975de94e8549613cyshang OneStarted = TRUE; 65528a00297189c323096aae8e2975de94e8549613cyshang } 65628a00297189c323096aae8e2975de94e8549613cyshang } 65728a00297189c323096aae8e2975de94e8549613cyshang } 65828a00297189c323096aae8e2975de94e8549613cyshang } 65928a00297189c323096aae8e2975de94e8549613cyshang } while (DriverFound); 66028a00297189c323096aae8e2975de94e8549613cyshang 66128a00297189c323096aae8e2975de94e8549613cyshang // 66228a00297189c323096aae8e2975de94e8549613cyshang // Free any buffers that were allocated with AllocatePool() 66328a00297189c323096aae8e2975de94e8549613cyshang // 66428a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (SortedDriverBindingProtocols); 66528a00297189c323096aae8e2975de94e8549613cyshang 66628a00297189c323096aae8e2975de94e8549613cyshang // 66728a00297189c323096aae8e2975de94e8549613cyshang // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. 66828a00297189c323096aae8e2975de94e8549613cyshang // 66928a00297189c323096aae8e2975de94e8549613cyshang if (OneStarted) { 67028a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 671022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 67228a00297189c323096aae8e2975de94e8549613cyshang 67328a00297189c323096aae8e2975de94e8549613cyshang // 67428a00297189c323096aae8e2975de94e8549613cyshang // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS 67528a00297189c323096aae8e2975de94e8549613cyshang // 67628a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 67728a00297189c323096aae8e2975de94e8549613cyshang if (IsDevicePathEnd (RemainingDevicePath)) { 67828a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 67928a00297189c323096aae8e2975de94e8549613cyshang } 680022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 68128a00297189c323096aae8e2975de94e8549613cyshang 68228a00297189c323096aae8e2975de94e8549613cyshang // 68328a00297189c323096aae8e2975de94e8549613cyshang // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND 68428a00297189c323096aae8e2975de94e8549613cyshang // 68528a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 68628a00297189c323096aae8e2975de94e8549613cyshang} 68728a00297189c323096aae8e2975de94e8549613cyshang 68828a00297189c323096aae8e2975de94e8549613cyshang 689162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 690162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 691162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Disonnects a controller from a driver 692162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 693022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle ControllerHandle The handle of 694022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the controller from which 695022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang driver(s) are to be 696022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected. 697022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverImageHandle DriverImageHandle The driver to 698022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnect from ControllerHandle. 699022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ChildHandle ChildHandle The handle of the 700022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child to destroy. 701022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 702022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 703022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected from the controller. 704022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS On entry, no drivers are managing 705022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle. 706022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS DriverImageHandle is not NULL, 707022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and on entry DriverImageHandle is 708022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang not managing ControllerHandle. 709284ee2e829ab2453293b7dc4539727ad6c047163niruiyu @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. 710022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, 711022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and it is not a valid EFI_HANDLE. 712022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it 713022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang is not a valid EFI_HANDLE. 714022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES There are not enough resources 715022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang available to disconnect any 716022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang drivers from ControllerHandle. 717022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_DEVICE_ERROR The controller could not be 718022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected because of a device 719162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang error. 720162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 721162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 722022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 72328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 72428a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController ( 72528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 72628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverImageHandle OPTIONAL, 72728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ChildHandle OPTIONAL 72828a00297189c323096aae8e2975de94e8549613cyshang ) 72928a00297189c323096aae8e2975de94e8549613cyshang{ 73028a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 73128a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 73228a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverImageHandleBuffer; 73328a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *ChildBuffer; 73428a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 73528a00297189c323096aae8e2975de94e8549613cyshang UINTN HandleIndex; 73628a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverImageHandleCount; 73728a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildrenToStop; 73828a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildBufferCount; 73928a00297189c323096aae8e2975de94e8549613cyshang UINTN StopCount; 74028a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Duplicate; 74128a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ChildHandleValid; 74228a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverImageHandleValid; 74328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 74428a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 74528a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 74628a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 74728a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 74828a00297189c323096aae8e2975de94e8549613cyshang 74928a00297189c323096aae8e2975de94e8549613cyshang // 75028a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 75128a00297189c323096aae8e2975de94e8549613cyshang // 75228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 75328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 75428a00297189c323096aae8e2975de94e8549613cyshang return Status; 75528a00297189c323096aae8e2975de94e8549613cyshang } 75628a00297189c323096aae8e2975de94e8549613cyshang 75728a00297189c323096aae8e2975de94e8549613cyshang // 75828a00297189c323096aae8e2975de94e8549613cyshang // Make sure ChildHandle is valid if it is not NULL 75928a00297189c323096aae8e2975de94e8549613cyshang // 76028a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 76128a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ChildHandle); 76228a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 76328a00297189c323096aae8e2975de94e8549613cyshang return Status; 76428a00297189c323096aae8e2975de94e8549613cyshang } 76528a00297189c323096aae8e2975de94e8549613cyshang } 76628a00297189c323096aae8e2975de94e8549613cyshang 76728a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 76828a00297189c323096aae8e2975de94e8549613cyshang 76928a00297189c323096aae8e2975de94e8549613cyshang // 77028a00297189c323096aae8e2975de94e8549613cyshang // Get list of drivers that are currently managing ControllerHandle 77128a00297189c323096aae8e2975de94e8549613cyshang // 77228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = NULL; 773022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandleCount = 1; 774022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 77528a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandle == NULL) { 77628a00297189c323096aae8e2975de94e8549613cyshang // 77728a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 77828a00297189c323096aae8e2975de94e8549613cyshang // 77928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 78028a00297189c323096aae8e2975de94e8549613cyshang 78128a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 78228a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 78328a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 784022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 785022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 78628a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 78728a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 78828a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 78928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 79028a00297189c323096aae8e2975de94e8549613cyshang } 79128a00297189c323096aae8e2975de94e8549613cyshang } 79228a00297189c323096aae8e2975de94e8549613cyshang } 79328a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 794022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 79528a00297189c323096aae8e2975de94e8549613cyshang // 79628a00297189c323096aae8e2975de94e8549613cyshang // If there are no drivers managing this controller, then return EFI_SUCCESS 79728a00297189c323096aae8e2975de94e8549613cyshang // 79828a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleCount == 0) { 79928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 80028a00297189c323096aae8e2975de94e8549613cyshang goto Done; 80128a00297189c323096aae8e2975de94e8549613cyshang } 80228a00297189c323096aae8e2975de94e8549613cyshang 8039c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount); 80428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer == NULL) { 80528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 80628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 80728a00297189c323096aae8e2975de94e8549613cyshang } 80828a00297189c323096aae8e2975de94e8549613cyshang 80928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 81028a00297189c323096aae8e2975de94e8549613cyshang 81128a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 81228a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 81328a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 814022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 815022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 81628a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 81728a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 81828a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 81928a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 82028a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index< DriverImageHandleCount; Index++) { 82128a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { 82228a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 82328a00297189c323096aae8e2975de94e8549613cyshang break; 82428a00297189c323096aae8e2975de94e8549613cyshang } 82528a00297189c323096aae8e2975de94e8549613cyshang } 82628a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 82728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; 82828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 82928a00297189c323096aae8e2975de94e8549613cyshang } 83028a00297189c323096aae8e2975de94e8549613cyshang } 83128a00297189c323096aae8e2975de94e8549613cyshang } 83228a00297189c323096aae8e2975de94e8549613cyshang } 83328a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 83428a00297189c323096aae8e2975de94e8549613cyshang } 83528a00297189c323096aae8e2975de94e8549613cyshang 83628a00297189c323096aae8e2975de94e8549613cyshang StopCount = 0; 83728a00297189c323096aae8e2975de94e8549613cyshang for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { 83828a00297189c323096aae8e2975de94e8549613cyshang 83928a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 84028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; 84128a00297189c323096aae8e2975de94e8549613cyshang } 84228a00297189c323096aae8e2975de94e8549613cyshang 84328a00297189c323096aae8e2975de94e8549613cyshang // 84428a00297189c323096aae8e2975de94e8549613cyshang // Get the Driver Binding Protocol of the driver that is managing this controller 84528a00297189c323096aae8e2975de94e8549613cyshang // 84628a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol ( 847022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandle, 848022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 84928a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 85028a00297189c323096aae8e2975de94e8549613cyshang ); 851d2fbaaab17945b59ca66bcd2f72e26ba3361e1d0rsun if (EFI_ERROR (Status) || DriverBinding == NULL) { 85228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 85328a00297189c323096aae8e2975de94e8549613cyshang goto Done; 85428a00297189c323096aae8e2975de94e8549613cyshang } 85528a00297189c323096aae8e2975de94e8549613cyshang 85628a00297189c323096aae8e2975de94e8549613cyshang // 85728a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 85828a00297189c323096aae8e2975de94e8549613cyshang // 85928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = FALSE; 86028a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 86128a00297189c323096aae8e2975de94e8549613cyshang 86228a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 86328a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 86428a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 865022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 866022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 86728a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 86828a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 86928a00297189c323096aae8e2975de94e8549613cyshang if (OpenData->AgentHandle == DriverImageHandle) { 87028a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 87128a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 872022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 87328a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 87428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = TRUE; 87528a00297189c323096aae8e2975de94e8549613cyshang } 87628a00297189c323096aae8e2975de94e8549613cyshang } 87728a00297189c323096aae8e2975de94e8549613cyshang } 87828a00297189c323096aae8e2975de94e8549613cyshang } 87928a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 88028a00297189c323096aae8e2975de94e8549613cyshang 88128a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleValid) { 88228a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = FALSE; 88328a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = NULL; 88428a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount != 0) { 8859c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount); 88628a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer == NULL) { 88728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 88828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 88928a00297189c323096aae8e2975de94e8549613cyshang } 89028a00297189c323096aae8e2975de94e8549613cyshang 89128a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 89228a00297189c323096aae8e2975de94e8549613cyshang 89328a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 89428a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 89528a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 896022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 897022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 89828a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 89928a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 90028a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == DriverImageHandle) && 90128a00297189c323096aae8e2975de94e8549613cyshang ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { 90228a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 90328a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < ChildBufferCount; Index++) { 90428a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer[Index] == OpenData->ControllerHandle) { 90528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 90628a00297189c323096aae8e2975de94e8549613cyshang break; 90728a00297189c323096aae8e2975de94e8549613cyshang } 90828a00297189c323096aae8e2975de94e8549613cyshang } 90928a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 91028a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; 91128a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == ChildBuffer[ChildBufferCount]) { 91228a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = TRUE; 91328a00297189c323096aae8e2975de94e8549613cyshang } 91428a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 91528a00297189c323096aae8e2975de94e8549613cyshang } 91628a00297189c323096aae8e2975de94e8549613cyshang } 91728a00297189c323096aae8e2975de94e8549613cyshang } 91828a00297189c323096aae8e2975de94e8549613cyshang } 91928a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 92028a00297189c323096aae8e2975de94e8549613cyshang } 92128a00297189c323096aae8e2975de94e8549613cyshang 92228a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == NULL || ChildHandleValid) { 92328a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 0; 92428a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 92528a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount > 0) { 92628a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 92728a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 1; 92828a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); 92928a00297189c323096aae8e2975de94e8549613cyshang } else { 93028a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = ChildBufferCount; 93128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); 93228a00297189c323096aae8e2975de94e8549613cyshang } 93328a00297189c323096aae8e2975de94e8549613cyshang } 93428a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { 93528a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); 93628a00297189c323096aae8e2975de94e8549613cyshang } 93728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 93828a00297189c323096aae8e2975de94e8549613cyshang StopCount++; 93928a00297189c323096aae8e2975de94e8549613cyshang } 94028a00297189c323096aae8e2975de94e8549613cyshang } 94128a00297189c323096aae8e2975de94e8549613cyshang 94228a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer != NULL) { 94328a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (ChildBuffer); 94428a00297189c323096aae8e2975de94e8549613cyshang } 94528a00297189c323096aae8e2975de94e8549613cyshang } 94628a00297189c323096aae8e2975de94e8549613cyshang } 94728a00297189c323096aae8e2975de94e8549613cyshang 94828a00297189c323096aae8e2975de94e8549613cyshang if (StopCount > 0) { 94928a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 95028a00297189c323096aae8e2975de94e8549613cyshang } else { 95128a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 95228a00297189c323096aae8e2975de94e8549613cyshang } 953022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 954022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangDone: 95528a00297189c323096aae8e2975de94e8549613cyshang 95628a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 95728a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverImageHandleBuffer); 95828a00297189c323096aae8e2975de94e8549613cyshang } 95928a00297189c323096aae8e2975de94e8549613cyshang 96028a00297189c323096aae8e2975de94e8549613cyshang return Status; 96128a00297189c323096aae8e2975de94e8549613cyshang} 962