-/*++\r
+/** @file \r
+\r
+ Support functions to connect/disconnect UEFI Driver model Protocol\r
\r
-Copyright (c) 2006, Intel Corporation \r
+Copyright (c) 2006 - 2008, 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
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
\r
#include <DxeMain.h>\r
\r
-BOOLEAN mRepairLoadedImage = FALSE;\r
-\r
//\r
// Driver Support Function Prototypes\r
//\r
-EFI_STATUS\r
-GetHandleFromDriverBinding (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindingNeed,\r
- OUT EFI_HANDLE *Handle \r
- );\r
-\r
EFI_STATUS \r
CoreConnectSingleController (\r
IN EFI_HANDLE ControllerHandle,\r
EFI_HANDLE *ChildHandleBuffer;\r
UINTN ChildHandleCount;\r
UINTN Index;\r
- EFI_HANDLE *LoadedImageHandleBuffer;\r
- UINTN LoadedImageHandleCount;\r
- LOADED_IMAGE_PRIVATE_DATA *Image;\r
- EFI_HANDLE DeviceHandle;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
\r
//\r
// Make sure ControllerHandle is valid\r
CoreFreePool (ChildHandleBuffer);\r
}\r
\r
- //\r
- // If a Stop() function has been called one or more time successfully, then attempt to \r
- // repair the stale DeviceHandle fields of the Loaded Image Protocols\r
- //\r
- if (mRepairLoadedImage) {\r
- //\r
- // Assume that all Loaded Image Protocols can be repaired\r
- //\r
- mRepairLoadedImage = FALSE;\r
-\r
- //\r
- // Get list of all Loaded Image Protocol Instances\r
- //\r
- Status = CoreLocateHandleBuffer (\r
- ByProtocol, \r
- &gEfiLoadedImageProtocolGuid, \r
- NULL,\r
- &LoadedImageHandleCount, \r
- &LoadedImageHandleBuffer\r
- );\r
- if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) {\r
- for (Index = 0; Index < LoadedImageHandleCount; Index++) {\r
- //\r
- // Retrieve the Loaded Image Protocol\r
- //\r
- Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]);\r
- if (Image != NULL) {\r
- //\r
- // Check to see if the DeviceHandle field is a valid handle\r
- //\r
- Status = CoreValidateHandle (Image->Info.DeviceHandle);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // The DeviceHandle field is not valid.\r
- // Attempt to locate a device handle with a device path that matches the one\r
- // that was used to originally load the image\r
- //\r
- DevicePath = Image->DeviceHandleDevicePath;\r
- if (DevicePath != NULL) {\r
- Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);\r
- if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) {\r
- //\r
- // A device handle with a matching device path was found, so update the Loaded Image Protocol\r
- // with the device handle discovered\r
- //\r
- Image->Info.DeviceHandle = DeviceHandle;\r
- } else {\r
- //\r
- // There is still at least one Loaded Image Protocol that requires repair\r
- //\r
- mRepairLoadedImage = TRUE;\r
- }\r
- }\r
- }\r
- }\r
- }\r
- CoreFreePool (LoadedImageHandleBuffer);\r
- }\r
- }\r
-\r
return ReturnStatus;\r
}\r
\r
IN OUT UINTN *NumberOfSortedDriverBindingProtocols, \r
IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,\r
IN UINTN DriverBindingHandleCount,\r
- IN OUT EFI_HANDLE *DriverBindingHandleBuffer\r
+ IN OUT EFI_HANDLE *DriverBindingHandleBuffer,\r
+ IN BOOLEAN IsImageHandle\r
)\r
/*++\r
\r
\r
DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.\r
\r
+ IsImageHandle - Indicate whether DriverBindingHandle is an image handle\r
+ \r
Returns:\r
\r
None.\r
return;\r
}\r
\r
+ //\r
+ // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle\r
+ // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list\r
+ //\r
+ if (IsImageHandle) {\r
+ //\r
+ // Loop through all the Driver Binding Handles\r
+ //\r
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+ //\r
+ // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle\r
+ //\r
+ Status = CoreHandleProtocol (\r
+ DriverBindingHandleBuffer[Index],\r
+ &gEfiDriverBindingProtocolGuid,\r
+ (VOID **)&DriverBinding\r
+ );\r
+ if (EFI_ERROR (Status) || DriverBinding == NULL) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,\r
+ // then add the DriverBindingProtocol[Index] to the sorted list\r
+ //\r
+ if (DriverBinding->ImageHandle == DriverBindingHandle) {\r
+ AddSortedDriverBindingProtocol (\r
+ DriverBindingHandleBuffer[Index],\r
+ NumberOfSortedDriverBindingProtocols, \r
+ SortedDriverBindingProtocols,\r
+ DriverBindingHandleCount,\r
+ DriverBindingHandleBuffer,\r
+ FALSE\r
+ );\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
//\r
// Retrieve the Driver Binding Protocol from DriverBindingHandle\r
//\r
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
UINTN DriverBindingHandleCount;\r
EFI_HANDLE *DriverBindingHandleBuffer;\r
+ UINTN NewDriverBindingHandleCount;\r
+ EFI_HANDLE *NewDriverBindingHandleBuffer;\r
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
UINTN NumberOfSortedDriverBindingProtocols;\r
EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;\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
&NumberOfSortedDriverBindingProtocols, \r
SortedDriverBindingProtocols,\r
DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
+ DriverBindingHandleBuffer,\r
+ FALSE\r
);\r
}\r
}\r
&NumberOfSortedDriverBindingProtocols, \r
SortedDriverBindingProtocols,\r
DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
+ DriverBindingHandleBuffer,\r
+ TRUE\r
);\r
}\r
} while (!EFI_ERROR (Status));\r
//\r
// Get the Bus Specific Driver Override Protocol instance on the Controller Handle\r
//\r
- Status = CoreHandleProtocol(\r
+ Status = CoreHandleProtocol (\r
ControllerHandle, \r
&gEfiBusSpecificDriverOverrideProtocolGuid, \r
(VOID **)&BusSpecificDriverOverride\r
&NumberOfSortedDriverBindingProtocols, \r
SortedDriverBindingProtocols,\r
DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
+ DriverBindingHandleBuffer,\r
+ TRUE\r
);\r
}\r
} while (!EFI_ERROR (Status));\r
&NumberOfSortedDriverBindingProtocols, \r
SortedDriverBindingProtocols,\r
DriverBindingHandleCount,\r
- DriverBindingHandleBuffer\r
+ DriverBindingHandleBuffer,\r
+ FALSE\r
);\r
}\r
\r
// If the number of Driver Binding Protocols has increased since this function started, then return\r
// EFI_NOT_READY, so it will be restarted\r
//\r
- if (NumberOfSortedDriverBindingProtocols > DriverBindingHandleCount) {\r
+ Status = CoreLocateHandleBuffer (\r
+ ByProtocol, \r
+ &gEfiDriverBindingProtocolGuid, \r
+ NULL,\r
+ &NewDriverBindingHandleCount, \r
+ &NewDriverBindingHandleBuffer\r
+ );\r
+ CoreFreePool (NewDriverBindingHandleBuffer);\r
+ if (NewDriverBindingHandleCount > DriverBindingHandleCount) {\r
//\r
// Free any buffers that were allocated with AllocatePool()\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
+ PERF_START (DriverBinding->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
+ PERF_END (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);\r
\r
if (!EFI_ERROR (Status)) {\r
//\r
OPEN_PROTOCOL_DATA *OpenData;\r
PROTOCOL_INTERFACE *Prot;\r
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
- EFI_HANDLE *LoadedImageHandleBuffer;\r
- UINTN LoadedImageHandleCount;\r
- LOADED_IMAGE_PRIVATE_DATA *Image;\r
\r
//\r
// Make sure ControllerHandle is valid\r
}\r
\r
if (StopCount > 0) {\r
- //\r
- // If the Loaded Image Protocols do not already need to be repaired, then\r
- // check the status of the DeviceHandle field of all Loaded Image Protocols\r
- // to determine if any of them now need repair because a sucessful Stop()\r
- // may have destroyed the DeviceHandle value in the Loaded Image Protocol\r
- //\r
- if (!mRepairLoadedImage) {\r
- //\r
- // Get list of all Loaded Image Protocol Instances\r
- //\r
- Status = CoreLocateHandleBuffer (\r
- ByProtocol, \r
- &gEfiLoadedImageProtocolGuid, \r
- NULL,\r
- &LoadedImageHandleCount, \r
- &LoadedImageHandleBuffer\r
- );\r
- if (!EFI_ERROR (Status) && LoadedImageHandleCount != 0) {\r
- for (Index = 0; Index < LoadedImageHandleCount; Index++) {\r
- //\r
- // Retrieve the Loaded Image Protocol\r
- //\r
- Image = CoreLoadedImageInfo (LoadedImageHandleBuffer[Index]);\r
- if (Image != NULL) {\r
- //\r
- // Check to see if the DeviceHandle field is a valid handle\r
- //\r
- Status = CoreValidateHandle (Image->Info.DeviceHandle);\r
- if (EFI_ERROR (Status)) {\r
- //\r
- // The DeviceHandle field is not longer a valid handle. This means\r
- // that future calls to ConnectController() need to attemp to repair\r
- // the Loaded Image Protocols with invalid DeviceHandle fields. Set \r
- // the flag used by ConnectController().\r
- //\r
- mRepairLoadedImage = TRUE;\r
- break;\r
- }\r
- }\r
- }\r
- CoreFreePool (LoadedImageHandleBuffer);\r
- }\r
- }\r
Status = EFI_SUCCESS;\r
} else {\r
Status = EFI_NOT_FOUND;\r
\r
return Status;\r
}\r
-\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