+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- DriverSupport.c\r
- \r
-Abstract:\r
-\r
- EFI Driver Support Protocol\r
-\r
-Revision History\r
-\r
---*/\r
-\r
-#include <DxeMain.h>\r
-\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetHandleFromDriverBinding (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,\r
- OUT EFI_HANDLE *Handle \r
- );\r
-\r
-\r
-//\r
-// Driver Support Function Prototypes\r
-//\r
-STATIC\r
-EFI_STATUS \r
-CoreConnectSingleController (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE *DriverImageHandle OPTIONAL,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL\r
- );\r
-\r
-//\r
-// Driver Support Functions\r
-//\r
-\r
-\r
-EFI_STATUS \r
-EFIAPI\r
-CoreConnectController (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE *DriverImageHandle OPTIONAL,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,\r
- IN BOOLEAN Recursive\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Connects one or more drivers to a controller.\r
-\r
-Arguments:\r
-\r
- ControllerHandle - Handle of the controller to be connected.\r
-\r
- DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.\r
-\r
- RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the\r
- controller specified by ControllerHandle.\r
- \r
- Recursive - Whether the function would be called recursively or not.\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_STATUS ReturnStatus;\r
- IHANDLE *Handle;\r
- PROTOCOL_INTERFACE *Prot;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *ProtLink;\r
- OPEN_PROTOCOL_DATA *OpenData;\r
- EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;\r
- \r
- //\r
- // Make sure ControllerHandle is valid\r
- //\r
- Status = CoreValidateHandle (ControllerHandle);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Handle = ControllerHandle;\r
-\r
- //\r
- // Connect all drivers to ControllerHandle \r
- //\r
- AlignedRemainingDevicePath = NULL;\r
- if (RemainingDevicePath != NULL) {\r
- AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath);\r
- }\r
- ReturnStatus = CoreConnectSingleController (\r
- ControllerHandle,\r
- DriverImageHandle,\r
- AlignedRemainingDevicePath\r
- );\r
- if (AlignedRemainingDevicePath != NULL) {\r
- CoreFreePool (AlignedRemainingDevicePath);\r
- }\r
-\r
- //\r
- // If not recursive, then just return after connecting drivers to ControllerHandle\r
- //\r
- if (!Recursive) {\r
- return ReturnStatus;\r
- }\r
-\r
- //\r
- // If recursive, then connect all drivers to all of ControllerHandle's children\r
- //\r
- CoreAcquireProtocolLock ();\r
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
- Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
- for (ProtLink = Prot->OpenList.ForwardLink; \r
- ProtLink != &Prot->OpenList; \r
- ProtLink = ProtLink->ForwardLink) {\r
- OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
- CoreReleaseProtocolLock ();\r
- Status = CoreConnectController (\r
- OpenData->ControllerHandle,\r
- NULL,\r
- NULL,\r
- TRUE\r
- ); \r
- CoreAcquireProtocolLock ();\r
- }\r
- }\r
- }\r
- CoreReleaseProtocolLock ();\r
- \r
- return ReturnStatus;\r
-}\r
-\r
-STATIC\r
-VOID\r
-AddSortedDriverBindingProtocol (\r
- IN EFI_HANDLE DriverBindingHandle,\r
- IN OUT UINTN *NumberOfSortedDriverBindingProtocols, \r
- IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,\r
- IN UINTN DriverBindingHandleCount,\r
- IN OUT EFI_HANDLE *DriverBindingHandleBuffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Add Driver Binding Protocols from Context Driver Image Handles to sorted \r
- Driver Binding Protocol list.\r
-\r
-Arguments:\r
-\r
- DriverBindingHandle - Handle of the driver binding protocol.\r
-\r
- NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols\r
-\r
- SortedDriverBindingProtocols - The sorted protocol list. \r
- \r
- DriverBindingHandleCount - Driver Binding Handle Count.\r
-\r
- DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
- UINTN Index;\r
-\r
- //\r
- // Make sure the DriverBindingHandle is valid\r
- //\r
- Status = CoreValidateHandle (DriverBindingHandle);\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- //\r
- // Retrieve the Driver Binding Protocol from DriverBindingHandle\r
- //\r
- Status = CoreHandleProtocol(\r
- DriverBindingHandle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **)&DriverBinding\r
- );\r
- //\r
- // If DriverBindingHandle does not support the Driver Binding Protocol then return\r
- //\r
- if (EFI_ERROR (Status) || DriverBinding == NULL) {\r
- return;\r
- }\r
-\r
- //\r
- // See if DriverBinding is already in the sorted list\r
- //\r
- for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols; Index++) {\r
- if (DriverBinding == SortedDriverBindingProtocols[Index]) {\r
- return;\r
- }\r
- }\r
-\r
- //\r
- // Add DriverBinding to the end of the list\r
- //\r
- SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;\r
- *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;\r
-\r
- //\r
- // Mark the cooresponding handle in DriverBindingHandleBuffer as used\r
- //\r
- for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
- if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {\r
- DriverBindingHandleBuffer[Index] = NULL;\r
- }\r
- }\r
-}\r
- \r
-STATIC\r
-EFI_STATUS \r
-CoreConnectSingleController (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Connects a controller to a driver.\r
-\r
-Arguments:\r
-\r
- ControllerHandle - Handle of the controller to be connected.\r
- ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.\r
- RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child \r
- of the controller specified by ControllerHandle.\r
- \r
-Returns:\r
-\r
- EFI_SUCCESS - One or more drivers were connected to ControllerHandle.\r
- EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.\r
- EFI_NOT_FOUND - No drivers were connected to ControllerHandle.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_HANDLE DriverImageHandle;\r
- EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;\r
- EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
- UINTN DriverBindingHandleCount;\r
- EFI_HANDLE *DriverBindingHandleBuffer;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
- UINTN NumberOfSortedDriverBindingProtocols;\r
- EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;\r
- UINT32 HighestVersion;\r
- UINTN HighestIndex;\r
- UINTN SortIndex;\r
- BOOLEAN OneStarted;\r
- BOOLEAN DriverFound;\r
- EFI_HANDLE DriverBindingHandle;\r
-\r
- //\r
- // DriverBindingHandle is used for performance measurement, initialize it here just in case.\r
- //\r
- DriverBindingHandle = NULL;\r
- //\r
- // Initialize local variables\r
- //\r
- DriverBindingHandleCount = 0;\r
- DriverBindingHandleBuffer = NULL;\r
- NumberOfSortedDriverBindingProtocols = 0;\r
- SortedDriverBindingProtocols = NULL;\r
-\r
- //\r
- // Get list of all Driver Binding Protocol Instances\r
- //\r
- Status = CoreLocateHandleBuffer (\r
- ByProtocol, \r
- &gEfiDriverBindingProtocolGuid, \r
- NULL,\r
- &DriverBindingHandleCount, \r
- &DriverBindingHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- //\r
- // Allocate a duplicate array for the sorted Driver Binding Protocol Instances\r
- //\r
- SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount);\r
- if (SortedDriverBindingProtocols == NULL) {\r
- CoreFreePool (DriverBindingHandleBuffer);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Add Driver Binding Protocols from Context Driver Image Handles first\r
- //\r
- if (ContextDriverImageHandles != NULL) {\r
- for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {\r
- AddSortedDriverBindingProtocol (\r
- ContextDriverImageHandles[Index],\r
- &NumberOfSortedDriverBindingProtocols, \r
- SortedDriverBindingProtocols,\r
- DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
- );\r
- }\r
- }\r
-\r
- //\r
- // Add the Platform Driver Override Protocol drivers for ControllerHandle next\r
- //\r
- Status = CoreLocateProtocol (\r
- &gEfiPlatformDriverOverrideProtocolGuid, \r
- NULL, \r
- (VOID **)&PlatformDriverOverride\r
- );\r
- if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {\r
- DriverImageHandle = NULL;\r
- do {\r
- Status = PlatformDriverOverride->GetDriver (\r
- PlatformDriverOverride,\r
- ControllerHandle,\r
- &DriverImageHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- AddSortedDriverBindingProtocol (\r
- DriverImageHandle,\r
- &NumberOfSortedDriverBindingProtocols, \r
- SortedDriverBindingProtocols,\r
- DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
- );\r
- }\r
- } while (!EFI_ERROR (Status));\r
- }\r
-\r
- //\r
- // Get the Bus Specific Driver Override Protocol instance on the Controller Handle\r
- //\r
- Status = CoreHandleProtocol(\r
- ControllerHandle, \r
- &gEfiBusSpecificDriverOverrideProtocolGuid, \r
- (VOID **)&BusSpecificDriverOverride\r
- );\r
- if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {\r
- DriverImageHandle = NULL;\r
- do {\r
- Status = BusSpecificDriverOverride->GetDriver (\r
- BusSpecificDriverOverride,\r
- &DriverImageHandle\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- AddSortedDriverBindingProtocol (\r
- DriverImageHandle,\r
- &NumberOfSortedDriverBindingProtocols, \r
- SortedDriverBindingProtocols,\r
- DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
- );\r
- }\r
- } while (!EFI_ERROR (Status));\r
- }\r
-\r
- //\r
- // Then add all the remaining Driver Binding Protocols\r
- //\r
- SortIndex = NumberOfSortedDriverBindingProtocols;\r
- for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
- AddSortedDriverBindingProtocol (\r
- DriverBindingHandleBuffer[Index],\r
- &NumberOfSortedDriverBindingProtocols, \r
- SortedDriverBindingProtocols,\r
- DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
- );\r
- }\r
-\r
- //\r
- // Free the Driver Binding Handle Buffer\r
- //\r
- CoreFreePool (DriverBindingHandleBuffer);\r
-\r
- //\r
- // Sort the remaining DriverBinding Protocol based on their Version field from\r
- // highest to lowest.\r
- //\r
- for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {\r
- HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;\r
- HighestIndex = SortIndex;\r
- for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {\r
- if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {\r
- HighestVersion = SortedDriverBindingProtocols[Index]->Version;\r
- HighestIndex = Index;\r
- }\r
- }\r
- if (SortIndex != HighestIndex) {\r
- DriverBinding = SortedDriverBindingProtocols[SortIndex];\r
- SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];\r
- SortedDriverBindingProtocols[HighestIndex] = DriverBinding;\r
- }\r
- }\r
-\r
- //\r
- // Loop until no more drivers can be started on ControllerHandle\r
- //\r
- OneStarted = FALSE;\r
- do {\r
-\r
- //\r
- // Loop through the sorted Driver Binding Protocol Instances in order, and see if\r
- // any of the Driver Binding Protocols support the controller specified by \r
- // ControllerHandle.\r
- //\r
- DriverBinding = NULL;\r
- DriverFound = FALSE;\r
- for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {\r
- if (SortedDriverBindingProtocols[Index] != NULL) {\r
- DriverBinding = SortedDriverBindingProtocols[Index];\r
- Status = DriverBinding->Supported(\r
- DriverBinding, \r
- ControllerHandle,\r
- RemainingDevicePath\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- SortedDriverBindingProtocols[Index] = NULL;\r
- DriverFound = TRUE;\r
-\r
- //\r
- // A driver was found that supports ControllerHandle, so attempt to start the driver\r
- // on ControllerHandle.\r
- //\r
- PERF_CODE_BEGIN ();\r
- GetHandleFromDriverBinding (DriverBinding, &DriverBindingHandle);\r
- PERF_CODE_END ();\r
-\r
- PERF_START (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);\r
- Status = DriverBinding->Start (\r
- DriverBinding, \r
- ControllerHandle,\r
- RemainingDevicePath\r
- );\r
- PERF_END (DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);\r
-\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // The driver was successfully started on ControllerHandle, so set a flag\r
- //\r
- OneStarted = TRUE;\r
- }\r
- }\r
- }\r
- }\r
- } while (DriverFound);\r
-\r
- //\r
- // Free any buffers that were allocated with AllocatePool()\r
- //\r
- CoreFreePool (SortedDriverBindingProtocols);\r
-\r
- //\r
- // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.\r
- //\r
- if (OneStarted) {\r
- return EFI_SUCCESS;\r
- } \r
-\r
- //\r
- // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS\r
- //\r
- if (RemainingDevicePath != NULL) {\r
- if (IsDevicePathEnd (RemainingDevicePath)) {\r
- return EFI_SUCCESS;\r
- }\r
- } \r
-\r
- //\r
- // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND\r
- //\r
- return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-EFI_STATUS \r
-EFIAPI\r
-CoreDisconnectController (\r
- IN EFI_HANDLE ControllerHandle,\r
- IN EFI_HANDLE DriverImageHandle OPTIONAL,\r
- IN EFI_HANDLE ChildHandle OPTIONAL\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Disonnects a controller from a driver\r
-\r
-Arguments:\r
-\r
- ControllerHandle - ControllerHandle The handle of the controller from which driver(s) \r
- are to be disconnected.\r
- DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.\r
- ChildHandle - ChildHandle The handle of the child to destroy.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - One or more drivers were disconnected from the controller.\r
- EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.\r
- EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.\r
- EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.\r
- EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.\r
- EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.\r
- EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.\r
- EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- IHANDLE *Handle;\r
- EFI_HANDLE *DriverImageHandleBuffer;\r
- EFI_HANDLE *ChildBuffer;\r
- UINTN Index;\r
- UINTN HandleIndex;\r
- UINTN DriverImageHandleCount;\r
- UINTN ChildrenToStop;\r
- UINTN ChildBufferCount;\r
- UINTN StopCount;\r
- BOOLEAN Duplicate;\r
- BOOLEAN ChildHandleValid;\r
- BOOLEAN DriverImageHandleValid;\r
- LIST_ENTRY *Link;\r
- LIST_ENTRY *ProtLink;\r
- OPEN_PROTOCOL_DATA *OpenData;\r
- PROTOCOL_INTERFACE *Prot;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
-\r
- //\r
- // Make sure ControllerHandle is valid\r
- //\r
- Status = CoreValidateHandle (ControllerHandle);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Make sure ChildHandle is valid if it is not NULL\r
- //\r
- if (ChildHandle != NULL) {\r
- Status = CoreValidateHandle (ChildHandle);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- Handle = ControllerHandle;\r
-\r
- //\r
- // Get list of drivers that are currently managing ControllerHandle\r
- //\r
- DriverImageHandleBuffer = NULL;\r
- DriverImageHandleCount = 1; \r
- \r
- if (DriverImageHandle == NULL) {\r
- //\r
- // Look at each protocol interface for a match\r
- //\r
- DriverImageHandleCount = 0;\r
-\r
- CoreAcquireProtocolLock ();\r
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
- Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
- for (ProtLink = Prot->OpenList.ForwardLink; \r
- ProtLink != &Prot->OpenList; \r
- ProtLink = ProtLink->ForwardLink) {\r
- OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
- DriverImageHandleCount++;\r
- }\r
- }\r
- }\r
- CoreReleaseProtocolLock ();\r
- \r
- //\r
- // If there are no drivers managing this controller, then return EFI_SUCCESS\r
- //\r
- if (DriverImageHandleCount == 0) {\r
- Status = EFI_SUCCESS;\r
- goto Done;\r
- }\r
-\r
- DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);\r
- if (DriverImageHandleBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- DriverImageHandleCount = 0;\r
-\r
- CoreAcquireProtocolLock ();\r
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
- Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
- for (ProtLink = Prot->OpenList.ForwardLink; \r
- ProtLink != &Prot->OpenList; \r
- ProtLink = ProtLink->ForwardLink) {\r
- OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
- Duplicate = FALSE;\r
- for (Index = 0; Index< DriverImageHandleCount; Index++) {\r
- if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {\r
- Duplicate = TRUE;\r
- break;\r
- }\r
- }\r
- if (!Duplicate) {\r
- DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;\r
- DriverImageHandleCount++;\r
- }\r
- }\r
- }\r
- }\r
- CoreReleaseProtocolLock ();\r
- }\r
-\r
- StopCount = 0;\r
- for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {\r
-\r
- if (DriverImageHandleBuffer != NULL) {\r
- DriverImageHandle = DriverImageHandleBuffer[HandleIndex];\r
- }\r
-\r
- //\r
- // Get the Driver Binding Protocol of the driver that is managing this controller\r
- //\r
- Status = CoreHandleProtocol (\r
- DriverImageHandle, \r
- &gEfiDriverBindingProtocolGuid, \r
- (VOID **)&DriverBinding\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Done;\r
- }\r
-\r
- //\r
- // Look at each protocol interface for a match\r
- //\r
- DriverImageHandleValid = FALSE;\r
- ChildBufferCount = 0;\r
-\r
- CoreAcquireProtocolLock ();\r
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
- Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
- for (ProtLink = Prot->OpenList.ForwardLink; \r
- ProtLink != &Prot->OpenList; \r
- ProtLink = ProtLink->ForwardLink) {\r
- OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if (OpenData->AgentHandle == DriverImageHandle) {\r
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
- ChildBufferCount++;\r
- } \r
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {\r
- DriverImageHandleValid = TRUE;\r
- }\r
- }\r
- }\r
- }\r
- CoreReleaseProtocolLock ();\r
-\r
- if (DriverImageHandleValid) {\r
- ChildHandleValid = FALSE;\r
- ChildBuffer = NULL;\r
- if (ChildBufferCount != 0) {\r
- ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);\r
- if (ChildBuffer == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Done;\r
- }\r
-\r
- ChildBufferCount = 0;\r
-\r
- CoreAcquireProtocolLock ();\r
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {\r
- Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);\r
- for (ProtLink = Prot->OpenList.ForwardLink; \r
- ProtLink != &Prot->OpenList; \r
- ProtLink = ProtLink->ForwardLink) {\r
- OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);\r
- if ((OpenData->AgentHandle == DriverImageHandle) &&\r
- ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {\r
- Duplicate = FALSE;\r
- for (Index = 0; Index < ChildBufferCount; Index++) {\r
- if (ChildBuffer[Index] == OpenData->ControllerHandle) {\r
- Duplicate = TRUE;\r
- break;\r
- }\r
- }\r
- if (!Duplicate) {\r
- ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;\r
- if (ChildHandle == ChildBuffer[ChildBufferCount]) {\r
- ChildHandleValid = TRUE;\r
- }\r
- ChildBufferCount++;\r
- }\r
- }\r
- }\r
- }\r
- CoreReleaseProtocolLock ();\r
- }\r
-\r
- if (ChildHandle == NULL || ChildHandleValid) {\r
- ChildrenToStop = 0;\r
- Status = EFI_SUCCESS;\r
- if (ChildBufferCount > 0) {\r
- if (ChildHandle != NULL) {\r
- ChildrenToStop = 1;\r
- Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);\r
- } else {\r
- ChildrenToStop = ChildBufferCount;\r
- Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);\r
- }\r
- }\r
- if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {\r
- Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);\r
- }\r
- if (!EFI_ERROR (Status)) {\r
- StopCount++;\r
- }\r
- }\r
-\r
- if (ChildBuffer != NULL) {\r
- CoreFreePool (ChildBuffer);\r
- }\r
- }\r
- }\r
-\r
- if (StopCount > 0) {\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_NOT_FOUND;\r
- }\r
- \r
-Done: \r
-\r
- if (DriverImageHandleBuffer != NULL) {\r
- CoreFreePool (DriverImageHandleBuffer);\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetHandleFromDriverBinding (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,\r
- OUT EFI_HANDLE *Handle \r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Locate the driver binding handle which a specified driver binding protocol installed on.\r
-\r
-Arguments:\r
-\r
- DriverBindingNeed - The specified driver binding protocol.\r
- \r
- Handle - The driver binding handle which the protocol installed on.\r
- \r
-\r
-Returns:\r
-\r
- EFI_NOT_FOUND - Could not find the handle.\r
- \r
- EFI_SUCCESS - Successfully find the associated driver binding handle.\r
- \r
---*/ \r
- {\r
- EFI_STATUS Status ;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
- UINTN DriverBindingHandleCount;\r
- EFI_HANDLE *DriverBindingHandleBuffer;\r
- UINTN Index;\r
- \r
- DriverBindingHandleCount = 0;\r
- DriverBindingHandleBuffer = NULL;\r
- *Handle = NULL_HANDLE;\r
- Status = CoreLocateHandleBuffer (\r
- ByProtocol, \r
- &gEfiDriverBindingProtocolGuid, \r
- NULL,\r
- &DriverBindingHandleCount, \r
- &DriverBindingHandleBuffer\r
- );\r
- if (EFI_ERROR (Status) || DriverBindingHandleCount == 0) {\r
- return EFI_NOT_FOUND;\r
- }\r
- \r
- for (Index = 0 ; Index < DriverBindingHandleCount; Index++ ) {\r
- Status = CoreOpenProtocol(\r
- DriverBindingHandleBuffer[Index],\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **)&DriverBinding,\r
- gDxeCoreImageHandle,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- \r
- if (!EFI_ERROR (Status) && DriverBinding != NULL) {\r
- \r
- if ( DriverBinding == DriverBindingNeed ) {\r
- *Handle = DriverBindingHandleBuffer[Index];\r
- CoreFreePool (DriverBindingHandleBuffer); \r
- return EFI_SUCCESS ;\r
- }\r
- }\r
- }\r
- \r
- CoreFreePool (DriverBindingHandleBuffer);\r
- return EFI_NOT_FOUND ;\r
-}\r
-\r