//\r
if (!EFI_ERROR (Status)) {\r
if (HandleBuffer != NULL) {\r
- gBS->FreePool (HandleBuffer);\r
+ FreePool (HandleBuffer);\r
}\r
return EFI_ALREADY_STARTED;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Get the first Binding protocol which has the specific image handle\r
+\r
+ @param Image Image handle\r
+\r
+ @return Pointer into the Binding Protocol interface\r
+\r
+**/\r
+EFI_DRIVER_BINDING_PROTOCOL *\r
+EFIAPI\r
+GetBindingProtocolFromImageHandle (\r
+ IN EFI_HANDLE ImageHandle,\r
+ OUT EFI_HANDLE *BindingHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+ UINTN DriverBindingHandleCount;\r
+ EFI_HANDLE *DriverBindingHandleBuffer;\r
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBindingInterface;\r
+\r
+ if (BindingHandle == NULL || ImageHandle == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Get all driver which support binding protocol in second page\r
+ //\r
+ DriverBindingHandleCount = 0;\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiDriverBindingProtocolGuid,\r
+ NULL,\r
+ &DriverBindingHandleCount,\r
+ &DriverBindingHandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
+ return NULL;\r
+ }\r
+\r
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+ DriverBindingInterface =NULL;\r
+ Status = gBS->OpenProtocol (\r
+ DriverBindingHandleBuffer[Index],\r
+ &gEfiDriverBindingProtocolGuid,\r
+ (VOID **) &DriverBindingInterface,\r
+ NULL,\r
+ NULL,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ continue;\r
+ }\r
+\r
+ if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
+ *BindingHandle = DriverBindingHandleBuffer[Index];\r
+ FreePool (DriverBindingHandleBuffer);\r
+ return DriverBindingInterface;\r
+ }\r
+ }\r
+\r
+ FreePool (DriverBindingHandleBuffer);\r
+ *BindingHandle = NULL;\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ return the current TPL, copied from the EDKII glue lib\r
+\r
+ @param VOID\r
+\r
+ @return Current TPL\r
+\r
+**/\r
+EFI_TPL\r
+GetCurrentTpl (\r
+ VOID\r
+ )\r
+{\r
+ EFI_TPL Tpl;\r
+\r
+ Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ gBS->RestoreTPL (Tpl);\r
+\r
+ return Tpl;\r
+}\r
+\r
\r
/**\r
Retrieves the image handle of the platform override driver for a controller in the system from the memory mapping database.\r
UINTN Index;\r
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;\r
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
+ EFI_HANDLE DriverBindingHandle;\r
BOOLEAN FoundLastReturned;\r
PLATFORM_OVERRIDE_ITEM *OverrideItem;\r
DRIVER_IMAGE_INFO *DriverImageInfo;\r
}\r
\r
if (ImageFound) {\r
- Status = gBS->HandleProtocol (\r
- ImageHandleBuffer[Index],\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBinding\r
- );\r
- ASSERT (!EFI_ERROR (Status));\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image handle,\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandleBuffer[Index],\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
DriverImageInfo->ImageHandle = ImageHandleBuffer[Index];\r
- } else {\r
+ } else if (GetCurrentTpl() <= TPL_CALLBACK){\r
//\r
// The driver image has not been loaded and started, need try to load and start it now\r
// Try to connect all device in the driver image path\r
//\r
+ // Note: LoadImage() and StartImage() should be called under CALLBACK TPL in theory, but\r
+ // since many device need to be connected in CALLBACK level environment( e.g. Usb devices )\r
+ // and the Fat and Patition driver can endure executing in CALLBACK level in fact, so here permit\r
+ // to use LoadImage() and StartImage() in CALLBACK TPL.\r
+ //\r
Status = ConnectDevicePath (DriverImageInfo->DriverImagePath);\r
//\r
// check whether it points to a PCI Option Rom image, and try to use bus override protocol to get its first option rom image driver\r
&ImageHandle\r
);\r
if (!EFI_ERROR (Status)) {\r
- Status = gBS->HandleProtocol (\r
- ImageHandle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBinding\r
- );\r
- ASSERT (!EFI_ERROR (Status));\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image handle\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandle,\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
DriverImageInfo->ImageHandle = ImageHandle;\r
}\r
}\r
DriverImageInfo->UnStartable = TRUE;\r
DriverImageInfo->ImageHandle = NULL;\r
} else {\r
- Status = gBS->HandleProtocol (\r
- ImageHandle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBinding\r
- );\r
- ASSERT (!EFI_ERROR (Status));\r
+ //\r
+ // Find its related driver binding protocol\r
+ // Driver binding handle may be different with its driver's Image handle\r
+ //\r
+ DriverBindingHandle = NULL;\r
+ DriverBinding = GetBindingProtocolFromImageHandle (\r
+ ImageHandle,\r
+ &DriverBindingHandle\r
+ );\r
+ ASSERT (DriverBinding != NULL);\r
DriverImageInfo->ImageHandle = ImageHandle;\r
}\r
} else {\r