DriverSupport.c revision 85658066182d23e210209299770edaef26d09085
128a00297189c323096aae8e2975de94e8549613cyshang/*++ 228a00297189c323096aae8e2975de94e8549613cyshang 328a00297189c323096aae8e2975de94e8549613cyshangCopyright (c) 2006, Intel Corporation 428a00297189c323096aae8e2975de94e8549613cyshangAll rights reserved. This program and the accompanying materials 528a00297189c323096aae8e2975de94e8549613cyshangare licensed and made available under the terms and conditions of the BSD License 628a00297189c323096aae8e2975de94e8549613cyshangwhich accompanies this distribution. The full text of the license may be found at 728a00297189c323096aae8e2975de94e8549613cyshanghttp://opensource.org/licenses/bsd-license.php 828a00297189c323096aae8e2975de94e8549613cyshang 928a00297189c323096aae8e2975de94e8549613cyshangTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 1028a00297189c323096aae8e2975de94e8549613cyshangWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 1128a00297189c323096aae8e2975de94e8549613cyshang 1228a00297189c323096aae8e2975de94e8549613cyshangModule Name: 1328a00297189c323096aae8e2975de94e8549613cyshang 1428a00297189c323096aae8e2975de94e8549613cyshang DriverSupport.c 1528a00297189c323096aae8e2975de94e8549613cyshang 1628a00297189c323096aae8e2975de94e8549613cyshangAbstract: 1728a00297189c323096aae8e2975de94e8549613cyshang 1828a00297189c323096aae8e2975de94e8549613cyshang EFI Driver Support Protocol 1928a00297189c323096aae8e2975de94e8549613cyshang 2028a00297189c323096aae8e2975de94e8549613cyshangRevision History 2128a00297189c323096aae8e2975de94e8549613cyshang 2228a00297189c323096aae8e2975de94e8549613cyshang--*/ 2328a00297189c323096aae8e2975de94e8549613cyshang 2428a00297189c323096aae8e2975de94e8549613cyshang#include <DxeMain.h> 2528a00297189c323096aae8e2975de94e8549613cyshang 2685658066182d23e210209299770edaef26d09085mdkinneyBOOLEAN mRepairLoadedImage = FALSE; 2728a00297189c323096aae8e2975de94e8549613cyshang 2885658066182d23e210209299770edaef26d09085mdkinney// 2985658066182d23e210209299770edaef26d09085mdkinney// Driver Support Function Prototypes 3085658066182d23e210209299770edaef26d09085mdkinney// 3128a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 3228a00297189c323096aae8e2975de94e8549613cyshangGetHandleFromDriverBinding ( 3328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed, 3428a00297189c323096aae8e2975de94e8549613cyshang OUT EFI_HANDLE *Handle 3528a00297189c323096aae8e2975de94e8549613cyshang ); 3628a00297189c323096aae8e2975de94e8549613cyshang 3728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 3828a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 3928a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 4028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 4128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 4228a00297189c323096aae8e2975de94e8549613cyshang ); 4328a00297189c323096aae8e2975de94e8549613cyshang 4428a00297189c323096aae8e2975de94e8549613cyshang// 4528a00297189c323096aae8e2975de94e8549613cyshang// Driver Support Functions 4628a00297189c323096aae8e2975de94e8549613cyshang// 4728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 4828a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 4928a00297189c323096aae8e2975de94e8549613cyshangCoreConnectController ( 5028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 5128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 5228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, 5328a00297189c323096aae8e2975de94e8549613cyshang IN BOOLEAN Recursive 5428a00297189c323096aae8e2975de94e8549613cyshang ) 5528a00297189c323096aae8e2975de94e8549613cyshang/*++ 5628a00297189c323096aae8e2975de94e8549613cyshang 5728a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 5828a00297189c323096aae8e2975de94e8549613cyshang 5928a00297189c323096aae8e2975de94e8549613cyshang Connects one or more drivers to a controller. 6028a00297189c323096aae8e2975de94e8549613cyshang 6128a00297189c323096aae8e2975de94e8549613cyshangArguments: 6228a00297189c323096aae8e2975de94e8549613cyshang 6328a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - Handle of the controller to be connected. 6428a00297189c323096aae8e2975de94e8549613cyshang 6528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles. 6628a00297189c323096aae8e2975de94e8549613cyshang 6728a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the 6828a00297189c323096aae8e2975de94e8549613cyshang controller specified by ControllerHandle. 6928a00297189c323096aae8e2975de94e8549613cyshang 7028a00297189c323096aae8e2975de94e8549613cyshang Recursive - Whether the function would be called recursively or not. 7128a00297189c323096aae8e2975de94e8549613cyshang 7228a00297189c323096aae8e2975de94e8549613cyshangReturns: 7328a00297189c323096aae8e2975de94e8549613cyshang 7428a00297189c323096aae8e2975de94e8549613cyshang Status code. 7528a00297189c323096aae8e2975de94e8549613cyshang 7628a00297189c323096aae8e2975de94e8549613cyshang--*/ 7728a00297189c323096aae8e2975de94e8549613cyshang{ 7828a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 7928a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS ReturnStatus; 8028a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 8128a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 8228a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 8328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 8428a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 8528a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath; 8685658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *ChildHandleBuffer; 8785658066182d23e210209299770edaef26d09085mdkinney UINTN ChildHandleCount; 8885658066182d23e210209299770edaef26d09085mdkinney UINTN Index; 8985658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *LoadedImageHandleBuffer; 9085658066182d23e210209299770edaef26d09085mdkinney UINTN LoadedImageHandleCount; 9185658066182d23e210209299770edaef26d09085mdkinney LOADED_IMAGE_PRIVATE_DATA *Image; 9285658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE DeviceHandle; 9385658066182d23e210209299770edaef26d09085mdkinney EFI_DEVICE_PATH_PROTOCOL *DevicePath; 9428a00297189c323096aae8e2975de94e8549613cyshang 9528a00297189c323096aae8e2975de94e8549613cyshang // 9628a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 9728a00297189c323096aae8e2975de94e8549613cyshang // 9828a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 9928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 10028a00297189c323096aae8e2975de94e8549613cyshang return Status; 10128a00297189c323096aae8e2975de94e8549613cyshang } 10228a00297189c323096aae8e2975de94e8549613cyshang 10328a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 10428a00297189c323096aae8e2975de94e8549613cyshang 10528a00297189c323096aae8e2975de94e8549613cyshang // 10685658066182d23e210209299770edaef26d09085mdkinney // Make a copy of RemainingDevicePath to guanatee it is aligned 10728a00297189c323096aae8e2975de94e8549613cyshang // 10828a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = NULL; 10928a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 11028a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath); 11128a00297189c323096aae8e2975de94e8549613cyshang } 11228a00297189c323096aae8e2975de94e8549613cyshang 11328a00297189c323096aae8e2975de94e8549613cyshang // 11485658066182d23e210209299770edaef26d09085mdkinney // Connect all drivers to ControllerHandle 11585658066182d23e210209299770edaef26d09085mdkinney // If CoreConnectSingleController returns EFI_NOT_READY, then the number of 11685658066182d23e210209299770edaef26d09085mdkinney // Driver Binding Protocols in the handle database has increased during the call 11785658066182d23e210209299770edaef26d09085mdkinney // so the connect operation must be restarted 11828a00297189c323096aae8e2975de94e8549613cyshang // 11985658066182d23e210209299770edaef26d09085mdkinney do { 12085658066182d23e210209299770edaef26d09085mdkinney ReturnStatus = CoreConnectSingleController ( 12185658066182d23e210209299770edaef26d09085mdkinney ControllerHandle, 12285658066182d23e210209299770edaef26d09085mdkinney DriverImageHandle, 12385658066182d23e210209299770edaef26d09085mdkinney AlignedRemainingDevicePath 12485658066182d23e210209299770edaef26d09085mdkinney ); 12585658066182d23e210209299770edaef26d09085mdkinney } while (ReturnStatus == EFI_NOT_READY); 12685658066182d23e210209299770edaef26d09085mdkinney 12785658066182d23e210209299770edaef26d09085mdkinney // 12885658066182d23e210209299770edaef26d09085mdkinney // Free the aligned copy of RemainingDevicePath 12985658066182d23e210209299770edaef26d09085mdkinney // 13085658066182d23e210209299770edaef26d09085mdkinney if (AlignedRemainingDevicePath != NULL) { 13185658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (AlignedRemainingDevicePath); 13228a00297189c323096aae8e2975de94e8549613cyshang } 13328a00297189c323096aae8e2975de94e8549613cyshang 13428a00297189c323096aae8e2975de94e8549613cyshang // 13528a00297189c323096aae8e2975de94e8549613cyshang // If recursive, then connect all drivers to all of ControllerHandle's children 13628a00297189c323096aae8e2975de94e8549613cyshang // 13785658066182d23e210209299770edaef26d09085mdkinney if (Recursive) { 13885658066182d23e210209299770edaef26d09085mdkinney // 13985658066182d23e210209299770edaef26d09085mdkinney // Acquire the protocol lock on the handle database so the child handles can be collected 14085658066182d23e210209299770edaef26d09085mdkinney // 14185658066182d23e210209299770edaef26d09085mdkinney CoreAcquireProtocolLock (); 14285658066182d23e210209299770edaef26d09085mdkinney 14385658066182d23e210209299770edaef26d09085mdkinney // 14485658066182d23e210209299770edaef26d09085mdkinney // Make sure the DriverBindingHandle is valid 14585658066182d23e210209299770edaef26d09085mdkinney // 14685658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (ControllerHandle); 14785658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 14885658066182d23e210209299770edaef26d09085mdkinney // 14985658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 15085658066182d23e210209299770edaef26d09085mdkinney // 15185658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 15285658066182d23e210209299770edaef26d09085mdkinney 15385658066182d23e210209299770edaef26d09085mdkinney return ReturnStatus; 15485658066182d23e210209299770edaef26d09085mdkinney } 15585658066182d23e210209299770edaef26d09085mdkinney 15685658066182d23e210209299770edaef26d09085mdkinney 15785658066182d23e210209299770edaef26d09085mdkinney // 15885658066182d23e210209299770edaef26d09085mdkinney // Count ControllerHandle's children 15985658066182d23e210209299770edaef26d09085mdkinney // 16085658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 16185658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 16285658066182d23e210209299770edaef26d09085mdkinney for (ProtLink = Prot->OpenList.ForwardLink; 16385658066182d23e210209299770edaef26d09085mdkinney ProtLink != &Prot->OpenList; 16485658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 16585658066182d23e210209299770edaef26d09085mdkinney OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 16685658066182d23e210209299770edaef26d09085mdkinney if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 16785658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 16885658066182d23e210209299770edaef26d09085mdkinney } 16985658066182d23e210209299770edaef26d09085mdkinney } 17085658066182d23e210209299770edaef26d09085mdkinney } 17185658066182d23e210209299770edaef26d09085mdkinney 17285658066182d23e210209299770edaef26d09085mdkinney // 17385658066182d23e210209299770edaef26d09085mdkinney // Allocate a handle buffer for ControllerHandle's children 17485658066182d23e210209299770edaef26d09085mdkinney // 17585658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer = CoreAllocateBootServicesPool (ChildHandleCount * sizeof(EFI_HANDLE)); 17685658066182d23e210209299770edaef26d09085mdkinney 17785658066182d23e210209299770edaef26d09085mdkinney // 17885658066182d23e210209299770edaef26d09085mdkinney // Fill in a handle buffer with ControllerHandle's children 17985658066182d23e210209299770edaef26d09085mdkinney // 18085658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 18185658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 18285658066182d23e210209299770edaef26d09085mdkinney for (ProtLink = Prot->OpenList.ForwardLink; 18385658066182d23e210209299770edaef26d09085mdkinney ProtLink != &Prot->OpenList; 18485658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 18528a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 18628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 18785658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; 18885658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 18985658066182d23e210209299770edaef26d09085mdkinney } 19085658066182d23e210209299770edaef26d09085mdkinney } 19185658066182d23e210209299770edaef26d09085mdkinney } 19285658066182d23e210209299770edaef26d09085mdkinney 19385658066182d23e210209299770edaef26d09085mdkinney // 19485658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 19585658066182d23e210209299770edaef26d09085mdkinney // 19685658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 19785658066182d23e210209299770edaef26d09085mdkinney 19885658066182d23e210209299770edaef26d09085mdkinney // 19985658066182d23e210209299770edaef26d09085mdkinney // Recursively connect each child handle 20085658066182d23e210209299770edaef26d09085mdkinney // 20185658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < ChildHandleCount; Index++) { 20285658066182d23e210209299770edaef26d09085mdkinney CoreConnectController ( 20385658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[Index], 20485658066182d23e210209299770edaef26d09085mdkinney NULL, 20585658066182d23e210209299770edaef26d09085mdkinney NULL, 20685658066182d23e210209299770edaef26d09085mdkinney TRUE 20785658066182d23e210209299770edaef26d09085mdkinney ); 20885658066182d23e210209299770edaef26d09085mdkinney } 20985658066182d23e210209299770edaef26d09085mdkinney 21085658066182d23e210209299770edaef26d09085mdkinney // 21185658066182d23e210209299770edaef26d09085mdkinney // Free the handle buffer of ControllerHandle's children 21285658066182d23e210209299770edaef26d09085mdkinney // 21385658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (ChildHandleBuffer); 21485658066182d23e210209299770edaef26d09085mdkinney } 21585658066182d23e210209299770edaef26d09085mdkinney 21685658066182d23e210209299770edaef26d09085mdkinney // 21785658066182d23e210209299770edaef26d09085mdkinney // If a Stop() function has been called one or more time successfully, then attempt to 21885658066182d23e210209299770edaef26d09085mdkinney // repair the stale DeviceHandle fields of the Loaded Image Protocols 21985658066182d23e210209299770edaef26d09085mdkinney // 22085658066182d23e210209299770edaef26d09085mdkinney if (mRepairLoadedImage) { 22185658066182d23e210209299770edaef26d09085mdkinney // 22285658066182d23e210209299770edaef26d09085mdkinney // Assume that all Loaded Image Protocols can be repaired 22385658066182d23e210209299770edaef26d09085mdkinney // 22485658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = FALSE; 22585658066182d23e210209299770edaef26d09085mdkinney 22685658066182d23e210209299770edaef26d09085mdkinney // 22785658066182d23e210209299770edaef26d09085mdkinney // Get list of all Loaded Image Protocol Instances 22885658066182d23e210209299770edaef26d09085mdkinney // 22985658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateHandleBuffer ( 23085658066182d23e210209299770edaef26d09085mdkinney ByProtocol, 23185658066182d23e210209299770edaef26d09085mdkinney &gEfiLoadedImageProtocolGuid, 23285658066182d23e210209299770edaef26d09085mdkinney NULL, 23385658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleCount, 23485658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleBuffer 23585658066182d23e210209299770edaef26d09085mdkinney ); 23685658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) { 23785658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < LoadedImageHandleCount; Index++) { 23885658066182d23e210209299770edaef26d09085mdkinney // 23985658066182d23e210209299770edaef26d09085mdkinney // Retrieve the Loaded Image Protocol 24085658066182d23e210209299770edaef26d09085mdkinney // 24185658066182d23e210209299770edaef26d09085mdkinney Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]); 24285658066182d23e210209299770edaef26d09085mdkinney if (Image != NULL) { 24385658066182d23e210209299770edaef26d09085mdkinney // 24485658066182d23e210209299770edaef26d09085mdkinney // Check to see if the DeviceHandle field is a valid handle 24585658066182d23e210209299770edaef26d09085mdkinney // 24685658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (Image->Info.DeviceHandle); 24785658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 24885658066182d23e210209299770edaef26d09085mdkinney // 24985658066182d23e210209299770edaef26d09085mdkinney // The DeviceHandle field is not valid. 25085658066182d23e210209299770edaef26d09085mdkinney // Attempt to locate a device handle with a device path that matches the one 25185658066182d23e210209299770edaef26d09085mdkinney // that was used to originally load the image 25285658066182d23e210209299770edaef26d09085mdkinney // 25385658066182d23e210209299770edaef26d09085mdkinney DevicePath = Image->DeviceHandleDevicePath; 25485658066182d23e210209299770edaef26d09085mdkinney if (DevicePath != NULL) { 25585658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle); 25685658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) { 25785658066182d23e210209299770edaef26d09085mdkinney // 25885658066182d23e210209299770edaef26d09085mdkinney // A device handle with a matching device path was found, so update the Loaded Image Protocol 25985658066182d23e210209299770edaef26d09085mdkinney // with the device handle discovered 26085658066182d23e210209299770edaef26d09085mdkinney // 26185658066182d23e210209299770edaef26d09085mdkinney Image->Info.DeviceHandle = DeviceHandle; 26285658066182d23e210209299770edaef26d09085mdkinney } else { 26385658066182d23e210209299770edaef26d09085mdkinney // 26485658066182d23e210209299770edaef26d09085mdkinney // There is still at least one Loaded Image Protocol that requires repair 26585658066182d23e210209299770edaef26d09085mdkinney // 26685658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = TRUE; 26785658066182d23e210209299770edaef26d09085mdkinney } 26885658066182d23e210209299770edaef26d09085mdkinney } 26985658066182d23e210209299770edaef26d09085mdkinney } 27028a00297189c323096aae8e2975de94e8549613cyshang } 27185658066182d23e210209299770edaef26d09085mdkinney } 27285658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (LoadedImageHandleBuffer); 27328a00297189c323096aae8e2975de94e8549613cyshang } 27428a00297189c323096aae8e2975de94e8549613cyshang } 27585658066182d23e210209299770edaef26d09085mdkinney 27628a00297189c323096aae8e2975de94e8549613cyshang return ReturnStatus; 27728a00297189c323096aae8e2975de94e8549613cyshang} 27828a00297189c323096aae8e2975de94e8549613cyshang 27928a00297189c323096aae8e2975de94e8549613cyshangVOID 28028a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol ( 28128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverBindingHandle, 28228a00297189c323096aae8e2975de94e8549613cyshang IN OUT UINTN *NumberOfSortedDriverBindingProtocols, 28328a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, 28428a00297189c323096aae8e2975de94e8549613cyshang IN UINTN DriverBindingHandleCount, 28528a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_HANDLE *DriverBindingHandleBuffer 28628a00297189c323096aae8e2975de94e8549613cyshang ) 28728a00297189c323096aae8e2975de94e8549613cyshang/*++ 28828a00297189c323096aae8e2975de94e8549613cyshang 28928a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 29028a00297189c323096aae8e2975de94e8549613cyshang 29128a00297189c323096aae8e2975de94e8549613cyshang Add Driver Binding Protocols from Context Driver Image Handles to sorted 29228a00297189c323096aae8e2975de94e8549613cyshang Driver Binding Protocol list. 29328a00297189c323096aae8e2975de94e8549613cyshang 29428a00297189c323096aae8e2975de94e8549613cyshangArguments: 29528a00297189c323096aae8e2975de94e8549613cyshang 29628a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle - Handle of the driver binding protocol. 29728a00297189c323096aae8e2975de94e8549613cyshang 29828a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols 29928a00297189c323096aae8e2975de94e8549613cyshang 30028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols - The sorted protocol list. 30128a00297189c323096aae8e2975de94e8549613cyshang 30228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount - Driver Binding Handle Count. 30328a00297189c323096aae8e2975de94e8549613cyshang 30428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified. 30528a00297189c323096aae8e2975de94e8549613cyshang 30628a00297189c323096aae8e2975de94e8549613cyshangReturns: 30728a00297189c323096aae8e2975de94e8549613cyshang 30828a00297189c323096aae8e2975de94e8549613cyshang None. 30928a00297189c323096aae8e2975de94e8549613cyshang 31028a00297189c323096aae8e2975de94e8549613cyshang--*/ 31128a00297189c323096aae8e2975de94e8549613cyshang{ 31228a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 31328a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 31428a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 31528a00297189c323096aae8e2975de94e8549613cyshang 31628a00297189c323096aae8e2975de94e8549613cyshang // 31728a00297189c323096aae8e2975de94e8549613cyshang // Make sure the DriverBindingHandle is valid 31828a00297189c323096aae8e2975de94e8549613cyshang // 31928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (DriverBindingHandle); 32028a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 32128a00297189c323096aae8e2975de94e8549613cyshang return; 32228a00297189c323096aae8e2975de94e8549613cyshang } 32328a00297189c323096aae8e2975de94e8549613cyshang 32428a00297189c323096aae8e2975de94e8549613cyshang // 32528a00297189c323096aae8e2975de94e8549613cyshang // Retrieve the Driver Binding Protocol from DriverBindingHandle 32628a00297189c323096aae8e2975de94e8549613cyshang // 32728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 32828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle, 32928a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 33028a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 33128a00297189c323096aae8e2975de94e8549613cyshang ); 33228a00297189c323096aae8e2975de94e8549613cyshang // 33328a00297189c323096aae8e2975de94e8549613cyshang // If DriverBindingHandle does not support the Driver Binding Protocol then return 33428a00297189c323096aae8e2975de94e8549613cyshang // 33528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBinding == NULL) { 33628a00297189c323096aae8e2975de94e8549613cyshang return; 33728a00297189c323096aae8e2975de94e8549613cyshang } 33828a00297189c323096aae8e2975de94e8549613cyshang 33928a00297189c323096aae8e2975de94e8549613cyshang // 34028a00297189c323096aae8e2975de94e8549613cyshang // See if DriverBinding is already in the sorted list 34128a00297189c323096aae8e2975de94e8549613cyshang // 34285658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { 34328a00297189c323096aae8e2975de94e8549613cyshang if (DriverBinding == SortedDriverBindingProtocols[Index]) { 34428a00297189c323096aae8e2975de94e8549613cyshang return; 34528a00297189c323096aae8e2975de94e8549613cyshang } 34628a00297189c323096aae8e2975de94e8549613cyshang } 34728a00297189c323096aae8e2975de94e8549613cyshang 34828a00297189c323096aae8e2975de94e8549613cyshang // 34928a00297189c323096aae8e2975de94e8549613cyshang // Add DriverBinding to the end of the list 35028a00297189c323096aae8e2975de94e8549613cyshang // 35185658066182d23e210209299770edaef26d09085mdkinney if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { 35285658066182d23e210209299770edaef26d09085mdkinney SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; 35385658066182d23e210209299770edaef26d09085mdkinney } 35428a00297189c323096aae8e2975de94e8549613cyshang *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; 35528a00297189c323096aae8e2975de94e8549613cyshang 35628a00297189c323096aae8e2975de94e8549613cyshang // 35728a00297189c323096aae8e2975de94e8549613cyshang // Mark the cooresponding handle in DriverBindingHandleBuffer as used 35828a00297189c323096aae8e2975de94e8549613cyshang // 35928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 36028a00297189c323096aae8e2975de94e8549613cyshang if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { 36128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index] = NULL; 36228a00297189c323096aae8e2975de94e8549613cyshang } 36328a00297189c323096aae8e2975de94e8549613cyshang } 36428a00297189c323096aae8e2975de94e8549613cyshang} 36528a00297189c323096aae8e2975de94e8549613cyshang 36628a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 36728a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 36828a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 36928a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, 37028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 37128a00297189c323096aae8e2975de94e8549613cyshang ) 37228a00297189c323096aae8e2975de94e8549613cyshang/*++ 37328a00297189c323096aae8e2975de94e8549613cyshang 37428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 37528a00297189c323096aae8e2975de94e8549613cyshang 37628a00297189c323096aae8e2975de94e8549613cyshang Connects a controller to a driver. 37728a00297189c323096aae8e2975de94e8549613cyshang 37828a00297189c323096aae8e2975de94e8549613cyshangArguments: 37928a00297189c323096aae8e2975de94e8549613cyshang 38028a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - Handle of the controller to be connected. 38128a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles. 38228a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child 38328a00297189c323096aae8e2975de94e8549613cyshang of the controller specified by ControllerHandle. 38428a00297189c323096aae8e2975de94e8549613cyshang 38528a00297189c323096aae8e2975de94e8549613cyshangReturns: 38628a00297189c323096aae8e2975de94e8549613cyshang 38728a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - One or more drivers were connected to ControllerHandle. 38828a00297189c323096aae8e2975de94e8549613cyshang EFI_OUT_OF_RESOURCES - No enough system resources to complete the request. 38928a00297189c323096aae8e2975de94e8549613cyshang EFI_NOT_FOUND - No drivers were connected to ControllerHandle. 39028a00297189c323096aae8e2975de94e8549613cyshang 39128a00297189c323096aae8e2975de94e8549613cyshang--*/ 39228a00297189c323096aae8e2975de94e8549613cyshang{ 39328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 39428a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 39528a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverImageHandle; 39628a00297189c323096aae8e2975de94e8549613cyshang EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; 39728a00297189c323096aae8e2975de94e8549613cyshang EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; 39828a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 39928a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 40028a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 40128a00297189c323096aae8e2975de94e8549613cyshang UINTN NumberOfSortedDriverBindingProtocols; 40228a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; 40328a00297189c323096aae8e2975de94e8549613cyshang UINT32 HighestVersion; 40428a00297189c323096aae8e2975de94e8549613cyshang UINTN HighestIndex; 40528a00297189c323096aae8e2975de94e8549613cyshang UINTN SortIndex; 40628a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN OneStarted; 40728a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverFound; 40828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverBindingHandle; 40928a00297189c323096aae8e2975de94e8549613cyshang 41028a00297189c323096aae8e2975de94e8549613cyshang // 41128a00297189c323096aae8e2975de94e8549613cyshang // DriverBindingHandle is used for performance measurement, initialize it here just in case. 41228a00297189c323096aae8e2975de94e8549613cyshang // 41328a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle = NULL; 41428a00297189c323096aae8e2975de94e8549613cyshang // 41528a00297189c323096aae8e2975de94e8549613cyshang // Initialize local variables 41628a00297189c323096aae8e2975de94e8549613cyshang // 41728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 41828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 41928a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols = 0; 42028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = NULL; 42128a00297189c323096aae8e2975de94e8549613cyshang 42228a00297189c323096aae8e2975de94e8549613cyshang // 42328a00297189c323096aae8e2975de94e8549613cyshang // Get list of all Driver Binding Protocol Instances 42428a00297189c323096aae8e2975de94e8549613cyshang // 42528a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 42628a00297189c323096aae8e2975de94e8549613cyshang ByProtocol, 42728a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 42828a00297189c323096aae8e2975de94e8549613cyshang NULL, 42928a00297189c323096aae8e2975de94e8549613cyshang &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 // 43928a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = CoreAllocateBootServicesPool (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], 45228a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 45328a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 45428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 45528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer 45628a00297189c323096aae8e2975de94e8549613cyshang ); 45728a00297189c323096aae8e2975de94e8549613cyshang } 45828a00297189c323096aae8e2975de94e8549613cyshang } 45928a00297189c323096aae8e2975de94e8549613cyshang 46028a00297189c323096aae8e2975de94e8549613cyshang // 46128a00297189c323096aae8e2975de94e8549613cyshang // Add the Platform Driver Override Protocol drivers for ControllerHandle next 46228a00297189c323096aae8e2975de94e8549613cyshang // 46328a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateProtocol ( 46428a00297189c323096aae8e2975de94e8549613cyshang &gEfiPlatformDriverOverrideProtocolGuid, 46528a00297189c323096aae8e2975de94e8549613cyshang NULL, 46628a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&PlatformDriverOverride 46728a00297189c323096aae8e2975de94e8549613cyshang ); 46828a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { 46928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 47028a00297189c323096aae8e2975de94e8549613cyshang do { 47128a00297189c323096aae8e2975de94e8549613cyshang Status = PlatformDriverOverride->GetDriver ( 47228a00297189c323096aae8e2975de94e8549613cyshang PlatformDriverOverride, 47328a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 47428a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 47528a00297189c323096aae8e2975de94e8549613cyshang ); 47628a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 47728a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 47828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 47928a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 48028a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 48128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 48228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer 48328a00297189c323096aae8e2975de94e8549613cyshang ); 48428a00297189c323096aae8e2975de94e8549613cyshang } 48528a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 48628a00297189c323096aae8e2975de94e8549613cyshang } 48728a00297189c323096aae8e2975de94e8549613cyshang 48828a00297189c323096aae8e2975de94e8549613cyshang // 48928a00297189c323096aae8e2975de94e8549613cyshang // Get the Bus Specific Driver Override Protocol instance on the Controller Handle 49028a00297189c323096aae8e2975de94e8549613cyshang // 49128a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 49228a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 49328a00297189c323096aae8e2975de94e8549613cyshang &gEfiBusSpecificDriverOverrideProtocolGuid, 49428a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&BusSpecificDriverOverride 49528a00297189c323096aae8e2975de94e8549613cyshang ); 49628a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { 49728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 49828a00297189c323096aae8e2975de94e8549613cyshang do { 49928a00297189c323096aae8e2975de94e8549613cyshang Status = BusSpecificDriverOverride->GetDriver ( 50028a00297189c323096aae8e2975de94e8549613cyshang BusSpecificDriverOverride, 50128a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 50228a00297189c323096aae8e2975de94e8549613cyshang ); 50328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 50428a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 50528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 50628a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 50728a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 50828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 50928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer 51028a00297189c323096aae8e2975de94e8549613cyshang ); 51128a00297189c323096aae8e2975de94e8549613cyshang } 51228a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 51328a00297189c323096aae8e2975de94e8549613cyshang } 51428a00297189c323096aae8e2975de94e8549613cyshang 51528a00297189c323096aae8e2975de94e8549613cyshang // 51628a00297189c323096aae8e2975de94e8549613cyshang // Then add all the remaining Driver Binding Protocols 51728a00297189c323096aae8e2975de94e8549613cyshang // 51828a00297189c323096aae8e2975de94e8549613cyshang SortIndex = NumberOfSortedDriverBindingProtocols; 51928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 52028a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 52128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 52228a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 52328a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 52428a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 52528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer 52628a00297189c323096aae8e2975de94e8549613cyshang ); 52728a00297189c323096aae8e2975de94e8549613cyshang } 52828a00297189c323096aae8e2975de94e8549613cyshang 52928a00297189c323096aae8e2975de94e8549613cyshang // 53028a00297189c323096aae8e2975de94e8549613cyshang // Free the Driver Binding Handle Buffer 53128a00297189c323096aae8e2975de94e8549613cyshang // 53228a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 53328a00297189c323096aae8e2975de94e8549613cyshang 53428a00297189c323096aae8e2975de94e8549613cyshang // 53585658066182d23e210209299770edaef26d09085mdkinney // If the number of Driver Binding Protocols has increased since this function started, then return 53685658066182d23e210209299770edaef26d09085mdkinney // EFI_NOT_READY, so it will be restarted 53785658066182d23e210209299770edaef26d09085mdkinney // 53885658066182d23e210209299770edaef26d09085mdkinney if (NumberOfSortedDriverBindingProtocols > DriverBindingHandleCount) { 53985658066182d23e210209299770edaef26d09085mdkinney // 54085658066182d23e210209299770edaef26d09085mdkinney // Free any buffers that were allocated with AllocatePool() 54185658066182d23e210209299770edaef26d09085mdkinney // 54285658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (SortedDriverBindingProtocols); 54385658066182d23e210209299770edaef26d09085mdkinney 54485658066182d23e210209299770edaef26d09085mdkinney return EFI_NOT_READY; 54585658066182d23e210209299770edaef26d09085mdkinney } 54685658066182d23e210209299770edaef26d09085mdkinney 54785658066182d23e210209299770edaef26d09085mdkinney // 54828a00297189c323096aae8e2975de94e8549613cyshang // Sort the remaining DriverBinding Protocol based on their Version field from 54928a00297189c323096aae8e2975de94e8549613cyshang // highest to lowest. 55028a00297189c323096aae8e2975de94e8549613cyshang // 55128a00297189c323096aae8e2975de94e8549613cyshang for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { 55228a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; 55328a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = SortIndex; 55428a00297189c323096aae8e2975de94e8549613cyshang for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { 55528a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { 55628a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[Index]->Version; 55728a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = Index; 55828a00297189c323096aae8e2975de94e8549613cyshang } 55928a00297189c323096aae8e2975de94e8549613cyshang } 56028a00297189c323096aae8e2975de94e8549613cyshang if (SortIndex != HighestIndex) { 56128a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[SortIndex]; 56228a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; 56328a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[HighestIndex] = DriverBinding; 56428a00297189c323096aae8e2975de94e8549613cyshang } 56528a00297189c323096aae8e2975de94e8549613cyshang } 56628a00297189c323096aae8e2975de94e8549613cyshang 56728a00297189c323096aae8e2975de94e8549613cyshang // 56828a00297189c323096aae8e2975de94e8549613cyshang // Loop until no more drivers can be started on ControllerHandle 56928a00297189c323096aae8e2975de94e8549613cyshang // 57028a00297189c323096aae8e2975de94e8549613cyshang OneStarted = FALSE; 57128a00297189c323096aae8e2975de94e8549613cyshang do { 57228a00297189c323096aae8e2975de94e8549613cyshang 57328a00297189c323096aae8e2975de94e8549613cyshang // 57428a00297189c323096aae8e2975de94e8549613cyshang // Loop through the sorted Driver Binding Protocol Instances in order, and see if 57528a00297189c323096aae8e2975de94e8549613cyshang // any of the Driver Binding Protocols support the controller specified by 57628a00297189c323096aae8e2975de94e8549613cyshang // ControllerHandle. 57728a00297189c323096aae8e2975de94e8549613cyshang // 57828a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = NULL; 57928a00297189c323096aae8e2975de94e8549613cyshang DriverFound = FALSE; 58028a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { 58128a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index] != NULL) { 58228a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[Index]; 58328a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Supported( 58428a00297189c323096aae8e2975de94e8549613cyshang DriverBinding, 58528a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 58628a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 58728a00297189c323096aae8e2975de94e8549613cyshang ); 58828a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 58928a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[Index] = NULL; 59028a00297189c323096aae8e2975de94e8549613cyshang DriverFound = TRUE; 59128a00297189c323096aae8e2975de94e8549613cyshang 59228a00297189c323096aae8e2975de94e8549613cyshang // 59328a00297189c323096aae8e2975de94e8549613cyshang // A driver was found that supports ControllerHandle, so attempt to start the driver 59428a00297189c323096aae8e2975de94e8549613cyshang // on ControllerHandle. 59528a00297189c323096aae8e2975de94e8549613cyshang // 59628a00297189c323096aae8e2975de94e8549613cyshang PERF_CODE_BEGIN (); 59728a00297189c323096aae8e2975de94e8549613cyshang GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle); 59828a00297189c323096aae8e2975de94e8549613cyshang PERF_CODE_END (); 59928a00297189c323096aae8e2975de94e8549613cyshang 60028a00297189c323096aae8e2975de94e8549613cyshang PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 60128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Start ( 60228a00297189c323096aae8e2975de94e8549613cyshang DriverBinding, 60328a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 60428a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 60528a00297189c323096aae8e2975de94e8549613cyshang ); 60628a00297189c323096aae8e2975de94e8549613cyshang PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 60728a00297189c323096aae8e2975de94e8549613cyshang 60828a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 60928a00297189c323096aae8e2975de94e8549613cyshang // 61028a00297189c323096aae8e2975de94e8549613cyshang // The driver was successfully started on ControllerHandle, so set a flag 61128a00297189c323096aae8e2975de94e8549613cyshang // 61228a00297189c323096aae8e2975de94e8549613cyshang OneStarted = TRUE; 61328a00297189c323096aae8e2975de94e8549613cyshang } 61428a00297189c323096aae8e2975de94e8549613cyshang } 61528a00297189c323096aae8e2975de94e8549613cyshang } 61628a00297189c323096aae8e2975de94e8549613cyshang } 61728a00297189c323096aae8e2975de94e8549613cyshang } while (DriverFound); 61828a00297189c323096aae8e2975de94e8549613cyshang 61928a00297189c323096aae8e2975de94e8549613cyshang // 62028a00297189c323096aae8e2975de94e8549613cyshang // Free any buffers that were allocated with AllocatePool() 62128a00297189c323096aae8e2975de94e8549613cyshang // 62228a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (SortedDriverBindingProtocols); 62328a00297189c323096aae8e2975de94e8549613cyshang 62428a00297189c323096aae8e2975de94e8549613cyshang // 62528a00297189c323096aae8e2975de94e8549613cyshang // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. 62628a00297189c323096aae8e2975de94e8549613cyshang // 62728a00297189c323096aae8e2975de94e8549613cyshang if (OneStarted) { 62828a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 62928a00297189c323096aae8e2975de94e8549613cyshang } 63028a00297189c323096aae8e2975de94e8549613cyshang 63128a00297189c323096aae8e2975de94e8549613cyshang // 63228a00297189c323096aae8e2975de94e8549613cyshang // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS 63328a00297189c323096aae8e2975de94e8549613cyshang // 63428a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 63528a00297189c323096aae8e2975de94e8549613cyshang if (IsDevicePathEnd (RemainingDevicePath)) { 63628a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 63728a00297189c323096aae8e2975de94e8549613cyshang } 63828a00297189c323096aae8e2975de94e8549613cyshang } 63928a00297189c323096aae8e2975de94e8549613cyshang 64028a00297189c323096aae8e2975de94e8549613cyshang // 64128a00297189c323096aae8e2975de94e8549613cyshang // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND 64228a00297189c323096aae8e2975de94e8549613cyshang // 64328a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 64428a00297189c323096aae8e2975de94e8549613cyshang} 64528a00297189c323096aae8e2975de94e8549613cyshang 64628a00297189c323096aae8e2975de94e8549613cyshang 64728a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 64828a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 64928a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController ( 65028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 65128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverImageHandle OPTIONAL, 65228a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ChildHandle OPTIONAL 65328a00297189c323096aae8e2975de94e8549613cyshang ) 65428a00297189c323096aae8e2975de94e8549613cyshang/*++ 65528a00297189c323096aae8e2975de94e8549613cyshang 65628a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 65728a00297189c323096aae8e2975de94e8549613cyshang 65828a00297189c323096aae8e2975de94e8549613cyshang Disonnects a controller from a driver 65928a00297189c323096aae8e2975de94e8549613cyshang 66028a00297189c323096aae8e2975de94e8549613cyshangArguments: 66128a00297189c323096aae8e2975de94e8549613cyshang 66228a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - ControllerHandle The handle of the controller from which driver(s) 66328a00297189c323096aae8e2975de94e8549613cyshang are to be disconnected. 66428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle. 66528a00297189c323096aae8e2975de94e8549613cyshang ChildHandle - ChildHandle The handle of the child to destroy. 66628a00297189c323096aae8e2975de94e8549613cyshang 66728a00297189c323096aae8e2975de94e8549613cyshangReturns: 66828a00297189c323096aae8e2975de94e8549613cyshang 66928a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - One or more drivers were disconnected from the controller. 67028a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - On entry, no drivers are managing ControllerHandle. 67128a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle. 67228a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. 67328a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE. 67428a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE. 67528a00297189c323096aae8e2975de94e8549613cyshang EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle. 67628a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error. 67728a00297189c323096aae8e2975de94e8549613cyshang 67828a00297189c323096aae8e2975de94e8549613cyshang--*/ 67928a00297189c323096aae8e2975de94e8549613cyshang{ 68028a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 68128a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 68228a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverImageHandleBuffer; 68328a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *ChildBuffer; 68428a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 68528a00297189c323096aae8e2975de94e8549613cyshang UINTN HandleIndex; 68628a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverImageHandleCount; 68728a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildrenToStop; 68828a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildBufferCount; 68928a00297189c323096aae8e2975de94e8549613cyshang UINTN StopCount; 69028a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Duplicate; 69128a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ChildHandleValid; 69228a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverImageHandleValid; 69328a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 69428a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 69528a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 69628a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 69728a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 69885658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *LoadedImageHandleBuffer; 69985658066182d23e210209299770edaef26d09085mdkinney UINTN LoadedImageHandleCount; 70085658066182d23e210209299770edaef26d09085mdkinney LOADED_IMAGE_PRIVATE_DATA *Image; 70128a00297189c323096aae8e2975de94e8549613cyshang 70228a00297189c323096aae8e2975de94e8549613cyshang // 70328a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 70428a00297189c323096aae8e2975de94e8549613cyshang // 70528a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 70628a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 70728a00297189c323096aae8e2975de94e8549613cyshang return Status; 70828a00297189c323096aae8e2975de94e8549613cyshang } 70928a00297189c323096aae8e2975de94e8549613cyshang 71028a00297189c323096aae8e2975de94e8549613cyshang // 71128a00297189c323096aae8e2975de94e8549613cyshang // Make sure ChildHandle is valid if it is not NULL 71228a00297189c323096aae8e2975de94e8549613cyshang // 71328a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 71428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ChildHandle); 71528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 71628a00297189c323096aae8e2975de94e8549613cyshang return Status; 71728a00297189c323096aae8e2975de94e8549613cyshang } 71828a00297189c323096aae8e2975de94e8549613cyshang } 71928a00297189c323096aae8e2975de94e8549613cyshang 72028a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 72128a00297189c323096aae8e2975de94e8549613cyshang 72228a00297189c323096aae8e2975de94e8549613cyshang // 72328a00297189c323096aae8e2975de94e8549613cyshang // Get list of drivers that are currently managing ControllerHandle 72428a00297189c323096aae8e2975de94e8549613cyshang // 72528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = NULL; 72628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 1; 72728a00297189c323096aae8e2975de94e8549613cyshang 72828a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandle == NULL) { 72928a00297189c323096aae8e2975de94e8549613cyshang // 73028a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 73128a00297189c323096aae8e2975de94e8549613cyshang // 73228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 73328a00297189c323096aae8e2975de94e8549613cyshang 73428a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 73528a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 73628a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 73728a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 73828a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 73928a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 74028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 74128a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 74228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 74328a00297189c323096aae8e2975de94e8549613cyshang } 74428a00297189c323096aae8e2975de94e8549613cyshang } 74528a00297189c323096aae8e2975de94e8549613cyshang } 74628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 74728a00297189c323096aae8e2975de94e8549613cyshang 74828a00297189c323096aae8e2975de94e8549613cyshang // 74928a00297189c323096aae8e2975de94e8549613cyshang // If there are no drivers managing this controller, then return EFI_SUCCESS 75028a00297189c323096aae8e2975de94e8549613cyshang // 75128a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleCount == 0) { 75228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 75328a00297189c323096aae8e2975de94e8549613cyshang goto Done; 75428a00297189c323096aae8e2975de94e8549613cyshang } 75528a00297189c323096aae8e2975de94e8549613cyshang 75628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount); 75728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer == NULL) { 75828a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 75928a00297189c323096aae8e2975de94e8549613cyshang goto Done; 76028a00297189c323096aae8e2975de94e8549613cyshang } 76128a00297189c323096aae8e2975de94e8549613cyshang 76228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 76328a00297189c323096aae8e2975de94e8549613cyshang 76428a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 76528a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 76628a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 76728a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 76828a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 76928a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 77028a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 77128a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 77228a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 77328a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index< DriverImageHandleCount; Index++) { 77428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { 77528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 77628a00297189c323096aae8e2975de94e8549613cyshang break; 77728a00297189c323096aae8e2975de94e8549613cyshang } 77828a00297189c323096aae8e2975de94e8549613cyshang } 77928a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 78028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; 78128a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 78228a00297189c323096aae8e2975de94e8549613cyshang } 78328a00297189c323096aae8e2975de94e8549613cyshang } 78428a00297189c323096aae8e2975de94e8549613cyshang } 78528a00297189c323096aae8e2975de94e8549613cyshang } 78628a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 78728a00297189c323096aae8e2975de94e8549613cyshang } 78828a00297189c323096aae8e2975de94e8549613cyshang 78928a00297189c323096aae8e2975de94e8549613cyshang StopCount = 0; 79028a00297189c323096aae8e2975de94e8549613cyshang for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { 79128a00297189c323096aae8e2975de94e8549613cyshang 79228a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 79328a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; 79428a00297189c323096aae8e2975de94e8549613cyshang } 79528a00297189c323096aae8e2975de94e8549613cyshang 79628a00297189c323096aae8e2975de94e8549613cyshang // 79728a00297189c323096aae8e2975de94e8549613cyshang // Get the Driver Binding Protocol of the driver that is managing this controller 79828a00297189c323096aae8e2975de94e8549613cyshang // 79928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol ( 80028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 80128a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 80228a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 80328a00297189c323096aae8e2975de94e8549613cyshang ); 80428a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 80528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 80628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 80728a00297189c323096aae8e2975de94e8549613cyshang } 80828a00297189c323096aae8e2975de94e8549613cyshang 80928a00297189c323096aae8e2975de94e8549613cyshang // 81028a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 81128a00297189c323096aae8e2975de94e8549613cyshang // 81228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = FALSE; 81328a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 81428a00297189c323096aae8e2975de94e8549613cyshang 81528a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 81628a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 81728a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 81828a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 81928a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 82028a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 82128a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 82228a00297189c323096aae8e2975de94e8549613cyshang if (OpenData->AgentHandle == DriverImageHandle) { 82328a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 82428a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 82528a00297189c323096aae8e2975de94e8549613cyshang } 82628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 82728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = TRUE; 82828a00297189c323096aae8e2975de94e8549613cyshang } 82928a00297189c323096aae8e2975de94e8549613cyshang } 83028a00297189c323096aae8e2975de94e8549613cyshang } 83128a00297189c323096aae8e2975de94e8549613cyshang } 83228a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 83328a00297189c323096aae8e2975de94e8549613cyshang 83428a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleValid) { 83528a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = FALSE; 83628a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = NULL; 83728a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount != 0) { 83828a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount); 83928a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer == NULL) { 84028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 84128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 84228a00297189c323096aae8e2975de94e8549613cyshang } 84328a00297189c323096aae8e2975de94e8549613cyshang 84428a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 84528a00297189c323096aae8e2975de94e8549613cyshang 84628a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 84728a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 84828a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 84928a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 85028a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 85128a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 85228a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 85328a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == DriverImageHandle) && 85428a00297189c323096aae8e2975de94e8549613cyshang ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { 85528a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 85628a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < ChildBufferCount; Index++) { 85728a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer[Index] == OpenData->ControllerHandle) { 85828a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 85928a00297189c323096aae8e2975de94e8549613cyshang break; 86028a00297189c323096aae8e2975de94e8549613cyshang } 86128a00297189c323096aae8e2975de94e8549613cyshang } 86228a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 86328a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; 86428a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == ChildBuffer[ChildBufferCount]) { 86528a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = TRUE; 86628a00297189c323096aae8e2975de94e8549613cyshang } 86728a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 86828a00297189c323096aae8e2975de94e8549613cyshang } 86928a00297189c323096aae8e2975de94e8549613cyshang } 87028a00297189c323096aae8e2975de94e8549613cyshang } 87128a00297189c323096aae8e2975de94e8549613cyshang } 87228a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 87328a00297189c323096aae8e2975de94e8549613cyshang } 87428a00297189c323096aae8e2975de94e8549613cyshang 87528a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == NULL || ChildHandleValid) { 87628a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 0; 87728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 87828a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount > 0) { 87928a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 88028a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 1; 88128a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); 88228a00297189c323096aae8e2975de94e8549613cyshang } else { 88328a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = ChildBufferCount; 88428a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); 88528a00297189c323096aae8e2975de94e8549613cyshang } 88628a00297189c323096aae8e2975de94e8549613cyshang } 88728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { 88828a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); 88928a00297189c323096aae8e2975de94e8549613cyshang } 89028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 89128a00297189c323096aae8e2975de94e8549613cyshang StopCount++; 89228a00297189c323096aae8e2975de94e8549613cyshang } 89328a00297189c323096aae8e2975de94e8549613cyshang } 89428a00297189c323096aae8e2975de94e8549613cyshang 89528a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer != NULL) { 89628a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (ChildBuffer); 89728a00297189c323096aae8e2975de94e8549613cyshang } 89828a00297189c323096aae8e2975de94e8549613cyshang } 89928a00297189c323096aae8e2975de94e8549613cyshang } 90028a00297189c323096aae8e2975de94e8549613cyshang 90128a00297189c323096aae8e2975de94e8549613cyshang if (StopCount > 0) { 90285658066182d23e210209299770edaef26d09085mdkinney // 90385658066182d23e210209299770edaef26d09085mdkinney // If the Loaded Image Protocols do not already need to be repaired, then 90485658066182d23e210209299770edaef26d09085mdkinney // check the status of the DeviceHandle field of all Loaded Image Protocols 90585658066182d23e210209299770edaef26d09085mdkinney // to determine if any of them now need repair because a sucessful Stop() 90685658066182d23e210209299770edaef26d09085mdkinney // may have destroyed the DeviceHandle value in the Loaded Image Protocol 90785658066182d23e210209299770edaef26d09085mdkinney // 90885658066182d23e210209299770edaef26d09085mdkinney if (!mRepairLoadedImage) { 90985658066182d23e210209299770edaef26d09085mdkinney // 91085658066182d23e210209299770edaef26d09085mdkinney // Get list of all Loaded Image Protocol Instances 91185658066182d23e210209299770edaef26d09085mdkinney // 91285658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateHandleBuffer ( 91385658066182d23e210209299770edaef26d09085mdkinney ByProtocol, 91485658066182d23e210209299770edaef26d09085mdkinney &gEfiLoadedImageProtocolGuid, 91585658066182d23e210209299770edaef26d09085mdkinney NULL, 91685658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleCount, 91785658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleBuffer 91885658066182d23e210209299770edaef26d09085mdkinney ); 91985658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) { 92085658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < LoadedImageHandleCount; Index++) { 92185658066182d23e210209299770edaef26d09085mdkinney // 92285658066182d23e210209299770edaef26d09085mdkinney // Retrieve the Loaded Image Protocol 92385658066182d23e210209299770edaef26d09085mdkinney // 92485658066182d23e210209299770edaef26d09085mdkinney Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]); 92585658066182d23e210209299770edaef26d09085mdkinney if (Image != NULL) { 92685658066182d23e210209299770edaef26d09085mdkinney // 92785658066182d23e210209299770edaef26d09085mdkinney // Check to see if the DeviceHandle field is a valid handle 92885658066182d23e210209299770edaef26d09085mdkinney // 92985658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (Image->Info.DeviceHandle); 93085658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 93185658066182d23e210209299770edaef26d09085mdkinney // 93285658066182d23e210209299770edaef26d09085mdkinney // The DeviceHandle field is not longer a valid handle. This means 93385658066182d23e210209299770edaef26d09085mdkinney // that future calls to ConnectController() need to attemp to repair 93485658066182d23e210209299770edaef26d09085mdkinney // the Loaded Image Protocols with invalid DeviceHandle fields. Set 93585658066182d23e210209299770edaef26d09085mdkinney // the flag used by ConnectController(). 93685658066182d23e210209299770edaef26d09085mdkinney // 93785658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = TRUE; 93885658066182d23e210209299770edaef26d09085mdkinney break; 93985658066182d23e210209299770edaef26d09085mdkinney } 94085658066182d23e210209299770edaef26d09085mdkinney } 94185658066182d23e210209299770edaef26d09085mdkinney } 94285658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (LoadedImageHandleBuffer); 94385658066182d23e210209299770edaef26d09085mdkinney } 94485658066182d23e210209299770edaef26d09085mdkinney } 94528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 94628a00297189c323096aae8e2975de94e8549613cyshang } else { 94728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 94828a00297189c323096aae8e2975de94e8549613cyshang } 94928a00297189c323096aae8e2975de94e8549613cyshang 95028a00297189c323096aae8e2975de94e8549613cyshangDone: 95128a00297189c323096aae8e2975de94e8549613cyshang 95228a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 95328a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverImageHandleBuffer); 95428a00297189c323096aae8e2975de94e8549613cyshang } 95528a00297189c323096aae8e2975de94e8549613cyshang 95628a00297189c323096aae8e2975de94e8549613cyshang return Status; 95728a00297189c323096aae8e2975de94e8549613cyshang} 95828a00297189c323096aae8e2975de94e8549613cyshang 95928a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 96028a00297189c323096aae8e2975de94e8549613cyshangGetHandleFromDriverBinding ( 96128a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed, 96228a00297189c323096aae8e2975de94e8549613cyshang OUT EFI_HANDLE *Handle 96328a00297189c323096aae8e2975de94e8549613cyshang ) 96428a00297189c323096aae8e2975de94e8549613cyshang/*++ 96528a00297189c323096aae8e2975de94e8549613cyshang 96628a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 96728a00297189c323096aae8e2975de94e8549613cyshang 96828a00297189c323096aae8e2975de94e8549613cyshang Locate the driver binding handle which a specified driver binding protocol installed on. 96928a00297189c323096aae8e2975de94e8549613cyshang 97028a00297189c323096aae8e2975de94e8549613cyshangArguments: 97128a00297189c323096aae8e2975de94e8549613cyshang 97228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingNeed - The specified driver binding protocol. 97328a00297189c323096aae8e2975de94e8549613cyshang 97428a00297189c323096aae8e2975de94e8549613cyshang Handle - The driver binding handle which the protocol installed on. 97528a00297189c323096aae8e2975de94e8549613cyshang 97628a00297189c323096aae8e2975de94e8549613cyshang 97728a00297189c323096aae8e2975de94e8549613cyshangReturns: 97828a00297189c323096aae8e2975de94e8549613cyshang 97928a00297189c323096aae8e2975de94e8549613cyshang EFI_NOT_FOUND - Could not find the handle. 98028a00297189c323096aae8e2975de94e8549613cyshang 98128a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - Successfully find the associated driver binding handle. 98228a00297189c323096aae8e2975de94e8549613cyshang 98328a00297189c323096aae8e2975de94e8549613cyshang--*/ 98428a00297189c323096aae8e2975de94e8549613cyshang { 98528a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status ; 98628a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 98728a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 98828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 98928a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 99028a00297189c323096aae8e2975de94e8549613cyshang 99128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 99228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 99328a00297189c323096aae8e2975de94e8549613cyshang *Handle = NULL_HANDLE; 99428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 99528a00297189c323096aae8e2975de94e8549613cyshang ByProtocol, 99628a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 99728a00297189c323096aae8e2975de94e8549613cyshang NULL, 99828a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleCount, 99928a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleBuffer 100028a00297189c323096aae8e2975de94e8549613cyshang ); 100128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) { 100228a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 100328a00297189c323096aae8e2975de94e8549613cyshang } 100428a00297189c323096aae8e2975de94e8549613cyshang 100528a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) { 100628a00297189c323096aae8e2975de94e8549613cyshang Status = CoreOpenProtocol( 100728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 100828a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 100928a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding, 101028a00297189c323096aae8e2975de94e8549613cyshang gDxeCoreImageHandle, 101128a00297189c323096aae8e2975de94e8549613cyshang NULL, 101228a00297189c323096aae8e2975de94e8549613cyshang EFI_OPEN_PROTOCOL_GET_PROTOCOL 101328a00297189c323096aae8e2975de94e8549613cyshang ); 101428a00297189c323096aae8e2975de94e8549613cyshang 101528a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && DriverBinding != NULL) { 101628a00297189c323096aae8e2975de94e8549613cyshang 101728a00297189c323096aae8e2975de94e8549613cyshang if ( DriverBinding == DriverBindingNeed ) { 101828a00297189c323096aae8e2975de94e8549613cyshang *Handle = DriverBindingHandleBuffer[Index]; 101928a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 102028a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS ; 102128a00297189c323096aae8e2975de94e8549613cyshang } 102228a00297189c323096aae8e2975de94e8549613cyshang } 102328a00297189c323096aae8e2975de94e8549613cyshang } 102428a00297189c323096aae8e2975de94e8549613cyshang 102528a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 102628a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND ; 102728a00297189c323096aae8e2975de94e8549613cyshang} 102828a00297189c323096aae8e2975de94e8549613cyshang 1029