DriverSupport.c revision adc8840a2517db5d93fbdba93f5f51d94ee0fb39
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 3228a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 3328a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 3428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 3528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 3628a00297189c323096aae8e2975de94e8549613cyshang ); 3728a00297189c323096aae8e2975de94e8549613cyshang 3828a00297189c323096aae8e2975de94e8549613cyshang// 3928a00297189c323096aae8e2975de94e8549613cyshang// Driver Support Functions 4028a00297189c323096aae8e2975de94e8549613cyshang// 4128a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 4228a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 4328a00297189c323096aae8e2975de94e8549613cyshangCoreConnectController ( 4428a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 4528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *DriverImageHandle OPTIONAL, 4628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, 4728a00297189c323096aae8e2975de94e8549613cyshang IN BOOLEAN Recursive 4828a00297189c323096aae8e2975de94e8549613cyshang ) 4928a00297189c323096aae8e2975de94e8549613cyshang/*++ 5028a00297189c323096aae8e2975de94e8549613cyshang 5128a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 5228a00297189c323096aae8e2975de94e8549613cyshang 5328a00297189c323096aae8e2975de94e8549613cyshang Connects one or more drivers to a controller. 5428a00297189c323096aae8e2975de94e8549613cyshang 5528a00297189c323096aae8e2975de94e8549613cyshangArguments: 5628a00297189c323096aae8e2975de94e8549613cyshang 5728a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - Handle of the controller to be connected. 5828a00297189c323096aae8e2975de94e8549613cyshang 5928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles. 6028a00297189c323096aae8e2975de94e8549613cyshang 6128a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the 6228a00297189c323096aae8e2975de94e8549613cyshang controller specified by ControllerHandle. 6328a00297189c323096aae8e2975de94e8549613cyshang 6428a00297189c323096aae8e2975de94e8549613cyshang Recursive - Whether the function would be called recursively or not. 6528a00297189c323096aae8e2975de94e8549613cyshang 6628a00297189c323096aae8e2975de94e8549613cyshangReturns: 6728a00297189c323096aae8e2975de94e8549613cyshang 6828a00297189c323096aae8e2975de94e8549613cyshang Status code. 6928a00297189c323096aae8e2975de94e8549613cyshang 7028a00297189c323096aae8e2975de94e8549613cyshang--*/ 7128a00297189c323096aae8e2975de94e8549613cyshang{ 7228a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 7328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS ReturnStatus; 7428a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 7528a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 7628a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 7728a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 7828a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 7928a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath; 8085658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *ChildHandleBuffer; 8185658066182d23e210209299770edaef26d09085mdkinney UINTN ChildHandleCount; 8285658066182d23e210209299770edaef26d09085mdkinney UINTN Index; 8385658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *LoadedImageHandleBuffer; 8485658066182d23e210209299770edaef26d09085mdkinney UINTN LoadedImageHandleCount; 8585658066182d23e210209299770edaef26d09085mdkinney LOADED_IMAGE_PRIVATE_DATA *Image; 8685658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE DeviceHandle; 8785658066182d23e210209299770edaef26d09085mdkinney EFI_DEVICE_PATH_PROTOCOL *DevicePath; 8828a00297189c323096aae8e2975de94e8549613cyshang 8928a00297189c323096aae8e2975de94e8549613cyshang // 9028a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 9128a00297189c323096aae8e2975de94e8549613cyshang // 9228a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 9328a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 9428a00297189c323096aae8e2975de94e8549613cyshang return Status; 9528a00297189c323096aae8e2975de94e8549613cyshang } 9628a00297189c323096aae8e2975de94e8549613cyshang 9728a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 9828a00297189c323096aae8e2975de94e8549613cyshang 9928a00297189c323096aae8e2975de94e8549613cyshang // 10085658066182d23e210209299770edaef26d09085mdkinney // Make a copy of RemainingDevicePath to guanatee it is aligned 10128a00297189c323096aae8e2975de94e8549613cyshang // 10228a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = NULL; 10328a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 10428a00297189c323096aae8e2975de94e8549613cyshang AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath); 10528a00297189c323096aae8e2975de94e8549613cyshang } 10628a00297189c323096aae8e2975de94e8549613cyshang 10728a00297189c323096aae8e2975de94e8549613cyshang // 10885658066182d23e210209299770edaef26d09085mdkinney // Connect all drivers to ControllerHandle 10985658066182d23e210209299770edaef26d09085mdkinney // If CoreConnectSingleController returns EFI_NOT_READY, then the number of 11085658066182d23e210209299770edaef26d09085mdkinney // Driver Binding Protocols in the handle database has increased during the call 11185658066182d23e210209299770edaef26d09085mdkinney // so the connect operation must be restarted 11228a00297189c323096aae8e2975de94e8549613cyshang // 11385658066182d23e210209299770edaef26d09085mdkinney do { 11485658066182d23e210209299770edaef26d09085mdkinney ReturnStatus = CoreConnectSingleController ( 11585658066182d23e210209299770edaef26d09085mdkinney ControllerHandle, 11685658066182d23e210209299770edaef26d09085mdkinney DriverImageHandle, 11785658066182d23e210209299770edaef26d09085mdkinney AlignedRemainingDevicePath 11885658066182d23e210209299770edaef26d09085mdkinney ); 11985658066182d23e210209299770edaef26d09085mdkinney } while (ReturnStatus == EFI_NOT_READY); 12085658066182d23e210209299770edaef26d09085mdkinney 12185658066182d23e210209299770edaef26d09085mdkinney // 12285658066182d23e210209299770edaef26d09085mdkinney // Free the aligned copy of RemainingDevicePath 12385658066182d23e210209299770edaef26d09085mdkinney // 12485658066182d23e210209299770edaef26d09085mdkinney if (AlignedRemainingDevicePath != NULL) { 12585658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (AlignedRemainingDevicePath); 12628a00297189c323096aae8e2975de94e8549613cyshang } 12728a00297189c323096aae8e2975de94e8549613cyshang 12828a00297189c323096aae8e2975de94e8549613cyshang // 12928a00297189c323096aae8e2975de94e8549613cyshang // If recursive, then connect all drivers to all of ControllerHandle's children 13028a00297189c323096aae8e2975de94e8549613cyshang // 13185658066182d23e210209299770edaef26d09085mdkinney if (Recursive) { 13285658066182d23e210209299770edaef26d09085mdkinney // 13385658066182d23e210209299770edaef26d09085mdkinney // Acquire the protocol lock on the handle database so the child handles can be collected 13485658066182d23e210209299770edaef26d09085mdkinney // 13585658066182d23e210209299770edaef26d09085mdkinney CoreAcquireProtocolLock (); 13685658066182d23e210209299770edaef26d09085mdkinney 13785658066182d23e210209299770edaef26d09085mdkinney // 13885658066182d23e210209299770edaef26d09085mdkinney // Make sure the DriverBindingHandle is valid 13985658066182d23e210209299770edaef26d09085mdkinney // 14085658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (ControllerHandle); 14185658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 14285658066182d23e210209299770edaef26d09085mdkinney // 14385658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 14485658066182d23e210209299770edaef26d09085mdkinney // 14585658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 14685658066182d23e210209299770edaef26d09085mdkinney 14785658066182d23e210209299770edaef26d09085mdkinney return ReturnStatus; 14885658066182d23e210209299770edaef26d09085mdkinney } 14985658066182d23e210209299770edaef26d09085mdkinney 15085658066182d23e210209299770edaef26d09085mdkinney 15185658066182d23e210209299770edaef26d09085mdkinney // 15285658066182d23e210209299770edaef26d09085mdkinney // Count ControllerHandle's children 15385658066182d23e210209299770edaef26d09085mdkinney // 15485658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 15585658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 15685658066182d23e210209299770edaef26d09085mdkinney for (ProtLink = Prot->OpenList.ForwardLink; 15785658066182d23e210209299770edaef26d09085mdkinney ProtLink != &Prot->OpenList; 15885658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 15985658066182d23e210209299770edaef26d09085mdkinney OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 16085658066182d23e210209299770edaef26d09085mdkinney if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 16185658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 16285658066182d23e210209299770edaef26d09085mdkinney } 16385658066182d23e210209299770edaef26d09085mdkinney } 16485658066182d23e210209299770edaef26d09085mdkinney } 16585658066182d23e210209299770edaef26d09085mdkinney 16685658066182d23e210209299770edaef26d09085mdkinney // 16785658066182d23e210209299770edaef26d09085mdkinney // Allocate a handle buffer for ControllerHandle's children 16885658066182d23e210209299770edaef26d09085mdkinney // 16985658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer = CoreAllocateBootServicesPool (ChildHandleCount * sizeof(EFI_HANDLE)); 17085658066182d23e210209299770edaef26d09085mdkinney 17185658066182d23e210209299770edaef26d09085mdkinney // 17285658066182d23e210209299770edaef26d09085mdkinney // Fill in a handle buffer with ControllerHandle's children 17385658066182d23e210209299770edaef26d09085mdkinney // 17485658066182d23e210209299770edaef26d09085mdkinney for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) { 17585658066182d23e210209299770edaef26d09085mdkinney Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 17685658066182d23e210209299770edaef26d09085mdkinney for (ProtLink = Prot->OpenList.ForwardLink; 17785658066182d23e210209299770edaef26d09085mdkinney ProtLink != &Prot->OpenList; 17885658066182d23e210209299770edaef26d09085mdkinney ProtLink = ProtLink->ForwardLink) { 17928a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 18028a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 18185658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle; 18285658066182d23e210209299770edaef26d09085mdkinney ChildHandleCount++; 18385658066182d23e210209299770edaef26d09085mdkinney } 18485658066182d23e210209299770edaef26d09085mdkinney } 18585658066182d23e210209299770edaef26d09085mdkinney } 18685658066182d23e210209299770edaef26d09085mdkinney 18785658066182d23e210209299770edaef26d09085mdkinney // 18885658066182d23e210209299770edaef26d09085mdkinney // Release the protocol lock on the handle database 18985658066182d23e210209299770edaef26d09085mdkinney // 19085658066182d23e210209299770edaef26d09085mdkinney CoreReleaseProtocolLock (); 19185658066182d23e210209299770edaef26d09085mdkinney 19285658066182d23e210209299770edaef26d09085mdkinney // 19385658066182d23e210209299770edaef26d09085mdkinney // Recursively connect each child handle 19485658066182d23e210209299770edaef26d09085mdkinney // 19585658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < ChildHandleCount; Index++) { 19685658066182d23e210209299770edaef26d09085mdkinney CoreConnectController ( 19785658066182d23e210209299770edaef26d09085mdkinney ChildHandleBuffer[Index], 19885658066182d23e210209299770edaef26d09085mdkinney NULL, 19985658066182d23e210209299770edaef26d09085mdkinney NULL, 20085658066182d23e210209299770edaef26d09085mdkinney TRUE 20185658066182d23e210209299770edaef26d09085mdkinney ); 20285658066182d23e210209299770edaef26d09085mdkinney } 20385658066182d23e210209299770edaef26d09085mdkinney 20485658066182d23e210209299770edaef26d09085mdkinney // 20585658066182d23e210209299770edaef26d09085mdkinney // Free the handle buffer of ControllerHandle's children 20685658066182d23e210209299770edaef26d09085mdkinney // 20785658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (ChildHandleBuffer); 20885658066182d23e210209299770edaef26d09085mdkinney } 20985658066182d23e210209299770edaef26d09085mdkinney 21085658066182d23e210209299770edaef26d09085mdkinney // 21185658066182d23e210209299770edaef26d09085mdkinney // If a Stop() function has been called one or more time successfully, then attempt to 21285658066182d23e210209299770edaef26d09085mdkinney // repair the stale DeviceHandle fields of the Loaded Image Protocols 21385658066182d23e210209299770edaef26d09085mdkinney // 21485658066182d23e210209299770edaef26d09085mdkinney if (mRepairLoadedImage) { 21585658066182d23e210209299770edaef26d09085mdkinney // 21685658066182d23e210209299770edaef26d09085mdkinney // Assume that all Loaded Image Protocols can be repaired 21785658066182d23e210209299770edaef26d09085mdkinney // 21885658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = FALSE; 21985658066182d23e210209299770edaef26d09085mdkinney 22085658066182d23e210209299770edaef26d09085mdkinney // 22185658066182d23e210209299770edaef26d09085mdkinney // Get list of all Loaded Image Protocol Instances 22285658066182d23e210209299770edaef26d09085mdkinney // 22385658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateHandleBuffer ( 22485658066182d23e210209299770edaef26d09085mdkinney ByProtocol, 22585658066182d23e210209299770edaef26d09085mdkinney &gEfiLoadedImageProtocolGuid, 22685658066182d23e210209299770edaef26d09085mdkinney NULL, 22785658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleCount, 22885658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleBuffer 22985658066182d23e210209299770edaef26d09085mdkinney ); 23085658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) { 23185658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < LoadedImageHandleCount; Index++) { 23285658066182d23e210209299770edaef26d09085mdkinney // 23385658066182d23e210209299770edaef26d09085mdkinney // Retrieve the Loaded Image Protocol 23485658066182d23e210209299770edaef26d09085mdkinney // 23585658066182d23e210209299770edaef26d09085mdkinney Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]); 23685658066182d23e210209299770edaef26d09085mdkinney if (Image != NULL) { 23785658066182d23e210209299770edaef26d09085mdkinney // 23885658066182d23e210209299770edaef26d09085mdkinney // Check to see if the DeviceHandle field is a valid handle 23985658066182d23e210209299770edaef26d09085mdkinney // 24085658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (Image->Info.DeviceHandle); 24185658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 24285658066182d23e210209299770edaef26d09085mdkinney // 24385658066182d23e210209299770edaef26d09085mdkinney // The DeviceHandle field is not valid. 24485658066182d23e210209299770edaef26d09085mdkinney // Attempt to locate a device handle with a device path that matches the one 24585658066182d23e210209299770edaef26d09085mdkinney // that was used to originally load the image 24685658066182d23e210209299770edaef26d09085mdkinney // 24785658066182d23e210209299770edaef26d09085mdkinney DevicePath = Image->DeviceHandleDevicePath; 24885658066182d23e210209299770edaef26d09085mdkinney if (DevicePath != NULL) { 24985658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle); 25085658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) { 25185658066182d23e210209299770edaef26d09085mdkinney // 25285658066182d23e210209299770edaef26d09085mdkinney // A device handle with a matching device path was found, so update the Loaded Image Protocol 25385658066182d23e210209299770edaef26d09085mdkinney // with the device handle discovered 25485658066182d23e210209299770edaef26d09085mdkinney // 25585658066182d23e210209299770edaef26d09085mdkinney Image->Info.DeviceHandle = DeviceHandle; 25685658066182d23e210209299770edaef26d09085mdkinney } else { 25785658066182d23e210209299770edaef26d09085mdkinney // 25885658066182d23e210209299770edaef26d09085mdkinney // There is still at least one Loaded Image Protocol that requires repair 25985658066182d23e210209299770edaef26d09085mdkinney // 26085658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = TRUE; 26185658066182d23e210209299770edaef26d09085mdkinney } 26285658066182d23e210209299770edaef26d09085mdkinney } 26385658066182d23e210209299770edaef26d09085mdkinney } 26428a00297189c323096aae8e2975de94e8549613cyshang } 26585658066182d23e210209299770edaef26d09085mdkinney } 26685658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (LoadedImageHandleBuffer); 26728a00297189c323096aae8e2975de94e8549613cyshang } 26828a00297189c323096aae8e2975de94e8549613cyshang } 26985658066182d23e210209299770edaef26d09085mdkinney 27028a00297189c323096aae8e2975de94e8549613cyshang return ReturnStatus; 27128a00297189c323096aae8e2975de94e8549613cyshang} 27228a00297189c323096aae8e2975de94e8549613cyshang 27328a00297189c323096aae8e2975de94e8549613cyshangVOID 27428a00297189c323096aae8e2975de94e8549613cyshangAddSortedDriverBindingProtocol ( 27528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverBindingHandle, 27628a00297189c323096aae8e2975de94e8549613cyshang IN OUT UINTN *NumberOfSortedDriverBindingProtocols, 27728a00297189c323096aae8e2975de94e8549613cyshang IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols, 27828a00297189c323096aae8e2975de94e8549613cyshang IN UINTN DriverBindingHandleCount, 279adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN OUT EFI_HANDLE *DriverBindingHandleBuffer, 280adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney IN BOOLEAN IsImageHandle 28128a00297189c323096aae8e2975de94e8549613cyshang ) 28228a00297189c323096aae8e2975de94e8549613cyshang/*++ 28328a00297189c323096aae8e2975de94e8549613cyshang 28428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 28528a00297189c323096aae8e2975de94e8549613cyshang 28628a00297189c323096aae8e2975de94e8549613cyshang Add Driver Binding Protocols from Context Driver Image Handles to sorted 28728a00297189c323096aae8e2975de94e8549613cyshang Driver Binding Protocol list. 28828a00297189c323096aae8e2975de94e8549613cyshang 28928a00297189c323096aae8e2975de94e8549613cyshangArguments: 29028a00297189c323096aae8e2975de94e8549613cyshang 29128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle - Handle of the driver binding protocol. 29228a00297189c323096aae8e2975de94e8549613cyshang 29328a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols 29428a00297189c323096aae8e2975de94e8549613cyshang 29528a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols - The sorted protocol list. 29628a00297189c323096aae8e2975de94e8549613cyshang 29728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount - Driver Binding Handle Count. 29828a00297189c323096aae8e2975de94e8549613cyshang 29928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified. 30028a00297189c323096aae8e2975de94e8549613cyshang 30128a00297189c323096aae8e2975de94e8549613cyshangReturns: 30228a00297189c323096aae8e2975de94e8549613cyshang 30328a00297189c323096aae8e2975de94e8549613cyshang None. 30428a00297189c323096aae8e2975de94e8549613cyshang 30528a00297189c323096aae8e2975de94e8549613cyshang--*/ 30628a00297189c323096aae8e2975de94e8549613cyshang{ 30728a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 30828a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 30928a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 31028a00297189c323096aae8e2975de94e8549613cyshang 31128a00297189c323096aae8e2975de94e8549613cyshang // 31228a00297189c323096aae8e2975de94e8549613cyshang // Make sure the DriverBindingHandle is valid 31328a00297189c323096aae8e2975de94e8549613cyshang // 31428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (DriverBindingHandle); 31528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 31628a00297189c323096aae8e2975de94e8549613cyshang return; 31728a00297189c323096aae8e2975de94e8549613cyshang } 31828a00297189c323096aae8e2975de94e8549613cyshang 31928a00297189c323096aae8e2975de94e8549613cyshang // 320adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle 321adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list 322adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 323adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (IsImageHandle) { 324adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 325adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Loop through all the Driver Binding Handles 326adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 327adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney for (Index = 0; Index < DriverBindingHandleCount; Index++) { 328adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 329adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle 330adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 331adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 332adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 333adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney &gEfiDriverBindingProtocolGuid, 334adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney (VOID **)&DriverBinding 335adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 336adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 337adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // If the ImageHandle associated with DriverBinding matches DriverBindingHandle, 338adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // then add the DriverBindingProtocol[Index] to the sorted list 339adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 340adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney if (DriverBinding->ImageHandle == DriverBindingHandle) { 341adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney AddSortedDriverBindingProtocol ( 342adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer[Index], 343adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney NumberOfSortedDriverBindingProtocols, 344adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney SortedDriverBindingProtocols, 345adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleCount, 346adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 347adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 348adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney ); 349adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 350adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 351adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney return; 352adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney } 353adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney 354adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney // 35528a00297189c323096aae8e2975de94e8549613cyshang // Retrieve the Driver Binding Protocol from DriverBindingHandle 35628a00297189c323096aae8e2975de94e8549613cyshang // 35728a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol( 35828a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandle, 35928a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 36028a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 36128a00297189c323096aae8e2975de94e8549613cyshang ); 36228a00297189c323096aae8e2975de94e8549613cyshang // 36328a00297189c323096aae8e2975de94e8549613cyshang // If DriverBindingHandle does not support the Driver Binding Protocol then return 36428a00297189c323096aae8e2975de94e8549613cyshang // 36528a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || DriverBinding == NULL) { 36628a00297189c323096aae8e2975de94e8549613cyshang return; 36728a00297189c323096aae8e2975de94e8549613cyshang } 36828a00297189c323096aae8e2975de94e8549613cyshang 36928a00297189c323096aae8e2975de94e8549613cyshang // 37028a00297189c323096aae8e2975de94e8549613cyshang // See if DriverBinding is already in the sorted list 37128a00297189c323096aae8e2975de94e8549613cyshang // 37285658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) { 37328a00297189c323096aae8e2975de94e8549613cyshang if (DriverBinding == SortedDriverBindingProtocols[Index]) { 37428a00297189c323096aae8e2975de94e8549613cyshang return; 37528a00297189c323096aae8e2975de94e8549613cyshang } 37628a00297189c323096aae8e2975de94e8549613cyshang } 37728a00297189c323096aae8e2975de94e8549613cyshang 37828a00297189c323096aae8e2975de94e8549613cyshang // 37928a00297189c323096aae8e2975de94e8549613cyshang // Add DriverBinding to the end of the list 38028a00297189c323096aae8e2975de94e8549613cyshang // 38185658066182d23e210209299770edaef26d09085mdkinney if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) { 38285658066182d23e210209299770edaef26d09085mdkinney SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding; 38385658066182d23e210209299770edaef26d09085mdkinney } 38428a00297189c323096aae8e2975de94e8549613cyshang *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1; 38528a00297189c323096aae8e2975de94e8549613cyshang 38628a00297189c323096aae8e2975de94e8549613cyshang // 38728a00297189c323096aae8e2975de94e8549613cyshang // Mark the cooresponding handle in DriverBindingHandleBuffer as used 38828a00297189c323096aae8e2975de94e8549613cyshang // 38928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 39028a00297189c323096aae8e2975de94e8549613cyshang if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) { 39128a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index] = NULL; 39228a00297189c323096aae8e2975de94e8549613cyshang } 39328a00297189c323096aae8e2975de94e8549613cyshang } 39428a00297189c323096aae8e2975de94e8549613cyshang} 39528a00297189c323096aae8e2975de94e8549613cyshang 39628a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 39728a00297189c323096aae8e2975de94e8549613cyshangCoreConnectSingleController ( 39828a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 39928a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL, 40028a00297189c323096aae8e2975de94e8549613cyshang IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 40128a00297189c323096aae8e2975de94e8549613cyshang ) 40228a00297189c323096aae8e2975de94e8549613cyshang/*++ 40328a00297189c323096aae8e2975de94e8549613cyshang 40428a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 40528a00297189c323096aae8e2975de94e8549613cyshang 40628a00297189c323096aae8e2975de94e8549613cyshang Connects a controller to a driver. 40728a00297189c323096aae8e2975de94e8549613cyshang 40828a00297189c323096aae8e2975de94e8549613cyshangArguments: 40928a00297189c323096aae8e2975de94e8549613cyshang 41028a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - Handle of the controller to be connected. 41128a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles. 41228a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child 41328a00297189c323096aae8e2975de94e8549613cyshang of the controller specified by ControllerHandle. 41428a00297189c323096aae8e2975de94e8549613cyshang 41528a00297189c323096aae8e2975de94e8549613cyshangReturns: 41628a00297189c323096aae8e2975de94e8549613cyshang 41728a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - One or more drivers were connected to ControllerHandle. 41828a00297189c323096aae8e2975de94e8549613cyshang EFI_OUT_OF_RESOURCES - No enough system resources to complete the request. 41928a00297189c323096aae8e2975de94e8549613cyshang EFI_NOT_FOUND - No drivers were connected to ControllerHandle. 42028a00297189c323096aae8e2975de94e8549613cyshang 42128a00297189c323096aae8e2975de94e8549613cyshang--*/ 42228a00297189c323096aae8e2975de94e8549613cyshang{ 42328a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 42428a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 42528a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE DriverImageHandle; 42628a00297189c323096aae8e2975de94e8549613cyshang EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride; 42728a00297189c323096aae8e2975de94e8549613cyshang EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride; 42828a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverBindingHandleCount; 42928a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverBindingHandleBuffer; 43028a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 43128a00297189c323096aae8e2975de94e8549613cyshang UINTN NumberOfSortedDriverBindingProtocols; 43228a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols; 43328a00297189c323096aae8e2975de94e8549613cyshang UINT32 HighestVersion; 43428a00297189c323096aae8e2975de94e8549613cyshang UINTN HighestIndex; 43528a00297189c323096aae8e2975de94e8549613cyshang UINTN SortIndex; 43628a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN OneStarted; 43728a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverFound; 43828a00297189c323096aae8e2975de94e8549613cyshang 43928a00297189c323096aae8e2975de94e8549613cyshang // 44028a00297189c323096aae8e2975de94e8549613cyshang // Initialize local variables 44128a00297189c323096aae8e2975de94e8549613cyshang // 44228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount = 0; 44328a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer = NULL; 44428a00297189c323096aae8e2975de94e8549613cyshang NumberOfSortedDriverBindingProtocols = 0; 44528a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = NULL; 44628a00297189c323096aae8e2975de94e8549613cyshang 44728a00297189c323096aae8e2975de94e8549613cyshang // 44828a00297189c323096aae8e2975de94e8549613cyshang // Get list of all Driver Binding Protocol Instances 44928a00297189c323096aae8e2975de94e8549613cyshang // 45028a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateHandleBuffer ( 45128a00297189c323096aae8e2975de94e8549613cyshang ByProtocol, 45228a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 45328a00297189c323096aae8e2975de94e8549613cyshang NULL, 45428a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleCount, 45528a00297189c323096aae8e2975de94e8549613cyshang &DriverBindingHandleBuffer 45628a00297189c323096aae8e2975de94e8549613cyshang ); 45728a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) { 45828a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 45928a00297189c323096aae8e2975de94e8549613cyshang } 46028a00297189c323096aae8e2975de94e8549613cyshang 46128a00297189c323096aae8e2975de94e8549613cyshang // 46228a00297189c323096aae8e2975de94e8549613cyshang // Allocate a duplicate array for the sorted Driver Binding Protocol Instances 46328a00297189c323096aae8e2975de94e8549613cyshang // 46428a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount); 46528a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols == NULL) { 46628a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 46728a00297189c323096aae8e2975de94e8549613cyshang return EFI_OUT_OF_RESOURCES; 46828a00297189c323096aae8e2975de94e8549613cyshang } 46928a00297189c323096aae8e2975de94e8549613cyshang 47028a00297189c323096aae8e2975de94e8549613cyshang // 47128a00297189c323096aae8e2975de94e8549613cyshang // Add Driver Binding Protocols from Context Driver Image Handles first 47228a00297189c323096aae8e2975de94e8549613cyshang // 47328a00297189c323096aae8e2975de94e8549613cyshang if (ContextDriverImageHandles != NULL) { 47428a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) { 47528a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 47628a00297189c323096aae8e2975de94e8549613cyshang ContextDriverImageHandles[Index], 47728a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 47828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 47928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 480adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 481adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 48228a00297189c323096aae8e2975de94e8549613cyshang ); 48328a00297189c323096aae8e2975de94e8549613cyshang } 48428a00297189c323096aae8e2975de94e8549613cyshang } 48528a00297189c323096aae8e2975de94e8549613cyshang 48628a00297189c323096aae8e2975de94e8549613cyshang // 48728a00297189c323096aae8e2975de94e8549613cyshang // Add the Platform Driver Override Protocol drivers for ControllerHandle next 48828a00297189c323096aae8e2975de94e8549613cyshang // 48928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreLocateProtocol ( 49028a00297189c323096aae8e2975de94e8549613cyshang &gEfiPlatformDriverOverrideProtocolGuid, 49128a00297189c323096aae8e2975de94e8549613cyshang NULL, 49228a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&PlatformDriverOverride 49328a00297189c323096aae8e2975de94e8549613cyshang ); 49428a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) { 49528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 49628a00297189c323096aae8e2975de94e8549613cyshang do { 49728a00297189c323096aae8e2975de94e8549613cyshang Status = PlatformDriverOverride->GetDriver ( 49828a00297189c323096aae8e2975de94e8549613cyshang PlatformDriverOverride, 49928a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 50028a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 50128a00297189c323096aae8e2975de94e8549613cyshang ); 50228a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 50328a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 50428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 50528a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 50628a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 50728a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 508adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 509adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 51028a00297189c323096aae8e2975de94e8549613cyshang ); 51128a00297189c323096aae8e2975de94e8549613cyshang } 51228a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 51328a00297189c323096aae8e2975de94e8549613cyshang } 51428a00297189c323096aae8e2975de94e8549613cyshang 51528a00297189c323096aae8e2975de94e8549613cyshang // 51628a00297189c323096aae8e2975de94e8549613cyshang // Get the Bus Specific Driver Override Protocol instance on the Controller Handle 51728a00297189c323096aae8e2975de94e8549613cyshang // 518adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney Status = CoreHandleProtocol ( 51928a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 52028a00297189c323096aae8e2975de94e8549613cyshang &gEfiBusSpecificDriverOverrideProtocolGuid, 52128a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&BusSpecificDriverOverride 52228a00297189c323096aae8e2975de94e8549613cyshang ); 52328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) { 52428a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = NULL; 52528a00297189c323096aae8e2975de94e8549613cyshang do { 52628a00297189c323096aae8e2975de94e8549613cyshang Status = BusSpecificDriverOverride->GetDriver ( 52728a00297189c323096aae8e2975de94e8549613cyshang BusSpecificDriverOverride, 52828a00297189c323096aae8e2975de94e8549613cyshang &DriverImageHandle 52928a00297189c323096aae8e2975de94e8549613cyshang ); 53028a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 53128a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 53228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 53328a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 53428a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 53528a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 536adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 537adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney TRUE 53828a00297189c323096aae8e2975de94e8549613cyshang ); 53928a00297189c323096aae8e2975de94e8549613cyshang } 54028a00297189c323096aae8e2975de94e8549613cyshang } while (!EFI_ERROR (Status)); 54128a00297189c323096aae8e2975de94e8549613cyshang } 54228a00297189c323096aae8e2975de94e8549613cyshang 54328a00297189c323096aae8e2975de94e8549613cyshang // 54428a00297189c323096aae8e2975de94e8549613cyshang // Then add all the remaining Driver Binding Protocols 54528a00297189c323096aae8e2975de94e8549613cyshang // 54628a00297189c323096aae8e2975de94e8549613cyshang SortIndex = NumberOfSortedDriverBindingProtocols; 54728a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < DriverBindingHandleCount; Index++) { 54828a00297189c323096aae8e2975de94e8549613cyshang AddSortedDriverBindingProtocol ( 54928a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleBuffer[Index], 55028a00297189c323096aae8e2975de94e8549613cyshang &NumberOfSortedDriverBindingProtocols, 55128a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols, 55228a00297189c323096aae8e2975de94e8549613cyshang DriverBindingHandleCount, 553adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney DriverBindingHandleBuffer, 554adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney FALSE 55528a00297189c323096aae8e2975de94e8549613cyshang ); 55628a00297189c323096aae8e2975de94e8549613cyshang } 55728a00297189c323096aae8e2975de94e8549613cyshang 55828a00297189c323096aae8e2975de94e8549613cyshang // 55928a00297189c323096aae8e2975de94e8549613cyshang // Free the Driver Binding Handle Buffer 56028a00297189c323096aae8e2975de94e8549613cyshang // 56128a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverBindingHandleBuffer); 56228a00297189c323096aae8e2975de94e8549613cyshang 56328a00297189c323096aae8e2975de94e8549613cyshang // 56485658066182d23e210209299770edaef26d09085mdkinney // If the number of Driver Binding Protocols has increased since this function started, then return 56585658066182d23e210209299770edaef26d09085mdkinney // EFI_NOT_READY, so it will be restarted 56685658066182d23e210209299770edaef26d09085mdkinney // 56785658066182d23e210209299770edaef26d09085mdkinney if (NumberOfSortedDriverBindingProtocols > DriverBindingHandleCount) { 56885658066182d23e210209299770edaef26d09085mdkinney // 56985658066182d23e210209299770edaef26d09085mdkinney // Free any buffers that were allocated with AllocatePool() 57085658066182d23e210209299770edaef26d09085mdkinney // 57185658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (SortedDriverBindingProtocols); 57285658066182d23e210209299770edaef26d09085mdkinney 57385658066182d23e210209299770edaef26d09085mdkinney return EFI_NOT_READY; 57485658066182d23e210209299770edaef26d09085mdkinney } 57585658066182d23e210209299770edaef26d09085mdkinney 57685658066182d23e210209299770edaef26d09085mdkinney // 57728a00297189c323096aae8e2975de94e8549613cyshang // Sort the remaining DriverBinding Protocol based on their Version field from 57828a00297189c323096aae8e2975de94e8549613cyshang // highest to lowest. 57928a00297189c323096aae8e2975de94e8549613cyshang // 58028a00297189c323096aae8e2975de94e8549613cyshang for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) { 58128a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version; 58228a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = SortIndex; 58328a00297189c323096aae8e2975de94e8549613cyshang for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) { 58428a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) { 58528a00297189c323096aae8e2975de94e8549613cyshang HighestVersion = SortedDriverBindingProtocols[Index]->Version; 58628a00297189c323096aae8e2975de94e8549613cyshang HighestIndex = Index; 58728a00297189c323096aae8e2975de94e8549613cyshang } 58828a00297189c323096aae8e2975de94e8549613cyshang } 58928a00297189c323096aae8e2975de94e8549613cyshang if (SortIndex != HighestIndex) { 59028a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[SortIndex]; 59128a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex]; 59228a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[HighestIndex] = DriverBinding; 59328a00297189c323096aae8e2975de94e8549613cyshang } 59428a00297189c323096aae8e2975de94e8549613cyshang } 59528a00297189c323096aae8e2975de94e8549613cyshang 59628a00297189c323096aae8e2975de94e8549613cyshang // 59728a00297189c323096aae8e2975de94e8549613cyshang // Loop until no more drivers can be started on ControllerHandle 59828a00297189c323096aae8e2975de94e8549613cyshang // 59928a00297189c323096aae8e2975de94e8549613cyshang OneStarted = FALSE; 60028a00297189c323096aae8e2975de94e8549613cyshang do { 60128a00297189c323096aae8e2975de94e8549613cyshang 60228a00297189c323096aae8e2975de94e8549613cyshang // 60328a00297189c323096aae8e2975de94e8549613cyshang // Loop through the sorted Driver Binding Protocol Instances in order, and see if 60428a00297189c323096aae8e2975de94e8549613cyshang // any of the Driver Binding Protocols support the controller specified by 60528a00297189c323096aae8e2975de94e8549613cyshang // ControllerHandle. 60628a00297189c323096aae8e2975de94e8549613cyshang // 60728a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = NULL; 60828a00297189c323096aae8e2975de94e8549613cyshang DriverFound = FALSE; 60928a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) { 61028a00297189c323096aae8e2975de94e8549613cyshang if (SortedDriverBindingProtocols[Index] != NULL) { 61128a00297189c323096aae8e2975de94e8549613cyshang DriverBinding = SortedDriverBindingProtocols[Index]; 61228a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Supported( 61328a00297189c323096aae8e2975de94e8549613cyshang DriverBinding, 61428a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 61528a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 61628a00297189c323096aae8e2975de94e8549613cyshang ); 61728a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 61828a00297189c323096aae8e2975de94e8549613cyshang SortedDriverBindingProtocols[Index] = NULL; 61928a00297189c323096aae8e2975de94e8549613cyshang DriverFound = TRUE; 62028a00297189c323096aae8e2975de94e8549613cyshang 62128a00297189c323096aae8e2975de94e8549613cyshang // 62228a00297189c323096aae8e2975de94e8549613cyshang // A driver was found that supports ControllerHandle, so attempt to start the driver 62328a00297189c323096aae8e2975de94e8549613cyshang // on ControllerHandle. 62428a00297189c323096aae8e2975de94e8549613cyshang // 625adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney PERF_START (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 62628a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Start ( 62728a00297189c323096aae8e2975de94e8549613cyshang DriverBinding, 62828a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle, 62928a00297189c323096aae8e2975de94e8549613cyshang RemainingDevicePath 63028a00297189c323096aae8e2975de94e8549613cyshang ); 631adc8840a2517db5d93fbdba93f5f51d94ee0fb39mdkinney PERF_END (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0); 63228a00297189c323096aae8e2975de94e8549613cyshang 63328a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 63428a00297189c323096aae8e2975de94e8549613cyshang // 63528a00297189c323096aae8e2975de94e8549613cyshang // The driver was successfully started on ControllerHandle, so set a flag 63628a00297189c323096aae8e2975de94e8549613cyshang // 63728a00297189c323096aae8e2975de94e8549613cyshang OneStarted = TRUE; 63828a00297189c323096aae8e2975de94e8549613cyshang } 63928a00297189c323096aae8e2975de94e8549613cyshang } 64028a00297189c323096aae8e2975de94e8549613cyshang } 64128a00297189c323096aae8e2975de94e8549613cyshang } 64228a00297189c323096aae8e2975de94e8549613cyshang } while (DriverFound); 64328a00297189c323096aae8e2975de94e8549613cyshang 64428a00297189c323096aae8e2975de94e8549613cyshang // 64528a00297189c323096aae8e2975de94e8549613cyshang // Free any buffers that were allocated with AllocatePool() 64628a00297189c323096aae8e2975de94e8549613cyshang // 64728a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (SortedDriverBindingProtocols); 64828a00297189c323096aae8e2975de94e8549613cyshang 64928a00297189c323096aae8e2975de94e8549613cyshang // 65028a00297189c323096aae8e2975de94e8549613cyshang // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS. 65128a00297189c323096aae8e2975de94e8549613cyshang // 65228a00297189c323096aae8e2975de94e8549613cyshang if (OneStarted) { 65328a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 65428a00297189c323096aae8e2975de94e8549613cyshang } 65528a00297189c323096aae8e2975de94e8549613cyshang 65628a00297189c323096aae8e2975de94e8549613cyshang // 65728a00297189c323096aae8e2975de94e8549613cyshang // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS 65828a00297189c323096aae8e2975de94e8549613cyshang // 65928a00297189c323096aae8e2975de94e8549613cyshang if (RemainingDevicePath != NULL) { 66028a00297189c323096aae8e2975de94e8549613cyshang if (IsDevicePathEnd (RemainingDevicePath)) { 66128a00297189c323096aae8e2975de94e8549613cyshang return EFI_SUCCESS; 66228a00297189c323096aae8e2975de94e8549613cyshang } 66328a00297189c323096aae8e2975de94e8549613cyshang } 66428a00297189c323096aae8e2975de94e8549613cyshang 66528a00297189c323096aae8e2975de94e8549613cyshang // 66628a00297189c323096aae8e2975de94e8549613cyshang // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND 66728a00297189c323096aae8e2975de94e8549613cyshang // 66828a00297189c323096aae8e2975de94e8549613cyshang return EFI_NOT_FOUND; 66928a00297189c323096aae8e2975de94e8549613cyshang} 67028a00297189c323096aae8e2975de94e8549613cyshang 67128a00297189c323096aae8e2975de94e8549613cyshang 67228a00297189c323096aae8e2975de94e8549613cyshangEFI_STATUS 67328a00297189c323096aae8e2975de94e8549613cyshangEFIAPI 67428a00297189c323096aae8e2975de94e8549613cyshangCoreDisconnectController ( 67528a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ControllerHandle, 67628a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE DriverImageHandle OPTIONAL, 67728a00297189c323096aae8e2975de94e8549613cyshang IN EFI_HANDLE ChildHandle OPTIONAL 67828a00297189c323096aae8e2975de94e8549613cyshang ) 67928a00297189c323096aae8e2975de94e8549613cyshang/*++ 68028a00297189c323096aae8e2975de94e8549613cyshang 68128a00297189c323096aae8e2975de94e8549613cyshangRoutine Description: 68228a00297189c323096aae8e2975de94e8549613cyshang 68328a00297189c323096aae8e2975de94e8549613cyshang Disonnects a controller from a driver 68428a00297189c323096aae8e2975de94e8549613cyshang 68528a00297189c323096aae8e2975de94e8549613cyshangArguments: 68628a00297189c323096aae8e2975de94e8549613cyshang 68728a00297189c323096aae8e2975de94e8549613cyshang ControllerHandle - ControllerHandle The handle of the controller from which driver(s) 68828a00297189c323096aae8e2975de94e8549613cyshang are to be disconnected. 68928a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle. 69028a00297189c323096aae8e2975de94e8549613cyshang ChildHandle - ChildHandle The handle of the child to destroy. 69128a00297189c323096aae8e2975de94e8549613cyshang 69228a00297189c323096aae8e2975de94e8549613cyshangReturns: 69328a00297189c323096aae8e2975de94e8549613cyshang 69428a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - One or more drivers were disconnected from the controller. 69528a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - On entry, no drivers are managing ControllerHandle. 69628a00297189c323096aae8e2975de94e8549613cyshang EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle. 69728a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. 69828a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE. 69928a00297189c323096aae8e2975de94e8549613cyshang EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE. 70028a00297189c323096aae8e2975de94e8549613cyshang EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle. 70128a00297189c323096aae8e2975de94e8549613cyshang EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error. 70228a00297189c323096aae8e2975de94e8549613cyshang 70328a00297189c323096aae8e2975de94e8549613cyshang--*/ 70428a00297189c323096aae8e2975de94e8549613cyshang{ 70528a00297189c323096aae8e2975de94e8549613cyshang EFI_STATUS Status; 70628a00297189c323096aae8e2975de94e8549613cyshang IHANDLE *Handle; 70728a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *DriverImageHandleBuffer; 70828a00297189c323096aae8e2975de94e8549613cyshang EFI_HANDLE *ChildBuffer; 70928a00297189c323096aae8e2975de94e8549613cyshang UINTN Index; 71028a00297189c323096aae8e2975de94e8549613cyshang UINTN HandleIndex; 71128a00297189c323096aae8e2975de94e8549613cyshang UINTN DriverImageHandleCount; 71228a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildrenToStop; 71328a00297189c323096aae8e2975de94e8549613cyshang UINTN ChildBufferCount; 71428a00297189c323096aae8e2975de94e8549613cyshang UINTN StopCount; 71528a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN Duplicate; 71628a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN ChildHandleValid; 71728a00297189c323096aae8e2975de94e8549613cyshang BOOLEAN DriverImageHandleValid; 71828a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *Link; 71928a00297189c323096aae8e2975de94e8549613cyshang LIST_ENTRY *ProtLink; 72028a00297189c323096aae8e2975de94e8549613cyshang OPEN_PROTOCOL_DATA *OpenData; 72128a00297189c323096aae8e2975de94e8549613cyshang PROTOCOL_INTERFACE *Prot; 72228a00297189c323096aae8e2975de94e8549613cyshang EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; 72385658066182d23e210209299770edaef26d09085mdkinney EFI_HANDLE *LoadedImageHandleBuffer; 72485658066182d23e210209299770edaef26d09085mdkinney UINTN LoadedImageHandleCount; 72585658066182d23e210209299770edaef26d09085mdkinney LOADED_IMAGE_PRIVATE_DATA *Image; 72628a00297189c323096aae8e2975de94e8549613cyshang 72728a00297189c323096aae8e2975de94e8549613cyshang // 72828a00297189c323096aae8e2975de94e8549613cyshang // Make sure ControllerHandle is valid 72928a00297189c323096aae8e2975de94e8549613cyshang // 73028a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ControllerHandle); 73128a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 73228a00297189c323096aae8e2975de94e8549613cyshang return Status; 73328a00297189c323096aae8e2975de94e8549613cyshang } 73428a00297189c323096aae8e2975de94e8549613cyshang 73528a00297189c323096aae8e2975de94e8549613cyshang // 73628a00297189c323096aae8e2975de94e8549613cyshang // Make sure ChildHandle is valid if it is not NULL 73728a00297189c323096aae8e2975de94e8549613cyshang // 73828a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 73928a00297189c323096aae8e2975de94e8549613cyshang Status = CoreValidateHandle (ChildHandle); 74028a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 74128a00297189c323096aae8e2975de94e8549613cyshang return Status; 74228a00297189c323096aae8e2975de94e8549613cyshang } 74328a00297189c323096aae8e2975de94e8549613cyshang } 74428a00297189c323096aae8e2975de94e8549613cyshang 74528a00297189c323096aae8e2975de94e8549613cyshang Handle = ControllerHandle; 74628a00297189c323096aae8e2975de94e8549613cyshang 74728a00297189c323096aae8e2975de94e8549613cyshang // 74828a00297189c323096aae8e2975de94e8549613cyshang // Get list of drivers that are currently managing ControllerHandle 74928a00297189c323096aae8e2975de94e8549613cyshang // 75028a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = NULL; 75128a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 1; 75228a00297189c323096aae8e2975de94e8549613cyshang 75328a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandle == NULL) { 75428a00297189c323096aae8e2975de94e8549613cyshang // 75528a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 75628a00297189c323096aae8e2975de94e8549613cyshang // 75728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 75828a00297189c323096aae8e2975de94e8549613cyshang 75928a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 76028a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 76128a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 76228a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 76328a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 76428a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 76528a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 76628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 76728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 76828a00297189c323096aae8e2975de94e8549613cyshang } 76928a00297189c323096aae8e2975de94e8549613cyshang } 77028a00297189c323096aae8e2975de94e8549613cyshang } 77128a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 77228a00297189c323096aae8e2975de94e8549613cyshang 77328a00297189c323096aae8e2975de94e8549613cyshang // 77428a00297189c323096aae8e2975de94e8549613cyshang // If there are no drivers managing this controller, then return EFI_SUCCESS 77528a00297189c323096aae8e2975de94e8549613cyshang // 77628a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleCount == 0) { 77728a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 77828a00297189c323096aae8e2975de94e8549613cyshang goto Done; 77928a00297189c323096aae8e2975de94e8549613cyshang } 78028a00297189c323096aae8e2975de94e8549613cyshang 78128a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount); 78228a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer == NULL) { 78328a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 78428a00297189c323096aae8e2975de94e8549613cyshang goto Done; 78528a00297189c323096aae8e2975de94e8549613cyshang } 78628a00297189c323096aae8e2975de94e8549613cyshang 78728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount = 0; 78828a00297189c323096aae8e2975de94e8549613cyshang 78928a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 79028a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 79128a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 79228a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 79328a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 79428a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 79528a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 79628a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 79728a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 79828a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index< DriverImageHandleCount; Index++) { 79928a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) { 80028a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 80128a00297189c323096aae8e2975de94e8549613cyshang break; 80228a00297189c323096aae8e2975de94e8549613cyshang } 80328a00297189c323096aae8e2975de94e8549613cyshang } 80428a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 80528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle; 80628a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleCount++; 80728a00297189c323096aae8e2975de94e8549613cyshang } 80828a00297189c323096aae8e2975de94e8549613cyshang } 80928a00297189c323096aae8e2975de94e8549613cyshang } 81028a00297189c323096aae8e2975de94e8549613cyshang } 81128a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 81228a00297189c323096aae8e2975de94e8549613cyshang } 81328a00297189c323096aae8e2975de94e8549613cyshang 81428a00297189c323096aae8e2975de94e8549613cyshang StopCount = 0; 81528a00297189c323096aae8e2975de94e8549613cyshang for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) { 81628a00297189c323096aae8e2975de94e8549613cyshang 81728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 81828a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle = DriverImageHandleBuffer[HandleIndex]; 81928a00297189c323096aae8e2975de94e8549613cyshang } 82028a00297189c323096aae8e2975de94e8549613cyshang 82128a00297189c323096aae8e2975de94e8549613cyshang // 82228a00297189c323096aae8e2975de94e8549613cyshang // Get the Driver Binding Protocol of the driver that is managing this controller 82328a00297189c323096aae8e2975de94e8549613cyshang // 82428a00297189c323096aae8e2975de94e8549613cyshang Status = CoreHandleProtocol ( 82528a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandle, 82628a00297189c323096aae8e2975de94e8549613cyshang &gEfiDriverBindingProtocolGuid, 82728a00297189c323096aae8e2975de94e8549613cyshang (VOID **)&DriverBinding 82828a00297189c323096aae8e2975de94e8549613cyshang ); 82928a00297189c323096aae8e2975de94e8549613cyshang if (EFI_ERROR (Status)) { 83028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_INVALID_PARAMETER; 83128a00297189c323096aae8e2975de94e8549613cyshang goto Done; 83228a00297189c323096aae8e2975de94e8549613cyshang } 83328a00297189c323096aae8e2975de94e8549613cyshang 83428a00297189c323096aae8e2975de94e8549613cyshang // 83528a00297189c323096aae8e2975de94e8549613cyshang // Look at each protocol interface for a match 83628a00297189c323096aae8e2975de94e8549613cyshang // 83728a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = FALSE; 83828a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 83928a00297189c323096aae8e2975de94e8549613cyshang 84028a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 84128a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 84228a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 84328a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 84428a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 84528a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 84628a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 84728a00297189c323096aae8e2975de94e8549613cyshang if (OpenData->AgentHandle == DriverImageHandle) { 84828a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { 84928a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 85028a00297189c323096aae8e2975de94e8549613cyshang } 85128a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { 85228a00297189c323096aae8e2975de94e8549613cyshang DriverImageHandleValid = TRUE; 85328a00297189c323096aae8e2975de94e8549613cyshang } 85428a00297189c323096aae8e2975de94e8549613cyshang } 85528a00297189c323096aae8e2975de94e8549613cyshang } 85628a00297189c323096aae8e2975de94e8549613cyshang } 85728a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 85828a00297189c323096aae8e2975de94e8549613cyshang 85928a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleValid) { 86028a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = FALSE; 86128a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = NULL; 86228a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount != 0) { 86328a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount); 86428a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer == NULL) { 86528a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_OUT_OF_RESOURCES; 86628a00297189c323096aae8e2975de94e8549613cyshang goto Done; 86728a00297189c323096aae8e2975de94e8549613cyshang } 86828a00297189c323096aae8e2975de94e8549613cyshang 86928a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount = 0; 87028a00297189c323096aae8e2975de94e8549613cyshang 87128a00297189c323096aae8e2975de94e8549613cyshang CoreAcquireProtocolLock (); 87228a00297189c323096aae8e2975de94e8549613cyshang for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { 87328a00297189c323096aae8e2975de94e8549613cyshang Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); 87428a00297189c323096aae8e2975de94e8549613cyshang for (ProtLink = Prot->OpenList.ForwardLink; 87528a00297189c323096aae8e2975de94e8549613cyshang ProtLink != &Prot->OpenList; 87628a00297189c323096aae8e2975de94e8549613cyshang ProtLink = ProtLink->ForwardLink) { 87728a00297189c323096aae8e2975de94e8549613cyshang OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); 87828a00297189c323096aae8e2975de94e8549613cyshang if ((OpenData->AgentHandle == DriverImageHandle) && 87928a00297189c323096aae8e2975de94e8549613cyshang ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) { 88028a00297189c323096aae8e2975de94e8549613cyshang Duplicate = FALSE; 88128a00297189c323096aae8e2975de94e8549613cyshang for (Index = 0; Index < ChildBufferCount; Index++) { 88228a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer[Index] == OpenData->ControllerHandle) { 88328a00297189c323096aae8e2975de94e8549613cyshang Duplicate = TRUE; 88428a00297189c323096aae8e2975de94e8549613cyshang break; 88528a00297189c323096aae8e2975de94e8549613cyshang } 88628a00297189c323096aae8e2975de94e8549613cyshang } 88728a00297189c323096aae8e2975de94e8549613cyshang if (!Duplicate) { 88828a00297189c323096aae8e2975de94e8549613cyshang ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle; 88928a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == ChildBuffer[ChildBufferCount]) { 89028a00297189c323096aae8e2975de94e8549613cyshang ChildHandleValid = TRUE; 89128a00297189c323096aae8e2975de94e8549613cyshang } 89228a00297189c323096aae8e2975de94e8549613cyshang ChildBufferCount++; 89328a00297189c323096aae8e2975de94e8549613cyshang } 89428a00297189c323096aae8e2975de94e8549613cyshang } 89528a00297189c323096aae8e2975de94e8549613cyshang } 89628a00297189c323096aae8e2975de94e8549613cyshang } 89728a00297189c323096aae8e2975de94e8549613cyshang CoreReleaseProtocolLock (); 89828a00297189c323096aae8e2975de94e8549613cyshang } 89928a00297189c323096aae8e2975de94e8549613cyshang 90028a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle == NULL || ChildHandleValid) { 90128a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 0; 90228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 90328a00297189c323096aae8e2975de94e8549613cyshang if (ChildBufferCount > 0) { 90428a00297189c323096aae8e2975de94e8549613cyshang if (ChildHandle != NULL) { 90528a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = 1; 90628a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle); 90728a00297189c323096aae8e2975de94e8549613cyshang } else { 90828a00297189c323096aae8e2975de94e8549613cyshang ChildrenToStop = ChildBufferCount; 90928a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer); 91028a00297189c323096aae8e2975de94e8549613cyshang } 91128a00297189c323096aae8e2975de94e8549613cyshang } 91228a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) { 91328a00297189c323096aae8e2975de94e8549613cyshang Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL); 91428a00297189c323096aae8e2975de94e8549613cyshang } 91528a00297189c323096aae8e2975de94e8549613cyshang if (!EFI_ERROR (Status)) { 91628a00297189c323096aae8e2975de94e8549613cyshang StopCount++; 91728a00297189c323096aae8e2975de94e8549613cyshang } 91828a00297189c323096aae8e2975de94e8549613cyshang } 91928a00297189c323096aae8e2975de94e8549613cyshang 92028a00297189c323096aae8e2975de94e8549613cyshang if (ChildBuffer != NULL) { 92128a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (ChildBuffer); 92228a00297189c323096aae8e2975de94e8549613cyshang } 92328a00297189c323096aae8e2975de94e8549613cyshang } 92428a00297189c323096aae8e2975de94e8549613cyshang } 92528a00297189c323096aae8e2975de94e8549613cyshang 92628a00297189c323096aae8e2975de94e8549613cyshang if (StopCount > 0) { 92785658066182d23e210209299770edaef26d09085mdkinney // 92885658066182d23e210209299770edaef26d09085mdkinney // If the Loaded Image Protocols do not already need to be repaired, then 92985658066182d23e210209299770edaef26d09085mdkinney // check the status of the DeviceHandle field of all Loaded Image Protocols 93085658066182d23e210209299770edaef26d09085mdkinney // to determine if any of them now need repair because a sucessful Stop() 93185658066182d23e210209299770edaef26d09085mdkinney // may have destroyed the DeviceHandle value in the Loaded Image Protocol 93285658066182d23e210209299770edaef26d09085mdkinney // 93385658066182d23e210209299770edaef26d09085mdkinney if (!mRepairLoadedImage) { 93485658066182d23e210209299770edaef26d09085mdkinney // 93585658066182d23e210209299770edaef26d09085mdkinney // Get list of all Loaded Image Protocol Instances 93685658066182d23e210209299770edaef26d09085mdkinney // 93785658066182d23e210209299770edaef26d09085mdkinney Status = CoreLocateHandleBuffer ( 93885658066182d23e210209299770edaef26d09085mdkinney ByProtocol, 93985658066182d23e210209299770edaef26d09085mdkinney &gEfiLoadedImageProtocolGuid, 94085658066182d23e210209299770edaef26d09085mdkinney NULL, 94185658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleCount, 94285658066182d23e210209299770edaef26d09085mdkinney &LoadedImageHandleBuffer 94385658066182d23e210209299770edaef26d09085mdkinney ); 94485658066182d23e210209299770edaef26d09085mdkinney if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) { 94585658066182d23e210209299770edaef26d09085mdkinney for (Index = 0; Index < LoadedImageHandleCount; Index++) { 94685658066182d23e210209299770edaef26d09085mdkinney // 94785658066182d23e210209299770edaef26d09085mdkinney // Retrieve the Loaded Image Protocol 94885658066182d23e210209299770edaef26d09085mdkinney // 94985658066182d23e210209299770edaef26d09085mdkinney Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]); 95085658066182d23e210209299770edaef26d09085mdkinney if (Image != NULL) { 95185658066182d23e210209299770edaef26d09085mdkinney // 95285658066182d23e210209299770edaef26d09085mdkinney // Check to see if the DeviceHandle field is a valid handle 95385658066182d23e210209299770edaef26d09085mdkinney // 95485658066182d23e210209299770edaef26d09085mdkinney Status = CoreValidateHandle (Image->Info.DeviceHandle); 95585658066182d23e210209299770edaef26d09085mdkinney if (EFI_ERROR (Status)) { 95685658066182d23e210209299770edaef26d09085mdkinney // 95785658066182d23e210209299770edaef26d09085mdkinney // The DeviceHandle field is not longer a valid handle. This means 95885658066182d23e210209299770edaef26d09085mdkinney // that future calls to ConnectController() need to attemp to repair 95985658066182d23e210209299770edaef26d09085mdkinney // the Loaded Image Protocols with invalid DeviceHandle fields. Set 96085658066182d23e210209299770edaef26d09085mdkinney // the flag used by ConnectController(). 96185658066182d23e210209299770edaef26d09085mdkinney // 96285658066182d23e210209299770edaef26d09085mdkinney mRepairLoadedImage = TRUE; 96385658066182d23e210209299770edaef26d09085mdkinney break; 96485658066182d23e210209299770edaef26d09085mdkinney } 96585658066182d23e210209299770edaef26d09085mdkinney } 96685658066182d23e210209299770edaef26d09085mdkinney } 96785658066182d23e210209299770edaef26d09085mdkinney CoreFreePool (LoadedImageHandleBuffer); 96885658066182d23e210209299770edaef26d09085mdkinney } 96985658066182d23e210209299770edaef26d09085mdkinney } 97028a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_SUCCESS; 97128a00297189c323096aae8e2975de94e8549613cyshang } else { 97228a00297189c323096aae8e2975de94e8549613cyshang Status = EFI_NOT_FOUND; 97328a00297189c323096aae8e2975de94e8549613cyshang } 97428a00297189c323096aae8e2975de94e8549613cyshang 97528a00297189c323096aae8e2975de94e8549613cyshangDone: 97628a00297189c323096aae8e2975de94e8549613cyshang 97728a00297189c323096aae8e2975de94e8549613cyshang if (DriverImageHandleBuffer != NULL) { 97828a00297189c323096aae8e2975de94e8549613cyshang CoreFreePool (DriverImageHandleBuffer); 97928a00297189c323096aae8e2975de94e8549613cyshang } 98028a00297189c323096aae8e2975de94e8549613cyshang 98128a00297189c323096aae8e2975de94e8549613cyshang return Status; 98228a00297189c323096aae8e2975de94e8549613cyshang} 983