123c98c9417908188207408afa3f6901b8aca826aqhuang/** @file 2504214c4870e9183418014634268ce630eb5332algao Support functions to connect/disconnect UEFI Driver model Protocol 3504214c4870e9183418014634268ce630eb5332algao 45fef1a3492fd2bced485ff6845914d5681067f52Eric DongCopyright (c) 2006 - 2014, 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)) { 885fef1a3492fd2bced485ff6845914d5681067f52Eric Dong ASSERT (HandleFilePath != NULL); 89bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath = HandleFilePath; 90bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao TempFilePath = NULL; 91bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (RemainingDevicePath != NULL && !Recursive) { 92bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao HandleFilePathSize = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); 93bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath); 94bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao TempFilePath = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize); 95bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao ASSERT (TempFilePath != NULL); 96bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize); 97bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao CopyMem ((UINT8 *) TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize); 98bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath = TempFilePath; 99bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 100bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao Status = gSecurity2->FileAuthentication ( 101bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao gSecurity2, 102bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FilePath, 103bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao NULL, 104bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 0, 105bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FALSE 106bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao ); 107bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (TempFilePath != NULL) { 108bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao FreePool (TempFilePath); 109bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 110bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao if (EFI_ERROR (Status)) { 111bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao return Status; 112bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 113bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 114bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao } 115bc2dfdbcfc11dc785f0cc0ad2f519a63b98f88bclgao 11628a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 11728a00297189c323096aae8e2975de94e8549613cyshang 11828a00297189c323096aae8e2975de94e8549613cyshang // 11985658066182d23e210209299770edaef26d09085mdkinney // Make a copy of RemainingDevicePath to guanatee it is aligned 12028a00297189c323096aae8e2975de94e8549613cyshang // 12128a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = NULL; 12228a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 1239c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath); 1246c857d668cb7d2b219351be1daeec0bcd597e377qwang 1256c857d668cb7d2b219351be1daeec0bcd597e377qwang if (AlignedRemainingDevicePath == NULL) { 1266c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 1276c857d668cb7d2b219351be1daeec0bcd597e377qwang } 12828a00297189c323096aae8e2975de94e8549613cyshang } 12928a00297189c323096aae8e2975de94e8549613cyshang 13028a00297189c323096aae8e2975de94e8549613cyshang // 13185658066182d23e210209299770edaef26d09085mdkinney // Connect all drivers to ControllerHandle 13285658066182d23e210209299770edaef26d09085mdkinney // If CoreConnectSingleController returns EFI_NOT_READY, then the number of 13385658066182d23e210209299770edaef26d09085mdkinney // Driver Binding Protocols in the handle database has increased during the call 13485658066182d23e210209299770edaef26d09085mdkinney // so the connect operation must be restarted 13528a00297189c323096aae8e2975de94e8549613cyshang // 13685658066182d23e210209299770edaef26d09085mdkinney do { 13785658066182d23e210209299770edaef26d09085mdkinney ReturnStatus = CoreConnectSingleController ( 138e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ControllerHandle, 139e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang DriverImageHandle, 140e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang AlignedRemainingDevicePath 141e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang ); 14285658066182d23e210209299770edaef26d09085mdkinney } while (ReturnStatus == EFI_NOT_READY); 14385658066182d23e210209299770edaef26d09085mdkinney 14485658066182d23e210209299770edaef26d09085mdkinney // 14585658066182d23e210209299770edaef26d09085mdkinney // Free the aligned copy of RemainingDevicePath 14685658066182d23e210209299770edaef26d09085mdkinney // 14785658066182d23e210209299770edaef26d09085mdkinney if (AlignedRemainingDevicePath != NULL) { 14885658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (AlignedRemainingDevicePath); 14928a00297189c323096aae8e2975de94e8549613cyshang } 15028a00297189c323096aae8e2975de94e8549613cyshang 15128a00297189c323096aae8e2975de94e8549613cyshang // 15228a00297189c323096aae8e2975de94e8549613cyshang // If recursive, then connect all drivers to all of ControllerHandle's children 15328a00297189c323096aae8e2975de94e8549613cyshang // 15485658066182d23e210209299770edaef26d09085mdkinney if (Recursive) { 15585658066182d23e210209299770edaef26d09085mdkinney // 15685658066182d23e210209299770edaef26d09085mdkinney // Acquire the protocol lock on the handle database so the child handles can be collected 15785658066182d23e210209299770edaef26d09085mdkinney // 15885658066182d23e210209299770edaef26d09085mdkinney CoreAcquireProtocolLock (); 15985658066182d23e210209299770edaef26d09085mdkinney 16085658066182d23e210209299770edaef26d09085mdkinney // 16185658066182d23e210209299770edaef26d09085mdkinney // Make sure the DriverBindingHandle is valid 16285658066182d23e210209299770edaef26d09085mdkinney // 16385658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (ControllerHandle); 16485658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 16585658066182d23e210209299770edaef26d09085mdkinney // 16685658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 16785658066182d23e210209299770edaef26d09085mdkinney // 16885658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 16985658066182d23e210209299770edaef26d09085mdkinney 17085658066182d23e210209299770edaef26d09085mdkinney return ReturnStatus; 17185658066182d23e210209299770edaef26d09085mdkinney } 17285658066182d23e210209299770edaef26d09085mdkinney 17385658066182d23e210209299770edaef26d09085mdkinney 17485658066182d23e210209299770edaef26d09085mdkinney // 17585658066182d23e210209299770edaef26d09085mdkinney // Count ControllerHandle's children 17685658066182d23e210209299770edaef26d09085mdkinney // 17785658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 17885658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 179022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 180022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 18185658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 18285658066182d23e210209299770edaef26d09085mdkinney OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 18385658066182d23e210209299770edaef26d09085mdkinney if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 18485658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 18585658066182d23e210209299770edaef26d09085mdkinney } 18685658066182d23e210209299770edaef26d09085mdkinney } 18785658066182d23e210209299770edaef26d09085mdkinney } 18885658066182d23e210209299770edaef26d09085mdkinney 18985658066182d23e210209299770edaef26d09085mdkinney // 19085658066182d23e210209299770edaef26d09085mdkinney // Allocate a handle buffer for ControllerHandle's children 19185658066182d23e210209299770edaef26d09085mdkinney // 1929c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof(EFI_HANDLE)); 1936c857d668cb7d2b219351be1daeec0bcd597e377qwang if (ChildHandleBuffer == NULL) { 194fa3c419fec30282afb85a788cb71e12fd1a51804qwang CoreReleaseProtocolLock (); 1956c857d668cb7d2b219351be1daeec0bcd597e377qwang return EFI_OUT_OF_RESOURCES; 1966c857d668cb7d2b219351be1daeec0bcd597e377qwang } 19785658066182d23e210209299770edaef26d09085mdkinney 19885658066182d23e210209299770edaef26d09085mdkinney // 19985658066182d23e210209299770edaef26d09085mdkinney // Fill in a handle buffer with ControllerHandle's children 20085658066182d23e210209299770edaef26d09085mdkinney // 20185658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 20285658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 203022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 204022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 20585658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 20628a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 20728a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 20885658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; 20985658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 21085658066182d23e210209299770edaef26d09085mdkinney } 21185658066182d23e210209299770edaef26d09085mdkinney } 21285658066182d23e210209299770edaef26d09085mdkinney } 21385658066182d23e210209299770edaef26d09085mdkinney 21485658066182d23e210209299770edaef26d09085mdkinney // 21585658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 21685658066182d23e210209299770edaef26d09085mdkinney // 21785658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 21885658066182d23e210209299770edaef26d09085mdkinney 21985658066182d23e210209299770edaef26d09085mdkinney // 22085658066182d23e210209299770edaef26d09085mdkinney // Recursively connect each child handle 22185658066182d23e210209299770edaef26d09085mdkinney // 22285658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < ChildHandleCount; Index++) { 22385658066182d23e210209299770edaef26d09085mdkinney CoreConnectController ( 22485658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[Index], 22585658066182d23e210209299770edaef26d09085mdkinney NULL, 22685658066182d23e210209299770edaef26d09085mdkinney NULL, 22785658066182d23e210209299770edaef26d09085mdkinney TRUE 228022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ); 22985658066182d23e210209299770edaef26d09085mdkinney } 23085658066182d23e210209299770edaef26d09085mdkinney 23185658066182d23e210209299770edaef26d09085mdkinney // 23285658066182d23e210209299770edaef26d09085mdkinney // Free the handle buffer of ControllerHandle's children 23385658066182d23e210209299770edaef26d09085mdkinney // 23485658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (ChildHandleBuffer); 23585658066182d23e210209299770edaef26d09085mdkinney } 23685658066182d23e210209299770edaef26d09085mdkinney 23728a00297189c323096aae8e2975de94e8549613cyshang return ReturnStatus; 23828a00297189c323096aae8e2975de94e8549613cyshang} 23928a00297189c323096aae8e2975de94e8549613cyshang 240162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 241162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 242162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Add Driver Binding Protocols from Context Driver Image Handles to sorted 243162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Driver Binding Protocol list. 244162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 245022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandle Handle of the driver binding 246022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol. 247022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param NumberOfSortedDriverBindingProtocols Number Of sorted driver binding 248022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocols 249022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param SortedDriverBindingProtocols The sorted protocol list. 250022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleCount Driver Binding Handle Count. 251022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverBindingHandleBuffer The buffer of driver binding 252022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang protocol to be modified. 253022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param IsImageHandle Indicate whether 254022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBindingHandle is an image 255022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handle 256162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 257162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang @return None. 258162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 259162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 26028a00297189c323096aae8e2975de94e8549613cyshangVOID 26128a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol ( 26228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverBindingHandle, 263022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN OUT UINTN *NumberOfSortedDriverBindingProtocols, 26428a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, 26528a00297189c323096aae8e2975de94e8549613cyshang IN UINTN DriverBindingHandleCount, 266adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN OUT EFI_HANDLE *DriverBindingHandleBuffer, 267adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN BOOLEAN IsImageHandle 26828a00297189c323096aae8e2975de94e8549613cyshang ) 26928a00297189c323096aae8e2975de94e8549613cyshang{ 27028a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 27128a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 27228a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 27328a00297189c323096aae8e2975de94e8549613cyshang 27428a00297189c323096aae8e2975de94e8549613cyshang // 27528a00297189c323096aae8e2975de94e8549613cyshang // Make sure the DriverBindingHandle is valid 27628a00297189c323096aae8e2975de94e8549613cyshang // 27728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (DriverBindingHandle); 27828a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 27928a00297189c323096aae8e2975de94e8549613cyshang return; 28028a00297189c323096aae8e2975de94e8549613cyshang } 28128a00297189c323096aae8e2975de94e8549613cyshang 28228a00297189c323096aae8e2975de94e8549613cyshang // 283adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle 284adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list 285adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 286adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (IsImageHandle) { 287adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 288adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Loop through all the Driver Binding Handles 289adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 290adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney for (Index = 0; Index < DriverBindingHandleCount; Index++) { 291adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 292adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle 293adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 294adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 295adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 296adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney &gEfiDriverBindingProtocolGuid, 297e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 298adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 29970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (EFI_ERROR (Status) || DriverBinding == NULL) { 30070279390ba9a0774e020af36120f8b9ba1c217dbmdkinney continue; 30170279390ba9a0774e020af36120f8b9ba1c217dbmdkinney } 30270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney 303adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 304adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If the ImageHandle associated with DriverBinding matches DriverBindingHandle, 305adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // then add the DriverBindingProtocol[Index] to the sorted list 306adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 307adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (DriverBinding->ImageHandle == DriverBindingHandle) { 308adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney AddSortedDriverBindingProtocol ( 309adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 310022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NumberOfSortedDriverBindingProtocols, 311adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney SortedDriverBindingProtocols, 312adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleCount, 313adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 314adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 315adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 316adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 317adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 318adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney return; 319adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 320adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney 321adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 32228a00297189c323096aae8e2975de94e8549613cyshang // Retrieve the Driver Binding Protocol from DriverBindingHandle 32328a00297189c323096aae8e2975de94e8549613cyshang // 32428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 32528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle, 32628a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 327e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &DriverBinding 32828a00297189c323096aae8e2975de94e8549613cyshang ); 32928a00297189c323096aae8e2975de94e8549613cyshang // 33028a00297189c323096aae8e2975de94e8549613cyshang // If DriverBindingHandle does not support the Driver Binding Protocol then return 33128a00297189c323096aae8e2975de94e8549613cyshang // 33228a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBinding == NULL) { 33328a00297189c323096aae8e2975de94e8549613cyshang return; 33428a00297189c323096aae8e2975de94e8549613cyshang } 33528a00297189c323096aae8e2975de94e8549613cyshang 33628a00297189c323096aae8e2975de94e8549613cyshang // 33728a00297189c323096aae8e2975de94e8549613cyshang // See if DriverBinding is already in the sorted list 33828a00297189c323096aae8e2975de94e8549613cyshang // 33985658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { 34028a00297189c323096aae8e2975de94e8549613cyshang if (DriverBinding == SortedDriverBindingProtocols[Index]) { 34128a00297189c323096aae8e2975de94e8549613cyshang return; 34228a00297189c323096aae8e2975de94e8549613cyshang } 34328a00297189c323096aae8e2975de94e8549613cyshang } 34428a00297189c323096aae8e2975de94e8549613cyshang 34528a00297189c323096aae8e2975de94e8549613cyshang // 34628a00297189c323096aae8e2975de94e8549613cyshang // Add DriverBinding to the end of the list 34728a00297189c323096aae8e2975de94e8549613cyshang // 34885658066182d23e210209299770edaef26d09085mdkinney if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { 34985658066182d23e210209299770edaef26d09085mdkinney SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; 35085658066182d23e210209299770edaef26d09085mdkinney } 35128a00297189c323096aae8e2975de94e8549613cyshang *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; 35228a00297189c323096aae8e2975de94e8549613cyshang 35328a00297189c323096aae8e2975de94e8549613cyshang // 35428a00297189c323096aae8e2975de94e8549613cyshang // Mark the cooresponding handle in DriverBindingHandleBuffer as used 35528a00297189c323096aae8e2975de94e8549613cyshang // 35628a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 35728a00297189c323096aae8e2975de94e8549613cyshang if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { 35828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index] = NULL; 35928a00297189c323096aae8e2975de94e8549613cyshang } 36028a00297189c323096aae8e2975de94e8549613cyshang } 36128a00297189c323096aae8e2975de94e8549613cyshang} 362022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 363162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 364162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 365162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Connects a controller to a driver. 366162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 367022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle Handle of the controller to be 368022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected. 369022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ContextDriverImageHandles DriverImageHandle A pointer to an 370022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ordered list of driver image 371022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang handles. 372022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param RemainingDevicePath RemainingDevicePath A pointer to 373022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the device path that specifies a 374022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child of the controller 375022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang specified by ControllerHandle. 376022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 377022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 378022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang connected to ControllerHandle. 379022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES No enough system resources to 380022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang complete the request. 381022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_NOT_FOUND No drivers were connected to 382162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang ControllerHandle. 383162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 384162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 385022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 38628a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 38728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 38828a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, 389022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 39028a00297189c323096aae8e2975de94e8549613cyshang ) 39128a00297189c323096aae8e2975de94e8549613cyshang{ 39228a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 39328a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 39428a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverImageHandle; 39528a00297189c323096aae8e2975de94e8549613cyshang EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; 39628a00297189c323096aae8e2975de94e8549613cyshang EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; 39728a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 39828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 39970279390ba9a0774e020af36120f8b9ba1c217dbmdkinney UINTN NewDriverBindingHandleCount; 40070279390ba9a0774e020af36120f8b9ba1c217dbmdkinney EFI_HANDLE *NewDriverBindingHandleBuffer; 40128a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 402396e9039aec00982e98392a843635c1dcff5364dniruiyu EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL *DriverFamilyOverride; 40328a00297189c323096aae8e2975de94e8549613cyshang UINTN NumberOfSortedDriverBindingProtocols; 40428a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; 405396e9039aec00982e98392a843635c1dcff5364dniruiyu UINT32 DriverFamilyOverrideVersion; 40628a00297189c323096aae8e2975de94e8549613cyshang UINT32 HighestVersion; 40728a00297189c323096aae8e2975de94e8549613cyshang UINTN HighestIndex; 40828a00297189c323096aae8e2975de94e8549613cyshang UINTN SortIndex; 40928a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN OneStarted; 41028a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverFound; 41128a00297189c323096aae8e2975de94e8549613cyshang 41228a00297189c323096aae8e2975de94e8549613cyshang // 41328a00297189c323096aae8e2975de94e8549613cyshang // Initialize local variables 41428a00297189c323096aae8e2975de94e8549613cyshang // 41528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 41628a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 41728a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols = 0; 41828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = NULL; 4194e1005eca7186cbe61aaae09108f6fdf29959f22Eric Dong PlatformDriverOverride = NULL; 4204e1005eca7186cbe61aaae09108f6fdf29959f22Eric Dong NewDriverBindingHandleBuffer = NULL; 42128a00297189c323096aae8e2975de94e8549613cyshang 42228a00297189c323096aae8e2975de94e8549613cyshang // 42328a00297189c323096aae8e2975de94e8549613cyshang // Get list of all Driver Binding Protocol Instances 42428a00297189c323096aae8e2975de94e8549613cyshang // 42528a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 426022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 427022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 42828a00297189c323096aae8e2975de94e8549613cyshang NULL, 429022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &DriverBindingHandleCount, 43028a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleBuffer 43128a00297189c323096aae8e2975de94e8549613cyshang ); 43228a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) { 43328a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 43428a00297189c323096aae8e2975de94e8549613cyshang } 43528a00297189c323096aae8e2975de94e8549613cyshang 43628a00297189c323096aae8e2975de94e8549613cyshang // 43728a00297189c323096aae8e2975de94e8549613cyshang // Allocate a duplicate array for the sorted Driver Binding Protocol Instances 43828a00297189c323096aae8e2975de94e8549613cyshang // 4399c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount); 44028a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols == NULL) { 44128a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 44228a00297189c323096aae8e2975de94e8549613cyshang return EFI_OUT_OF_RESOURCES; 44328a00297189c323096aae8e2975de94e8549613cyshang } 44428a00297189c323096aae8e2975de94e8549613cyshang 44528a00297189c323096aae8e2975de94e8549613cyshang // 44628a00297189c323096aae8e2975de94e8549613cyshang // Add Driver Binding Protocols from Context Driver Image Handles first 44728a00297189c323096aae8e2975de94e8549613cyshang // 44828a00297189c323096aae8e2975de94e8549613cyshang if (ContextDriverImageHandles != NULL) { 44928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) { 45028a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 45128a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles[Index], 452022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 45328a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 45428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 455adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 456adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 45728a00297189c323096aae8e2975de94e8549613cyshang ); 45828a00297189c323096aae8e2975de94e8549613cyshang } 45928a00297189c323096aae8e2975de94e8549613cyshang } 46028a00297189c323096aae8e2975de94e8549613cyshang 46128a00297189c323096aae8e2975de94e8549613cyshang // 46228a00297189c323096aae8e2975de94e8549613cyshang // Add the Platform Driver Override Protocol drivers for ControllerHandle next 46328a00297189c323096aae8e2975de94e8549613cyshang // 46428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateProtocol ( 465022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiPlatformDriverOverrideProtocolGuid, 466022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang NULL, 467e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &PlatformDriverOverride 46828a00297189c323096aae8e2975de94e8549613cyshang ); 46928a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { 47028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 47128a00297189c323096aae8e2975de94e8549613cyshang do { 47228a00297189c323096aae8e2975de94e8549613cyshang Status = PlatformDriverOverride->GetDriver ( 47328a00297189c323096aae8e2975de94e8549613cyshang PlatformDriverOverride, 47428a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 47528a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 47628a00297189c323096aae8e2975de94e8549613cyshang ); 47728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 47828a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 47928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 480022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 48128a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 48228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 483adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 484adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 48528a00297189c323096aae8e2975de94e8549613cyshang ); 48628a00297189c323096aae8e2975de94e8549613cyshang } 48728a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 48828a00297189c323096aae8e2975de94e8549613cyshang } 48928a00297189c323096aae8e2975de94e8549613cyshang 49028a00297189c323096aae8e2975de94e8549613cyshang // 491396e9039aec00982e98392a843635c1dcff5364dniruiyu // Add the Driver Family Override Protocol drivers for ControllerHandle 492396e9039aec00982e98392a843635c1dcff5364dniruiyu // 493396e9039aec00982e98392a843635c1dcff5364dniruiyu while (TRUE) { 494396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestIndex = DriverBindingHandleCount; 495396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestVersion = 0; 496396e9039aec00982e98392a843635c1dcff5364dniruiyu for (Index = 0; Index < DriverBindingHandleCount; Index++) { 497396e9039aec00982e98392a843635c1dcff5364dniruiyu Status = CoreHandleProtocol ( 498396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer[Index], 499396e9039aec00982e98392a843635c1dcff5364dniruiyu &gEfiDriverFamilyOverrideProtocolGuid, 500396e9039aec00982e98392a843635c1dcff5364dniruiyu (VOID **) &DriverFamilyOverride 501396e9039aec00982e98392a843635c1dcff5364dniruiyu ); 502396e9039aec00982e98392a843635c1dcff5364dniruiyu if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) { 503396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride); 504396e9039aec00982e98392a843635c1dcff5364dniruiyu if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) { 505396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestVersion = DriverFamilyOverrideVersion; 506396e9039aec00982e98392a843635c1dcff5364dniruiyu HighestIndex = Index; 507396e9039aec00982e98392a843635c1dcff5364dniruiyu } 508396e9039aec00982e98392a843635c1dcff5364dniruiyu } 509396e9039aec00982e98392a843635c1dcff5364dniruiyu } 510396e9039aec00982e98392a843635c1dcff5364dniruiyu 511396e9039aec00982e98392a843635c1dcff5364dniruiyu if (HighestIndex == DriverBindingHandleCount) { 512396e9039aec00982e98392a843635c1dcff5364dniruiyu break; 513396e9039aec00982e98392a843635c1dcff5364dniruiyu } 514396e9039aec00982e98392a843635c1dcff5364dniruiyu 515396e9039aec00982e98392a843635c1dcff5364dniruiyu AddSortedDriverBindingProtocol ( 516396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer[HighestIndex], 517396e9039aec00982e98392a843635c1dcff5364dniruiyu &NumberOfSortedDriverBindingProtocols, 518396e9039aec00982e98392a843635c1dcff5364dniruiyu SortedDriverBindingProtocols, 519396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleCount, 520396e9039aec00982e98392a843635c1dcff5364dniruiyu DriverBindingHandleBuffer, 521396e9039aec00982e98392a843635c1dcff5364dniruiyu FALSE 522396e9039aec00982e98392a843635c1dcff5364dniruiyu ); 523396e9039aec00982e98392a843635c1dcff5364dniruiyu } 524396e9039aec00982e98392a843635c1dcff5364dniruiyu 525396e9039aec00982e98392a843635c1dcff5364dniruiyu // 52628a00297189c323096aae8e2975de94e8549613cyshang // Get the Bus Specific Driver Override Protocol instance on the Controller Handle 52728a00297189c323096aae8e2975de94e8549613cyshang // 528adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 529022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle, 530022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiBusSpecificDriverOverrideProtocolGuid, 531e94a9ff7271367e649ee4f9a86da1f1bea6d112eqhuang (VOID **) &BusSpecificDriverOverride 53228a00297189c323096aae8e2975de94e8549613cyshang ); 53328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { 53428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 53528a00297189c323096aae8e2975de94e8549613cyshang do { 53628a00297189c323096aae8e2975de94e8549613cyshang Status = BusSpecificDriverOverride->GetDriver ( 53728a00297189c323096aae8e2975de94e8549613cyshang BusSpecificDriverOverride, 53828a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 53928a00297189c323096aae8e2975de94e8549613cyshang ); 54028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 54128a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 54228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 543022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 54428a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 54528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 546adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 547adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 54828a00297189c323096aae8e2975de94e8549613cyshang ); 54928a00297189c323096aae8e2975de94e8549613cyshang } 55028a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 55128a00297189c323096aae8e2975de94e8549613cyshang } 55228a00297189c323096aae8e2975de94e8549613cyshang 55328a00297189c323096aae8e2975de94e8549613cyshang // 55428a00297189c323096aae8e2975de94e8549613cyshang // Then add all the remaining Driver Binding Protocols 55528a00297189c323096aae8e2975de94e8549613cyshang // 55628a00297189c323096aae8e2975de94e8549613cyshang SortIndex = NumberOfSortedDriverBindingProtocols; 55728a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 55828a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 55928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 560022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NumberOfSortedDriverBindingProtocols, 56128a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 56228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 563adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 564adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 56528a00297189c323096aae8e2975de94e8549613cyshang ); 56628a00297189c323096aae8e2975de94e8549613cyshang } 56728a00297189c323096aae8e2975de94e8549613cyshang 56828a00297189c323096aae8e2975de94e8549613cyshang // 56928a00297189c323096aae8e2975de94e8549613cyshang // Free the Driver Binding Handle Buffer 57028a00297189c323096aae8e2975de94e8549613cyshang // 57128a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 57228a00297189c323096aae8e2975de94e8549613cyshang 57328a00297189c323096aae8e2975de94e8549613cyshang // 57485658066182d23e210209299770edaef26d09085mdkinney // If the number of Driver Binding Protocols has increased since this function started, then return 57585658066182d23e210209299770edaef26d09085mdkinney // EFI_NOT_READY, so it will be restarted 57685658066182d23e210209299770edaef26d09085mdkinney // 57770279390ba9a0774e020af36120f8b9ba1c217dbmdkinney Status = CoreLocateHandleBuffer ( 578022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ByProtocol, 579022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 58070279390ba9a0774e020af36120f8b9ba1c217dbmdkinney NULL, 581022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &NewDriverBindingHandleCount, 58270279390ba9a0774e020af36120f8b9ba1c217dbmdkinney &NewDriverBindingHandleBuffer 58370279390ba9a0774e020af36120f8b9ba1c217dbmdkinney ); 58470279390ba9a0774e020af36120f8b9ba1c217dbmdkinney CoreFreePool (NewDriverBindingHandleBuffer); 58570279390ba9a0774e020af36120f8b9ba1c217dbmdkinney if (NewDriverBindingHandleCount > DriverBindingHandleCount) { 58685658066182d23e210209299770edaef26d09085mdkinney // 58785658066182d23e210209299770edaef26d09085mdkinney // Free any buffers that were allocated with AllocatePool() 58885658066182d23e210209299770edaef26d09085mdkinney // 58985658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (SortedDriverBindingProtocols); 59085658066182d23e210209299770edaef26d09085mdkinney 59185658066182d23e210209299770edaef26d09085mdkinney return EFI_NOT_READY; 59285658066182d23e210209299770edaef26d09085mdkinney } 59385658066182d23e210209299770edaef26d09085mdkinney 59485658066182d23e210209299770edaef26d09085mdkinney // 59528a00297189c323096aae8e2975de94e8549613cyshang // Sort the remaining DriverBinding Protocol based on their Version field from 59628a00297189c323096aae8e2975de94e8549613cyshang // highest to lowest. 59728a00297189c323096aae8e2975de94e8549613cyshang // 59828a00297189c323096aae8e2975de94e8549613cyshang for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { 59928a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; 60028a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = SortIndex; 60128a00297189c323096aae8e2975de94e8549613cyshang for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { 60228a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { 60328a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[Index]->Version; 60428a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = Index; 60528a00297189c323096aae8e2975de94e8549613cyshang } 60628a00297189c323096aae8e2975de94e8549613cyshang } 60728a00297189c323096aae8e2975de94e8549613cyshang if (SortIndex != HighestIndex) { 60828a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[SortIndex]; 60928a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; 61028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[HighestIndex] = DriverBinding; 61128a00297189c323096aae8e2975de94e8549613cyshang } 61228a00297189c323096aae8e2975de94e8549613cyshang } 61328a00297189c323096aae8e2975de94e8549613cyshang 61428a00297189c323096aae8e2975de94e8549613cyshang // 61528a00297189c323096aae8e2975de94e8549613cyshang // Loop until no more drivers can be started on ControllerHandle 61628a00297189c323096aae8e2975de94e8549613cyshang // 61728a00297189c323096aae8e2975de94e8549613cyshang OneStarted = FALSE; 61828a00297189c323096aae8e2975de94e8549613cyshang do { 61928a00297189c323096aae8e2975de94e8549613cyshang 62028a00297189c323096aae8e2975de94e8549613cyshang // 62128a00297189c323096aae8e2975de94e8549613cyshang // Loop through the sorted Driver Binding Protocol Instances in order, and see if 622022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang // any of the Driver Binding Protocols support the controller specified by 62328a00297189c323096aae8e2975de94e8549613cyshang // ControllerHandle. 62428a00297189c323096aae8e2975de94e8549613cyshang // 62528a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = NULL; 62628a00297189c323096aae8e2975de94e8549613cyshang DriverFound = FALSE; 62728a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { 62828a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index] != NULL) { 62928a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[Index]; 630bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_START (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); 63128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Supported( 632022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 63328a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 63428a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 63528a00297189c323096aae8e2975de94e8549613cyshang ); 636bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_END (DriverBinding->DriverBindingHandle, "DB:Support:", NULL, 0); 63728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 63828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[Index] = NULL; 63928a00297189c323096aae8e2975de94e8549613cyshang DriverFound = TRUE; 64028a00297189c323096aae8e2975de94e8549613cyshang 64128a00297189c323096aae8e2975de94e8549613cyshang // 64228a00297189c323096aae8e2975de94e8549613cyshang // A driver was found that supports ControllerHandle, so attempt to start the driver 64328a00297189c323096aae8e2975de94e8549613cyshang // on ControllerHandle. 64428a00297189c323096aae8e2975de94e8549613cyshang // 645bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_START (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); 64628a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Start ( 647022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverBinding, 64828a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 64928a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 65028a00297189c323096aae8e2975de94e8549613cyshang ); 651bc6b5892b007447b1024d98004681aa7a3305ddfqhuang PERF_END (DriverBinding->DriverBindingHandle, "DB:Start:", NULL, 0); 65228a00297189c323096aae8e2975de94e8549613cyshang 65328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 65428a00297189c323096aae8e2975de94e8549613cyshang // 65528a00297189c323096aae8e2975de94e8549613cyshang // The driver was successfully started on ControllerHandle, so set a flag 65628a00297189c323096aae8e2975de94e8549613cyshang // 65728a00297189c323096aae8e2975de94e8549613cyshang OneStarted = TRUE; 65828a00297189c323096aae8e2975de94e8549613cyshang } 65928a00297189c323096aae8e2975de94e8549613cyshang } 66028a00297189c323096aae8e2975de94e8549613cyshang } 66128a00297189c323096aae8e2975de94e8549613cyshang } 66228a00297189c323096aae8e2975de94e8549613cyshang } while (DriverFound); 66328a00297189c323096aae8e2975de94e8549613cyshang 66428a00297189c323096aae8e2975de94e8549613cyshang // 66528a00297189c323096aae8e2975de94e8549613cyshang // Free any buffers that were allocated with AllocatePool() 66628a00297189c323096aae8e2975de94e8549613cyshang // 66728a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (SortedDriverBindingProtocols); 66828a00297189c323096aae8e2975de94e8549613cyshang 66928a00297189c323096aae8e2975de94e8549613cyshang // 67028a00297189c323096aae8e2975de94e8549613cyshang // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. 67128a00297189c323096aae8e2975de94e8549613cyshang // 67228a00297189c323096aae8e2975de94e8549613cyshang if (OneStarted) { 67328a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 674022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 67528a00297189c323096aae8e2975de94e8549613cyshang 67628a00297189c323096aae8e2975de94e8549613cyshang // 67728a00297189c323096aae8e2975de94e8549613cyshang // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS 67828a00297189c323096aae8e2975de94e8549613cyshang // 67928a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 68028a00297189c323096aae8e2975de94e8549613cyshang if (IsDevicePathEnd (RemainingDevicePath)) { 68128a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 68228a00297189c323096aae8e2975de94e8549613cyshang } 683022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 68428a00297189c323096aae8e2975de94e8549613cyshang 68528a00297189c323096aae8e2975de94e8549613cyshang // 68628a00297189c323096aae8e2975de94e8549613cyshang // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND 68728a00297189c323096aae8e2975de94e8549613cyshang // 68828a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 68928a00297189c323096aae8e2975de94e8549613cyshang} 69028a00297189c323096aae8e2975de94e8549613cyshang 69128a00297189c323096aae8e2975de94e8549613cyshang 692162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 693162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang/** 694162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang Disonnects a controller from a driver 695162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 696022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ControllerHandle ControllerHandle The handle of 697022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang the controller from which 698022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang driver(s) are to be 699022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected. 700022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param DriverImageHandle DriverImageHandle The driver to 701022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnect from ControllerHandle. 702022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @param ChildHandle ChildHandle The handle of the 703022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang child to destroy. 704022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 705022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS One or more drivers were 706022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected from the controller. 707022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS On entry, no drivers are managing 708022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ControllerHandle. 709022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_SUCCESS DriverImageHandle is not NULL, 710022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and on entry DriverImageHandle is 711022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang not managing ControllerHandle. 712284ee2e829ab2453293b7dc4539727ad6c047163niruiyu @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. 713022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, 714022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang and it is not a valid EFI_HANDLE. 715022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it 716022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang is not a valid EFI_HANDLE. 717022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_OUT_OF_RESOURCES There are not enough resources 718022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang available to disconnect any 719022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang drivers from ControllerHandle. 720022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang @retval EFI_DEVICE_ERROR The controller could not be 721022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang disconnected because of a device 722162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang error. 723162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang 724162ed594438ab8d39f89b43e6d645ca24e1e1e65qhuang**/ 725022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangEFI_STATUS 72628a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 72728a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController ( 72828a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 72928a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverImageHandle OPTIONAL, 73028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ChildHandle OPTIONAL 73128a00297189c323096aae8e2975de94e8549613cyshang ) 73228a00297189c323096aae8e2975de94e8549613cyshang{ 73328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 73428a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 73528a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverImageHandleBuffer; 73628a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *ChildBuffer; 73728a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 73828a00297189c323096aae8e2975de94e8549613cyshang UINTN HandleIndex; 73928a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverImageHandleCount; 74028a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildrenToStop; 74128a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildBufferCount; 74228a00297189c323096aae8e2975de94e8549613cyshang UINTN StopCount; 74328a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Duplicate; 74428a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ChildHandleValid; 74528a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverImageHandleValid; 74628a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 74728a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 74828a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 74928a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 75028a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 75128a00297189c323096aae8e2975de94e8549613cyshang 75228a00297189c323096aae8e2975de94e8549613cyshang // 75328a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 75428a00297189c323096aae8e2975de94e8549613cyshang // 75528a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 75628a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 75728a00297189c323096aae8e2975de94e8549613cyshang return Status; 75828a00297189c323096aae8e2975de94e8549613cyshang } 75928a00297189c323096aae8e2975de94e8549613cyshang 76028a00297189c323096aae8e2975de94e8549613cyshang // 76128a00297189c323096aae8e2975de94e8549613cyshang // Make sure ChildHandle is valid if it is not NULL 76228a00297189c323096aae8e2975de94e8549613cyshang // 76328a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 76428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ChildHandle); 76528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 76628a00297189c323096aae8e2975de94e8549613cyshang return Status; 76728a00297189c323096aae8e2975de94e8549613cyshang } 76828a00297189c323096aae8e2975de94e8549613cyshang } 76928a00297189c323096aae8e2975de94e8549613cyshang 77028a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 77128a00297189c323096aae8e2975de94e8549613cyshang 77228a00297189c323096aae8e2975de94e8549613cyshang // 77328a00297189c323096aae8e2975de94e8549613cyshang // Get list of drivers that are currently managing ControllerHandle 77428a00297189c323096aae8e2975de94e8549613cyshang // 77528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = NULL; 776022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandleCount = 1; 777022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 77828a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandle == NULL) { 77928a00297189c323096aae8e2975de94e8549613cyshang // 78028a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 78128a00297189c323096aae8e2975de94e8549613cyshang // 78228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 78328a00297189c323096aae8e2975de94e8549613cyshang 78428a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 78528a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 78628a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 787022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 788022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 78928a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 79028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 79128a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 79228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 79328a00297189c323096aae8e2975de94e8549613cyshang } 79428a00297189c323096aae8e2975de94e8549613cyshang } 79528a00297189c323096aae8e2975de94e8549613cyshang } 79628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 797022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 79828a00297189c323096aae8e2975de94e8549613cyshang // 79928a00297189c323096aae8e2975de94e8549613cyshang // If there are no drivers managing this controller, then return EFI_SUCCESS 80028a00297189c323096aae8e2975de94e8549613cyshang // 80128a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleCount == 0) { 80228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 80328a00297189c323096aae8e2975de94e8549613cyshang goto Done; 80428a00297189c323096aae8e2975de94e8549613cyshang } 80528a00297189c323096aae8e2975de94e8549613cyshang 8069c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount); 80728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer == NULL) { 80828a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 80928a00297189c323096aae8e2975de94e8549613cyshang goto Done; 81028a00297189c323096aae8e2975de94e8549613cyshang } 81128a00297189c323096aae8e2975de94e8549613cyshang 81228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 81328a00297189c323096aae8e2975de94e8549613cyshang 81428a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 81528a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 81628a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 817022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 818022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 81928a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 82028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 82128a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 82228a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 82328a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index< DriverImageHandleCount; Index++) { 82428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { 82528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 82628a00297189c323096aae8e2975de94e8549613cyshang break; 82728a00297189c323096aae8e2975de94e8549613cyshang } 82828a00297189c323096aae8e2975de94e8549613cyshang } 82928a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 83028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; 83128a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 83228a00297189c323096aae8e2975de94e8549613cyshang } 83328a00297189c323096aae8e2975de94e8549613cyshang } 83428a00297189c323096aae8e2975de94e8549613cyshang } 83528a00297189c323096aae8e2975de94e8549613cyshang } 83628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 83728a00297189c323096aae8e2975de94e8549613cyshang } 83828a00297189c323096aae8e2975de94e8549613cyshang 83928a00297189c323096aae8e2975de94e8549613cyshang StopCount = 0; 84028a00297189c323096aae8e2975de94e8549613cyshang for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { 84128a00297189c323096aae8e2975de94e8549613cyshang 84228a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 84328a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; 84428a00297189c323096aae8e2975de94e8549613cyshang } 84528a00297189c323096aae8e2975de94e8549613cyshang 84628a00297189c323096aae8e2975de94e8549613cyshang // 84728a00297189c323096aae8e2975de94e8549613cyshang // Get the Driver Binding Protocol of the driver that is managing this controller 84828a00297189c323096aae8e2975de94e8549613cyshang // 84928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol ( 850022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang DriverImageHandle, 851022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang &gEfiDriverBindingProtocolGuid, 85228a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 85328a00297189c323096aae8e2975de94e8549613cyshang ); 854d2fbaaab17945b59ca66bcd2f72e26ba3361e1d0rsun if (EFI_ERROR (Status) || DriverBinding == NULL) { 85528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 85628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 85728a00297189c323096aae8e2975de94e8549613cyshang } 85828a00297189c323096aae8e2975de94e8549613cyshang 85928a00297189c323096aae8e2975de94e8549613cyshang // 86028a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 86128a00297189c323096aae8e2975de94e8549613cyshang // 86228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = FALSE; 86328a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 86428a00297189c323096aae8e2975de94e8549613cyshang 86528a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 86628a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 86728a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 868022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 869022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 87028a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 87128a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 87228a00297189c323096aae8e2975de94e8549613cyshang if (OpenData->AgentHandle == DriverImageHandle) { 87328a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 87428a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 875022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang } 87628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 87728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = TRUE; 87828a00297189c323096aae8e2975de94e8549613cyshang } 87928a00297189c323096aae8e2975de94e8549613cyshang } 88028a00297189c323096aae8e2975de94e8549613cyshang } 88128a00297189c323096aae8e2975de94e8549613cyshang } 88228a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 88328a00297189c323096aae8e2975de94e8549613cyshang 88428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleValid) { 88528a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = FALSE; 88628a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = NULL; 88728a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount != 0) { 8889c4ac31cca01b4a503c36616770ea3157bf3bb9eqhuang ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount); 88928a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer == NULL) { 89028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 89128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 89228a00297189c323096aae8e2975de94e8549613cyshang } 89328a00297189c323096aae8e2975de94e8549613cyshang 89428a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 89528a00297189c323096aae8e2975de94e8549613cyshang 89628a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 89728a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 89828a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 899022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang for (ProtLink = Prot->OpenList.ForwardLink; 900022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang ProtLink != &Prot->OpenList; 90128a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 90228a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 90328a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == DriverImageHandle) && 90428a00297189c323096aae8e2975de94e8549613cyshang ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { 90528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 90628a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < ChildBufferCount; Index++) { 90728a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer[Index] == OpenData->ControllerHandle) { 90828a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 90928a00297189c323096aae8e2975de94e8549613cyshang break; 91028a00297189c323096aae8e2975de94e8549613cyshang } 91128a00297189c323096aae8e2975de94e8549613cyshang } 91228a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 91328a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; 91428a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == ChildBuffer[ChildBufferCount]) { 91528a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = TRUE; 91628a00297189c323096aae8e2975de94e8549613cyshang } 91728a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 91828a00297189c323096aae8e2975de94e8549613cyshang } 91928a00297189c323096aae8e2975de94e8549613cyshang } 92028a00297189c323096aae8e2975de94e8549613cyshang } 92128a00297189c323096aae8e2975de94e8549613cyshang } 92228a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 92328a00297189c323096aae8e2975de94e8549613cyshang } 92428a00297189c323096aae8e2975de94e8549613cyshang 92528a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == NULL || ChildHandleValid) { 92628a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 0; 92728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 92828a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount > 0) { 92928a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 93028a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 1; 93128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); 93228a00297189c323096aae8e2975de94e8549613cyshang } else { 93328a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = ChildBufferCount; 93428a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); 93528a00297189c323096aae8e2975de94e8549613cyshang } 93628a00297189c323096aae8e2975de94e8549613cyshang } 93728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { 93828a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); 93928a00297189c323096aae8e2975de94e8549613cyshang } 94028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 94128a00297189c323096aae8e2975de94e8549613cyshang StopCount++; 94228a00297189c323096aae8e2975de94e8549613cyshang } 94328a00297189c323096aae8e2975de94e8549613cyshang } 94428a00297189c323096aae8e2975de94e8549613cyshang 94528a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer != NULL) { 94628a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (ChildBuffer); 94728a00297189c323096aae8e2975de94e8549613cyshang } 94828a00297189c323096aae8e2975de94e8549613cyshang } 94928a00297189c323096aae8e2975de94e8549613cyshang } 95028a00297189c323096aae8e2975de94e8549613cyshang 95128a00297189c323096aae8e2975de94e8549613cyshang if (StopCount > 0) { 95228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 95328a00297189c323096aae8e2975de94e8549613cyshang } else { 95428a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 95528a00297189c323096aae8e2975de94e8549613cyshang } 956022c6d45ef78605c173023f53984e4dfaf7b11f4qhuang 957022c6d45ef78605c173023f53984e4dfaf7b11f4qhuangDone: 95828a00297189c323096aae8e2975de94e8549613cyshang 95928a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 96028a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverImageHandleBuffer); 96128a00297189c323096aae8e2975de94e8549613cyshang } 96228a00297189c323096aae8e2975de94e8549613cyshang 96328a00297189c323096aae8e2975de94e8549613cyshang return Status; 96428a00297189c323096aae8e2975de94e8549613cyshang} 965