]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxePlatDriOverLib/PlatDriOverLib.c
1. Fixed bugs in DxeNetLib to meet consistence with network module DriverBinding...
[mirror_edk2.git] / MdeModulePkg / Library / DxePlatDriOverLib / PlatDriOverLib.c
index d32715bb40a84992b5eb7cfef9954706a246b975..0ba63fc5129c731b48106bb29aee42980ed4a6af 100644 (file)
@@ -63,7 +63,7 @@ InstallPlatformDriverOverrideProtocol (
   //\r
   if (!EFI_ERROR (Status)) {\r
     if (HandleBuffer != NULL) {\r
-      gBS->FreePool (HandleBuffer);\r
+      FreePool (HandleBuffer);\r
     }\r
     return EFI_ALREADY_STARTED;\r
   }\r
@@ -536,6 +536,92 @@ SaveOverridesMapping (
   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
@@ -582,6 +668,7 @@ GetDriverFromMapping (
   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
@@ -741,18 +828,27 @@ GetDriverFromMapping (
         }\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
@@ -774,12 +870,16 @@ GetDriverFromMapping (
                                                   &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
@@ -814,12 +914,16 @@ GetDriverFromMapping (
                 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