mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-11-03 21:17:23 +01:00 
			
		
		
		
	REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the MdeModulePkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
		
			
				
	
	
		
			990 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			990 lines
		
	
	
		
			35 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Support functions to connect/disconnect UEFI Driver model Protocol
 | 
						|
 | 
						|
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "DxeMain.h"
 | 
						|
#include "Handle.h"
 | 
						|
 | 
						|
//
 | 
						|
// Driver Support Functions
 | 
						|
//
 | 
						|
 | 
						|
/**
 | 
						|
  Connects one or more drivers to a controller.
 | 
						|
 | 
						|
  @param  ControllerHandle      The handle of the controller to which driver(s) are to be connected.
 | 
						|
  @param  DriverImageHandle     A pointer to an ordered list handles that support the
 | 
						|
                                EFI_DRIVER_BINDING_PROTOCOL.
 | 
						|
  @param  RemainingDevicePath   A pointer to the device path that specifies a child of the
 | 
						|
                                controller specified by ControllerHandle.
 | 
						|
  @param  Recursive             If TRUE, then ConnectController() is called recursively
 | 
						|
                                until the entire tree of controllers below the controller specified
 | 
						|
                                by ControllerHandle have been created. If FALSE, then
 | 
						|
                                the tree of controllers is only expanded one level.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           1) One or more drivers were connected to ControllerHandle.
 | 
						|
                                2) No drivers were connected to ControllerHandle, but
 | 
						|
                                RemainingDevicePath is not NULL, and it is an End Device
 | 
						|
                                Path Node.
 | 
						|
  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
 | 
						|
  @retval EFI_NOT_FOUND         1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
 | 
						|
                                present in the system.
 | 
						|
                                2) No drivers were connected to ControllerHandle.
 | 
						|
  @retval EFI_SECURITY_VIOLATION
 | 
						|
                                The user has no permission to start UEFI device drivers on the device path
 | 
						|
                                associated with the ControllerHandle or specified by the RemainingDevicePath.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
CoreConnectController (
 | 
						|
  IN  EFI_HANDLE                ControllerHandle,
 | 
						|
  IN  EFI_HANDLE                *DriverImageHandle    OPTIONAL,
 | 
						|
  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath  OPTIONAL,
 | 
						|
  IN  BOOLEAN                   Recursive
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  EFI_STATUS                ReturnStatus;
 | 
						|
  IHANDLE                   *Handle;
 | 
						|
  PROTOCOL_INTERFACE        *Prot;
 | 
						|
  LIST_ENTRY                *Link;
 | 
						|
  LIST_ENTRY                *ProtLink;
 | 
						|
  OPEN_PROTOCOL_DATA        *OpenData;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *AlignedRemainingDevicePath;
 | 
						|
  EFI_HANDLE                *ChildHandleBuffer;
 | 
						|
  UINTN                     ChildHandleCount;
 | 
						|
  UINTN                     Index;
 | 
						|
  UINTN                     HandleFilePathSize;
 | 
						|
  UINTN                     RemainingDevicePathSize;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *HandleFilePath;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *FilePath;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL  *TempFilePath;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure ControllerHandle is valid
 | 
						|
  //
 | 
						|
  CoreAcquireProtocolLock ();
 | 
						|
 | 
						|
  Status = CoreValidateHandle (ControllerHandle);
 | 
						|
 | 
						|
  CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  if (gSecurity2 != NULL) {
 | 
						|
    //
 | 
						|
    // Check whether the user has permission to start UEFI device drivers.
 | 
						|
    //
 | 
						|
    Status = CoreHandleProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&HandleFilePath);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      ASSERT (HandleFilePath != NULL);
 | 
						|
      FilePath     = HandleFilePath;
 | 
						|
      TempFilePath = NULL;
 | 
						|
      if ((RemainingDevicePath != NULL) && !Recursive) {
 | 
						|
        HandleFilePathSize      = GetDevicePathSize (HandleFilePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
 | 
						|
        RemainingDevicePathSize = GetDevicePathSize (RemainingDevicePath);
 | 
						|
        TempFilePath            = AllocateZeroPool (HandleFilePathSize + RemainingDevicePathSize);
 | 
						|
        ASSERT (TempFilePath != NULL);
 | 
						|
        CopyMem (TempFilePath, HandleFilePath, HandleFilePathSize);
 | 
						|
        CopyMem ((UINT8 *)TempFilePath + HandleFilePathSize, RemainingDevicePath, RemainingDevicePathSize);
 | 
						|
        FilePath = TempFilePath;
 | 
						|
      }
 | 
						|
 | 
						|
      Status = gSecurity2->FileAuthentication (
 | 
						|
                             gSecurity2,
 | 
						|
                             FilePath,
 | 
						|
                             NULL,
 | 
						|
                             0,
 | 
						|
                             FALSE
 | 
						|
                             );
 | 
						|
      if (TempFilePath != NULL) {
 | 
						|
        FreePool (TempFilePath);
 | 
						|
      }
 | 
						|
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        return Status;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Handle = ControllerHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make a copy of RemainingDevicePath to guanatee it is aligned
 | 
						|
  //
 | 
						|
  AlignedRemainingDevicePath = NULL;
 | 
						|
  if (RemainingDevicePath != NULL) {
 | 
						|
    AlignedRemainingDevicePath = DuplicateDevicePath (RemainingDevicePath);
 | 
						|
 | 
						|
    if (AlignedRemainingDevicePath == NULL) {
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Connect all drivers to ControllerHandle
 | 
						|
  // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
 | 
						|
  // Driver Binding Protocols in the handle database has increased during the call
 | 
						|
  // so the connect operation must be restarted
 | 
						|
  //
 | 
						|
  do {
 | 
						|
    ReturnStatus = CoreConnectSingleController (
 | 
						|
                     ControllerHandle,
 | 
						|
                     DriverImageHandle,
 | 
						|
                     AlignedRemainingDevicePath
 | 
						|
                     );
 | 
						|
  } while (ReturnStatus == EFI_NOT_READY);
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the aligned copy of RemainingDevicePath
 | 
						|
  //
 | 
						|
  if (AlignedRemainingDevicePath != NULL) {
 | 
						|
    CoreFreePool (AlignedRemainingDevicePath);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If recursive, then connect all drivers to all of ControllerHandle's children
 | 
						|
  //
 | 
						|
  if (Recursive) {
 | 
						|
    //
 | 
						|
    // Acquire the protocol lock on the handle database so the child handles can be collected
 | 
						|
    //
 | 
						|
    CoreAcquireProtocolLock ();
 | 
						|
 | 
						|
    //
 | 
						|
    // Make sure the DriverBindingHandle is valid
 | 
						|
    //
 | 
						|
    Status = CoreValidateHandle (ControllerHandle);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Release the protocol lock on the handle database
 | 
						|
      //
 | 
						|
      CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
      return ReturnStatus;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Count ControllerHandle's children
 | 
						|
    //
 | 
						|
    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
      for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
           ProtLink != &Prot->OpenList;
 | 
						|
           ProtLink = ProtLink->ForwardLink)
 | 
						|
      {
 | 
						|
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
 | 
						|
          ChildHandleCount++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Allocate a handle buffer for ControllerHandle's children
 | 
						|
    //
 | 
						|
    ChildHandleBuffer = AllocatePool (ChildHandleCount * sizeof (EFI_HANDLE));
 | 
						|
    if (ChildHandleBuffer == NULL) {
 | 
						|
      CoreReleaseProtocolLock ();
 | 
						|
      return EFI_OUT_OF_RESOURCES;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Fill in a handle buffer with ControllerHandle's children
 | 
						|
    //
 | 
						|
    for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
      for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
           ProtLink != &Prot->OpenList;
 | 
						|
           ProtLink = ProtLink->ForwardLink)
 | 
						|
      {
 | 
						|
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
 | 
						|
          ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
 | 
						|
          ChildHandleCount++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Release the protocol lock on the handle database
 | 
						|
    //
 | 
						|
    CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
    //
 | 
						|
    // Recursively connect each child handle
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < ChildHandleCount; Index++) {
 | 
						|
      CoreConnectController (
 | 
						|
        ChildHandleBuffer[Index],
 | 
						|
        NULL,
 | 
						|
        NULL,
 | 
						|
        TRUE
 | 
						|
        );
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Free the handle buffer of ControllerHandle's children
 | 
						|
    //
 | 
						|
    CoreFreePool (ChildHandleBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return ReturnStatus;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Add Driver Binding Protocols from Context Driver Image Handles to sorted
 | 
						|
  Driver Binding Protocol list.
 | 
						|
 | 
						|
  @param  DriverBindingHandle                   Handle of the driver binding
 | 
						|
                                                protocol.
 | 
						|
  @param  NumberOfSortedDriverBindingProtocols  Number Of sorted driver binding
 | 
						|
                                                protocols
 | 
						|
  @param  SortedDriverBindingProtocols          The sorted protocol list.
 | 
						|
  @param  DriverBindingHandleCount              Driver Binding Handle Count.
 | 
						|
  @param  DriverBindingHandleBuffer             The buffer of driver binding
 | 
						|
                                                protocol to be modified.
 | 
						|
  @param  IsImageHandle                         Indicate whether
 | 
						|
                                                DriverBindingHandle is an image
 | 
						|
                                                handle
 | 
						|
 | 
						|
  @return None.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
AddSortedDriverBindingProtocol (
 | 
						|
  IN      EFI_HANDLE                   DriverBindingHandle,
 | 
						|
  IN OUT  UINTN                        *NumberOfSortedDriverBindingProtocols,
 | 
						|
  IN OUT  EFI_DRIVER_BINDING_PROTOCOL  **SortedDriverBindingProtocols,
 | 
						|
  IN      UINTN                        DriverBindingHandleCount,
 | 
						|
  IN OUT  EFI_HANDLE                   *DriverBindingHandleBuffer,
 | 
						|
  IN      BOOLEAN                      IsImageHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                   Status;
 | 
						|
  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;
 | 
						|
  UINTN                        Index;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure the DriverBindingHandle is valid
 | 
						|
  //
 | 
						|
  CoreAcquireProtocolLock ();
 | 
						|
 | 
						|
  Status = CoreValidateHandle (DriverBindingHandle);
 | 
						|
 | 
						|
  CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
 | 
						|
  // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
 | 
						|
  //
 | 
						|
  if (IsImageHandle) {
 | 
						|
    //
 | 
						|
    // Loop through all the Driver Binding Handles
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < DriverBindingHandleCount; Index++) {
 | 
						|
      //
 | 
						|
      // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
 | 
						|
      //
 | 
						|
      Status = CoreHandleProtocol (
 | 
						|
                 DriverBindingHandleBuffer[Index],
 | 
						|
                 &gEfiDriverBindingProtocolGuid,
 | 
						|
                 (VOID **)&DriverBinding
 | 
						|
                 );
 | 
						|
      if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
 | 
						|
      // then add the DriverBindingProtocol[Index] to the sorted list
 | 
						|
      //
 | 
						|
      if (DriverBinding->ImageHandle == DriverBindingHandle) {
 | 
						|
        AddSortedDriverBindingProtocol (
 | 
						|
          DriverBindingHandleBuffer[Index],
 | 
						|
          NumberOfSortedDriverBindingProtocols,
 | 
						|
          SortedDriverBindingProtocols,
 | 
						|
          DriverBindingHandleCount,
 | 
						|
          DriverBindingHandleBuffer,
 | 
						|
          FALSE
 | 
						|
          );
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Retrieve the Driver Binding Protocol from DriverBindingHandle
 | 
						|
  //
 | 
						|
  Status = CoreHandleProtocol (
 | 
						|
             DriverBindingHandle,
 | 
						|
             &gEfiDriverBindingProtocolGuid,
 | 
						|
             (VOID **)&DriverBinding
 | 
						|
             );
 | 
						|
  //
 | 
						|
  // If DriverBindingHandle does not support the Driver Binding Protocol then return
 | 
						|
  //
 | 
						|
  if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // See if DriverBinding is already in the sorted list
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
 | 
						|
    if (DriverBinding == SortedDriverBindingProtocols[Index]) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add DriverBinding to the end of the list
 | 
						|
  //
 | 
						|
  if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
 | 
						|
    SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
 | 
						|
  }
 | 
						|
 | 
						|
  *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
 | 
						|
 | 
						|
  //
 | 
						|
  // Mark the cooresponding handle in DriverBindingHandleBuffer as used
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
 | 
						|
    if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
 | 
						|
      DriverBindingHandleBuffer[Index] = NULL;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Connects a controller to a driver.
 | 
						|
 | 
						|
  @param  ControllerHandle                      Handle of the controller to be
 | 
						|
                                                connected.
 | 
						|
  @param  ContextDriverImageHandles             DriverImageHandle A pointer to an
 | 
						|
                                                ordered list of driver image
 | 
						|
                                                handles.
 | 
						|
  @param  RemainingDevicePath                   RemainingDevicePath A pointer to
 | 
						|
                                                the device path that specifies a
 | 
						|
                                                child  of the controller
 | 
						|
                                                specified by ControllerHandle.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS                           One or more drivers were
 | 
						|
                                                connected to ControllerHandle.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES                  No enough system resources to
 | 
						|
                                                complete the request.
 | 
						|
  @retval EFI_NOT_FOUND                         No drivers were connected to
 | 
						|
                                                ControllerHandle.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
CoreConnectSingleController (
 | 
						|
  IN  EFI_HANDLE                ControllerHandle,
 | 
						|
  IN  EFI_HANDLE                *ContextDriverImageHandles OPTIONAL,
 | 
						|
  IN  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath       OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                                 Status;
 | 
						|
  UINTN                                      Index;
 | 
						|
  EFI_HANDLE                                 DriverImageHandle;
 | 
						|
  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL      *PlatformDriverOverride;
 | 
						|
  EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL  *BusSpecificDriverOverride;
 | 
						|
  UINTN                                      DriverBindingHandleCount;
 | 
						|
  EFI_HANDLE                                 *DriverBindingHandleBuffer;
 | 
						|
  UINTN                                      NewDriverBindingHandleCount;
 | 
						|
  EFI_HANDLE                                 *NewDriverBindingHandleBuffer;
 | 
						|
  EFI_DRIVER_BINDING_PROTOCOL                *DriverBinding;
 | 
						|
  EFI_DRIVER_FAMILY_OVERRIDE_PROTOCOL        *DriverFamilyOverride;
 | 
						|
  UINTN                                      NumberOfSortedDriverBindingProtocols;
 | 
						|
  EFI_DRIVER_BINDING_PROTOCOL                **SortedDriverBindingProtocols;
 | 
						|
  UINT32                                     DriverFamilyOverrideVersion;
 | 
						|
  UINT32                                     HighestVersion;
 | 
						|
  UINTN                                      HighestIndex;
 | 
						|
  UINTN                                      SortIndex;
 | 
						|
  BOOLEAN                                    OneStarted;
 | 
						|
  BOOLEAN                                    DriverFound;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize local variables
 | 
						|
  //
 | 
						|
  DriverBindingHandleCount             = 0;
 | 
						|
  DriverBindingHandleBuffer            = NULL;
 | 
						|
  NumberOfSortedDriverBindingProtocols = 0;
 | 
						|
  SortedDriverBindingProtocols         = NULL;
 | 
						|
  PlatformDriverOverride               = NULL;
 | 
						|
  NewDriverBindingHandleBuffer         = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get list of all Driver Binding Protocol Instances
 | 
						|
  //
 | 
						|
  Status = CoreLocateHandleBuffer (
 | 
						|
             ByProtocol,
 | 
						|
             &gEfiDriverBindingProtocolGuid,
 | 
						|
             NULL,
 | 
						|
             &DriverBindingHandleCount,
 | 
						|
             &DriverBindingHandleBuffer
 | 
						|
             );
 | 
						|
  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
 | 
						|
  //
 | 
						|
  SortedDriverBindingProtocols = AllocatePool (sizeof (VOID *) * DriverBindingHandleCount);
 | 
						|
  if (SortedDriverBindingProtocols == NULL) {
 | 
						|
    CoreFreePool (DriverBindingHandleBuffer);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add Driver Binding Protocols from Context Driver Image Handles first
 | 
						|
  //
 | 
						|
  if (ContextDriverImageHandles != NULL) {
 | 
						|
    for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
 | 
						|
      AddSortedDriverBindingProtocol (
 | 
						|
        ContextDriverImageHandles[Index],
 | 
						|
        &NumberOfSortedDriverBindingProtocols,
 | 
						|
        SortedDriverBindingProtocols,
 | 
						|
        DriverBindingHandleCount,
 | 
						|
        DriverBindingHandleBuffer,
 | 
						|
        FALSE
 | 
						|
        );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add the Platform Driver Override Protocol drivers for ControllerHandle next
 | 
						|
  //
 | 
						|
  Status = CoreLocateProtocol (
 | 
						|
             &gEfiPlatformDriverOverrideProtocolGuid,
 | 
						|
             NULL,
 | 
						|
             (VOID **)&PlatformDriverOverride
 | 
						|
             );
 | 
						|
  if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
 | 
						|
    DriverImageHandle = NULL;
 | 
						|
    do {
 | 
						|
      Status = PlatformDriverOverride->GetDriver (
 | 
						|
                                         PlatformDriverOverride,
 | 
						|
                                         ControllerHandle,
 | 
						|
                                         &DriverImageHandle
 | 
						|
                                         );
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        AddSortedDriverBindingProtocol (
 | 
						|
          DriverImageHandle,
 | 
						|
          &NumberOfSortedDriverBindingProtocols,
 | 
						|
          SortedDriverBindingProtocols,
 | 
						|
          DriverBindingHandleCount,
 | 
						|
          DriverBindingHandleBuffer,
 | 
						|
          TRUE
 | 
						|
          );
 | 
						|
      }
 | 
						|
    } while (!EFI_ERROR (Status));
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Add the Driver Family Override Protocol drivers for ControllerHandle
 | 
						|
  //
 | 
						|
  while (TRUE) {
 | 
						|
    HighestIndex   = DriverBindingHandleCount;
 | 
						|
    HighestVersion = 0;
 | 
						|
    for (Index = 0; Index < DriverBindingHandleCount; Index++) {
 | 
						|
      Status = CoreHandleProtocol (
 | 
						|
                 DriverBindingHandleBuffer[Index],
 | 
						|
                 &gEfiDriverFamilyOverrideProtocolGuid,
 | 
						|
                 (VOID **)&DriverFamilyOverride
 | 
						|
                 );
 | 
						|
      if (!EFI_ERROR (Status) && (DriverFamilyOverride != NULL)) {
 | 
						|
        DriverFamilyOverrideVersion = DriverFamilyOverride->GetVersion (DriverFamilyOverride);
 | 
						|
        if ((HighestIndex == DriverBindingHandleCount) || (DriverFamilyOverrideVersion > HighestVersion)) {
 | 
						|
          HighestVersion = DriverFamilyOverrideVersion;
 | 
						|
          HighestIndex   = Index;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (HighestIndex == DriverBindingHandleCount) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    AddSortedDriverBindingProtocol (
 | 
						|
      DriverBindingHandleBuffer[HighestIndex],
 | 
						|
      &NumberOfSortedDriverBindingProtocols,
 | 
						|
      SortedDriverBindingProtocols,
 | 
						|
      DriverBindingHandleCount,
 | 
						|
      DriverBindingHandleBuffer,
 | 
						|
      FALSE
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
 | 
						|
  //
 | 
						|
  Status = CoreHandleProtocol (
 | 
						|
             ControllerHandle,
 | 
						|
             &gEfiBusSpecificDriverOverrideProtocolGuid,
 | 
						|
             (VOID **)&BusSpecificDriverOverride
 | 
						|
             );
 | 
						|
  if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
 | 
						|
    DriverImageHandle = NULL;
 | 
						|
    do {
 | 
						|
      Status = BusSpecificDriverOverride->GetDriver (
 | 
						|
                                            BusSpecificDriverOverride,
 | 
						|
                                            &DriverImageHandle
 | 
						|
                                            );
 | 
						|
      if (!EFI_ERROR (Status)) {
 | 
						|
        AddSortedDriverBindingProtocol (
 | 
						|
          DriverImageHandle,
 | 
						|
          &NumberOfSortedDriverBindingProtocols,
 | 
						|
          SortedDriverBindingProtocols,
 | 
						|
          DriverBindingHandleCount,
 | 
						|
          DriverBindingHandleBuffer,
 | 
						|
          TRUE
 | 
						|
          );
 | 
						|
      }
 | 
						|
    } while (!EFI_ERROR (Status));
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Then add all the remaining Driver Binding Protocols
 | 
						|
  //
 | 
						|
  SortIndex = NumberOfSortedDriverBindingProtocols;
 | 
						|
  for (Index = 0; Index < DriverBindingHandleCount; Index++) {
 | 
						|
    AddSortedDriverBindingProtocol (
 | 
						|
      DriverBindingHandleBuffer[Index],
 | 
						|
      &NumberOfSortedDriverBindingProtocols,
 | 
						|
      SortedDriverBindingProtocols,
 | 
						|
      DriverBindingHandleCount,
 | 
						|
      DriverBindingHandleBuffer,
 | 
						|
      FALSE
 | 
						|
      );
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Free the Driver Binding Handle Buffer
 | 
						|
  //
 | 
						|
  CoreFreePool (DriverBindingHandleBuffer);
 | 
						|
 | 
						|
  //
 | 
						|
  // If the number of Driver Binding Protocols has increased since this function started, then return
 | 
						|
  // EFI_NOT_READY, so it will be restarted
 | 
						|
  //
 | 
						|
  Status = CoreLocateHandleBuffer (
 | 
						|
             ByProtocol,
 | 
						|
             &gEfiDriverBindingProtocolGuid,
 | 
						|
             NULL,
 | 
						|
             &NewDriverBindingHandleCount,
 | 
						|
             &NewDriverBindingHandleBuffer
 | 
						|
             );
 | 
						|
  CoreFreePool (NewDriverBindingHandleBuffer);
 | 
						|
  if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
 | 
						|
    //
 | 
						|
    // Free any buffers that were allocated with AllocatePool()
 | 
						|
    //
 | 
						|
    CoreFreePool (SortedDriverBindingProtocols);
 | 
						|
 | 
						|
    return EFI_NOT_READY;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Sort the remaining DriverBinding Protocol based on their Version field from
 | 
						|
  // highest to lowest.
 | 
						|
  //
 | 
						|
  for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
 | 
						|
    HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
 | 
						|
    HighestIndex   = SortIndex;
 | 
						|
    for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
 | 
						|
      if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
 | 
						|
        HighestVersion = SortedDriverBindingProtocols[Index]->Version;
 | 
						|
        HighestIndex   = Index;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (SortIndex != HighestIndex) {
 | 
						|
      DriverBinding                              = SortedDriverBindingProtocols[SortIndex];
 | 
						|
      SortedDriverBindingProtocols[SortIndex]    = SortedDriverBindingProtocols[HighestIndex];
 | 
						|
      SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Loop until no more drivers can be started on ControllerHandle
 | 
						|
  //
 | 
						|
  OneStarted = FALSE;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // Loop through the sorted Driver Binding Protocol Instances in order, and see if
 | 
						|
    // any of the Driver Binding Protocols support the controller specified by
 | 
						|
    // ControllerHandle.
 | 
						|
    //
 | 
						|
    DriverBinding = NULL;
 | 
						|
    DriverFound   = FALSE;
 | 
						|
    for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
 | 
						|
      if (SortedDriverBindingProtocols[Index] != NULL) {
 | 
						|
        DriverBinding = SortedDriverBindingProtocols[Index];
 | 
						|
        PERF_DRIVER_BINDING_SUPPORT_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
 | 
						|
        Status = DriverBinding->Supported (
 | 
						|
                                  DriverBinding,
 | 
						|
                                  ControllerHandle,
 | 
						|
                                  RemainingDevicePath
 | 
						|
                                  );
 | 
						|
        PERF_DRIVER_BINDING_SUPPORT_END (DriverBinding->DriverBindingHandle, ControllerHandle);
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          SortedDriverBindingProtocols[Index] = NULL;
 | 
						|
          DriverFound                         = TRUE;
 | 
						|
 | 
						|
          //
 | 
						|
          // A driver was found that supports ControllerHandle, so attempt to start the driver
 | 
						|
          // on ControllerHandle.
 | 
						|
          //
 | 
						|
          PERF_DRIVER_BINDING_START_BEGIN (DriverBinding->DriverBindingHandle, ControllerHandle);
 | 
						|
          Status = DriverBinding->Start (
 | 
						|
                                    DriverBinding,
 | 
						|
                                    ControllerHandle,
 | 
						|
                                    RemainingDevicePath
 | 
						|
                                    );
 | 
						|
          PERF_DRIVER_BINDING_START_END (DriverBinding->DriverBindingHandle, ControllerHandle);
 | 
						|
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            //
 | 
						|
            // The driver was successfully started on ControllerHandle, so set a flag
 | 
						|
            //
 | 
						|
            OneStarted = TRUE;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } while (DriverFound);
 | 
						|
 | 
						|
  //
 | 
						|
  // Free any buffers that were allocated with AllocatePool()
 | 
						|
  //
 | 
						|
  CoreFreePool (SortedDriverBindingProtocols);
 | 
						|
 | 
						|
  //
 | 
						|
  // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
 | 
						|
  //
 | 
						|
  if (OneStarted) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
 | 
						|
  //
 | 
						|
  if (RemainingDevicePath != NULL) {
 | 
						|
    if (IsDevicePathEnd (RemainingDevicePath)) {
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
 | 
						|
  //
 | 
						|
  return EFI_NOT_FOUND;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Disonnects a controller from a driver
 | 
						|
 | 
						|
  @param  ControllerHandle                      ControllerHandle The handle of
 | 
						|
                                                the controller from which
 | 
						|
                                                driver(s)  are to be
 | 
						|
                                                disconnected.
 | 
						|
  @param  DriverImageHandle                     DriverImageHandle The driver to
 | 
						|
                                                disconnect from ControllerHandle.
 | 
						|
  @param  ChildHandle                           ChildHandle The handle of the
 | 
						|
                                                child to destroy.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS                           One or more drivers were
 | 
						|
                                                disconnected from the controller.
 | 
						|
  @retval EFI_SUCCESS                           On entry, no drivers are managing
 | 
						|
                                                ControllerHandle.
 | 
						|
  @retval EFI_SUCCESS                           DriverImageHandle is not NULL,
 | 
						|
                                                and on entry DriverImageHandle is
 | 
						|
                                                not managing ControllerHandle.
 | 
						|
  @retval EFI_INVALID_PARAMETER                 ControllerHandle is NULL.
 | 
						|
  @retval EFI_INVALID_PARAMETER                 DriverImageHandle is not NULL,
 | 
						|
                                                and it is not a valid EFI_HANDLE.
 | 
						|
  @retval EFI_INVALID_PARAMETER                 ChildHandle is not NULL, and it
 | 
						|
                                                is not a valid EFI_HANDLE.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES                  There are not enough resources
 | 
						|
                                                available to disconnect any
 | 
						|
                                                drivers from ControllerHandle.
 | 
						|
  @retval EFI_DEVICE_ERROR                      The controller could not be
 | 
						|
                                                disconnected because of a device
 | 
						|
                                                error.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
CoreDisconnectController (
 | 
						|
  IN  EFI_HANDLE  ControllerHandle,
 | 
						|
  IN  EFI_HANDLE  DriverImageHandle  OPTIONAL,
 | 
						|
  IN  EFI_HANDLE  ChildHandle        OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                   Status;
 | 
						|
  IHANDLE                      *Handle;
 | 
						|
  EFI_HANDLE                   *DriverImageHandleBuffer;
 | 
						|
  EFI_HANDLE                   *ChildBuffer;
 | 
						|
  UINTN                        Index;
 | 
						|
  UINTN                        HandleIndex;
 | 
						|
  UINTN                        DriverImageHandleCount;
 | 
						|
  UINTN                        ChildrenToStop;
 | 
						|
  UINTN                        ChildBufferCount;
 | 
						|
  UINTN                        StopCount;
 | 
						|
  BOOLEAN                      Duplicate;
 | 
						|
  BOOLEAN                      ChildHandleValid;
 | 
						|
  BOOLEAN                      DriverImageHandleValid;
 | 
						|
  LIST_ENTRY                   *Link;
 | 
						|
  LIST_ENTRY                   *ProtLink;
 | 
						|
  OPEN_PROTOCOL_DATA           *OpenData;
 | 
						|
  PROTOCOL_INTERFACE           *Prot;
 | 
						|
  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure ControllerHandle is valid
 | 
						|
  //
 | 
						|
  CoreAcquireProtocolLock ();
 | 
						|
 | 
						|
  Status = CoreValidateHandle (ControllerHandle);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    CoreReleaseProtocolLock ();
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure ChildHandle is valid if it is not NULL
 | 
						|
  //
 | 
						|
  if (ChildHandle != NULL) {
 | 
						|
    Status = CoreValidateHandle (ChildHandle);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      CoreReleaseProtocolLock ();
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
  Handle = ControllerHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get list of drivers that are currently managing ControllerHandle
 | 
						|
  //
 | 
						|
  DriverImageHandleBuffer = NULL;
 | 
						|
  DriverImageHandleCount  = 1;
 | 
						|
 | 
						|
  if (DriverImageHandle == NULL) {
 | 
						|
    //
 | 
						|
    // Look at each protocol interface for a match
 | 
						|
    //
 | 
						|
    DriverImageHandleCount = 0;
 | 
						|
 | 
						|
    CoreAcquireProtocolLock ();
 | 
						|
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
      for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
           ProtLink != &Prot->OpenList;
 | 
						|
           ProtLink = ProtLink->ForwardLink)
 | 
						|
      {
 | 
						|
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
 | 
						|
          DriverImageHandleCount++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
    //
 | 
						|
    // If there are no drivers managing this controller, then return EFI_SUCCESS
 | 
						|
    //
 | 
						|
    if (DriverImageHandleCount == 0) {
 | 
						|
      Status = EFI_SUCCESS;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    DriverImageHandleBuffer = AllocatePool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
 | 
						|
    if (DriverImageHandleBuffer == NULL) {
 | 
						|
      Status = EFI_OUT_OF_RESOURCES;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    DriverImageHandleCount = 0;
 | 
						|
 | 
						|
    CoreAcquireProtocolLock ();
 | 
						|
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
      for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
           ProtLink != &Prot->OpenList;
 | 
						|
           ProtLink = ProtLink->ForwardLink)
 | 
						|
      {
 | 
						|
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
        if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
 | 
						|
          Duplicate = FALSE;
 | 
						|
          for (Index = 0; Index < DriverImageHandleCount; Index++) {
 | 
						|
            if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
 | 
						|
              Duplicate = TRUE;
 | 
						|
              break;
 | 
						|
            }
 | 
						|
          }
 | 
						|
 | 
						|
          if (!Duplicate) {
 | 
						|
            DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
 | 
						|
            DriverImageHandleCount++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    CoreReleaseProtocolLock ();
 | 
						|
  }
 | 
						|
 | 
						|
  StopCount = 0;
 | 
						|
  for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
 | 
						|
    if (DriverImageHandleBuffer != NULL) {
 | 
						|
      DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Get the Driver Binding Protocol of the driver that is managing this controller
 | 
						|
    //
 | 
						|
    Status = CoreHandleProtocol (
 | 
						|
               DriverImageHandle,
 | 
						|
               &gEfiDriverBindingProtocolGuid,
 | 
						|
               (VOID **)&DriverBinding
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status) || (DriverBinding == NULL)) {
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
      goto Done;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // Look at each protocol interface for a match
 | 
						|
    //
 | 
						|
    DriverImageHandleValid = FALSE;
 | 
						|
    ChildBufferCount       = 0;
 | 
						|
 | 
						|
    CoreAcquireProtocolLock ();
 | 
						|
    for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
      Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
      for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
           ProtLink != &Prot->OpenList;
 | 
						|
           ProtLink = ProtLink->ForwardLink)
 | 
						|
      {
 | 
						|
        OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
        if (OpenData->AgentHandle == DriverImageHandle) {
 | 
						|
          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
 | 
						|
            ChildBufferCount++;
 | 
						|
          }
 | 
						|
 | 
						|
          if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
 | 
						|
            DriverImageHandleValid = TRUE;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    CoreReleaseProtocolLock ();
 | 
						|
 | 
						|
    if (DriverImageHandleValid) {
 | 
						|
      ChildHandleValid = FALSE;
 | 
						|
      ChildBuffer      = NULL;
 | 
						|
      if (ChildBufferCount != 0) {
 | 
						|
        ChildBuffer = AllocatePool (sizeof (EFI_HANDLE) * ChildBufferCount);
 | 
						|
        if (ChildBuffer == NULL) {
 | 
						|
          Status = EFI_OUT_OF_RESOURCES;
 | 
						|
          goto Done;
 | 
						|
        }
 | 
						|
 | 
						|
        ChildBufferCount = 0;
 | 
						|
 | 
						|
        CoreAcquireProtocolLock ();
 | 
						|
        for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
 | 
						|
          Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
 | 
						|
          for (ProtLink = Prot->OpenList.ForwardLink;
 | 
						|
               ProtLink != &Prot->OpenList;
 | 
						|
               ProtLink = ProtLink->ForwardLink)
 | 
						|
          {
 | 
						|
            OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
 | 
						|
            if ((OpenData->AgentHandle == DriverImageHandle) &&
 | 
						|
                ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0))
 | 
						|
            {
 | 
						|
              Duplicate = FALSE;
 | 
						|
              for (Index = 0; Index < ChildBufferCount; Index++) {
 | 
						|
                if (ChildBuffer[Index] == OpenData->ControllerHandle) {
 | 
						|
                  Duplicate = TRUE;
 | 
						|
                  break;
 | 
						|
                }
 | 
						|
              }
 | 
						|
 | 
						|
              if (!Duplicate) {
 | 
						|
                ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
 | 
						|
                if (ChildHandle == ChildBuffer[ChildBufferCount]) {
 | 
						|
                  ChildHandleValid = TRUE;
 | 
						|
                }
 | 
						|
 | 
						|
                ChildBufferCount++;
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        CoreReleaseProtocolLock ();
 | 
						|
      }
 | 
						|
 | 
						|
      if ((ChildHandle == NULL) || ChildHandleValid) {
 | 
						|
        ChildrenToStop = 0;
 | 
						|
        Status         = EFI_SUCCESS;
 | 
						|
        if (ChildBufferCount > 0) {
 | 
						|
          if (ChildHandle != NULL) {
 | 
						|
            ChildrenToStop = 1;
 | 
						|
            Status         = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
 | 
						|
          } else {
 | 
						|
            ChildrenToStop = ChildBufferCount;
 | 
						|
            Status         = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
 | 
						|
          Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
 | 
						|
        }
 | 
						|
 | 
						|
        if (!EFI_ERROR (Status)) {
 | 
						|
          StopCount++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      if (ChildBuffer != NULL) {
 | 
						|
        CoreFreePool (ChildBuffer);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (StopCount > 0) {
 | 
						|
    Status = EFI_SUCCESS;
 | 
						|
  } else {
 | 
						|
    Status = EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
 | 
						|
Done:
 | 
						|
 | 
						|
  if (DriverImageHandleBuffer != NULL) {
 | 
						|
    CoreFreePool (DriverImageHandleBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 |