]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciDriverOverride.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciDriverOverride.c
index 119866b3c167c0743e3a112a2e6a1e7575f63877..3531e6b6efd59843768d46df8534334780dc7e65 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
-  Functions implementation for Bus Specific Driver Override protoocl.\r
+  Functions implementation for Bus Specific Driver Override protocol.\r
 \r
-Copyright (c) 2006 - 2009, 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
+Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -28,6 +22,56 @@ InitializePciDriverOverrideInstance (
   PciIoDevice->PciDriverOverride.GetDriver = GetDriver;\r
 }\r
 \r
+/**\r
+  Find the image handle whose path equals to ImagePath.\r
+\r
+  @param ImagePath   Image path.\r
+\r
+  @return Image handle.\r
+**/\r
+EFI_HANDLE\r
+LocateImageHandle (\r
+  IN EFI_DEVICE_PATH_PROTOCOL   *ImagePath\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *Handles;\r
+  UINTN                         Index;\r
+  UINTN                         HandleNum;\r
+  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;\r
+  UINTN                         ImagePathSize;\r
+  EFI_HANDLE                    ImageHandle;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiLoadedImageDevicePathProtocolGuid,\r
+                  NULL,\r
+                  &HandleNum,\r
+                  &Handles\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return NULL;\r
+  }\r
+\r
+  ImageHandle   = NULL;\r
+  ImagePathSize = GetDevicePathSize (ImagePath);\r
+\r
+  for (Index = 0; Index < HandleNum; Index++) {\r
+    Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &DevicePath);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+    if ((ImagePathSize == GetDevicePathSize (DevicePath)) &&\r
+        (CompareMem (ImagePath, DevicePath, ImagePathSize) == 0)\r
+        ) {\r
+      ImageHandle = Handles[Index];\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (Handles);\r
+  return ImageHandle;\r
+}\r
 \r
 /**\r
   Uses a bus specific algorithm to retrieve a driver image handle for a controller.\r
@@ -53,49 +97,60 @@ GetDriver (
   )\r
 {\r
   PCI_IO_DEVICE             *PciIoDevice;\r
-  LIST_ENTRY                *CurrentLink;\r
-  PCI_DRIVER_OVERRIDE_LIST  *Node;\r
+  LIST_ENTRY                *Link;\r
+  PCI_DRIVER_OVERRIDE_LIST  *Override;\r
+  BOOLEAN                   ReturnNext;\r
 \r
+  Override    = NULL;\r
   PciIoDevice = PCI_IO_DEVICE_FROM_PCI_DRIVER_OVERRIDE_THIS (This);\r
+  ReturnNext  = (BOOLEAN) (*DriverImageHandle == NULL);\r
+  for ( Link = GetFirstNode (&PciIoDevice->OptionRomDriverList)\r
+      ; !IsNull (&PciIoDevice->OptionRomDriverList, Link)\r
+      ; Link = GetNextNode (&PciIoDevice->OptionRomDriverList, Link)\r
+      ) {\r
 \r
-  CurrentLink = PciIoDevice->OptionRomDriverList.ForwardLink;\r
-\r
-  while (CurrentLink != NULL && CurrentLink != &PciIoDevice->OptionRomDriverList) {\r
-\r
-    Node = DRIVER_OVERRIDE_FROM_LINK (CurrentLink);\r
+    Override = DRIVER_OVERRIDE_FROM_LINK (Link);\r
 \r
-    if (*DriverImageHandle == NULL) {\r
-\r
-      *DriverImageHandle = Node->DriverImageHandle;\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    if (*DriverImageHandle == Node->DriverImageHandle) {\r
-\r
-      if (CurrentLink->ForwardLink == &PciIoDevice->OptionRomDriverList ||\r
-          CurrentLink->ForwardLink == NULL) {\r
-        return EFI_NOT_FOUND;\r
+    if (ReturnNext) {\r
+      if (Override->DriverImageHandle == NULL) {\r
+        Override->DriverImageHandle = LocateImageHandle (Override->DriverImagePath);\r
       }\r
 \r
-      //\r
-      // Get next node\r
-      //\r
-      Node                = DRIVER_OVERRIDE_FROM_LINK (CurrentLink->ForwardLink);\r
-      *DriverImageHandle  = Node->DriverImageHandle;\r
-      return EFI_SUCCESS;\r
+      if (Override->DriverImageHandle == NULL) {\r
+        //\r
+        // The Option ROM identified by Override->DriverImagePath is not loaded.\r
+        //\r
+        continue;\r
+      } else {\r
+        *DriverImageHandle = Override->DriverImageHandle;\r
+        return EFI_SUCCESS;\r
+      }\r
     }\r
 \r
-    CurrentLink = CurrentLink->ForwardLink;\r
+    if (*DriverImageHandle == Override->DriverImageHandle) {\r
+      ReturnNext = TRUE;\r
+    }\r
   }\r
 \r
-  return EFI_INVALID_PARAMETER;\r
+  ASSERT (IsNull (&PciIoDevice->OptionRomDriverList, Link));\r
+  //\r
+  // ReturnNext indicates a handle match happens.\r
+  // If all nodes are checked without handle match happening,\r
+  // the DriverImageHandle should be a invalid handle.\r
+  //\r
+  if (ReturnNext) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
 }\r
 \r
 /**\r
   Add an overriding driver image.\r
 \r
   @param PciIoDevice        Instance of PciIo device.\r
-  @param DriverImageHandle  new added driver image.\r
+  @param DriverImageHandle  Image handle of newly added driver image.\r
+  @param DriverImagePath    Device path of newly added driver image.\r
 \r
   @retval EFI_SUCCESS          Successfully added driver.\r
   @retval EFI_OUT_OF_RESOURCES No memory resource for new driver instance.\r
@@ -104,40 +159,30 @@ GetDriver (
 **/\r
 EFI_STATUS\r
 AddDriver (\r
-  IN PCI_IO_DEVICE     *PciIoDevice,\r
-  IN EFI_HANDLE        DriverImageHandle\r
+  IN PCI_IO_DEVICE            *PciIoDevice,\r
+  IN EFI_HANDLE               DriverImageHandle,\r
+  IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath\r
   )\r
 {\r
-  EFI_STATUS                    Status;\r
-  EFI_LOADED_IMAGE_PROTOCOL     *LoadedImage;\r
-  PE_COFF_LOADER_IMAGE_CONTEXT  ImageContext;\r
   PCI_DRIVER_OVERRIDE_LIST      *Node;\r
 \r
-  Status = gBS->HandleProtocol (DriverImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  //\r
+  // Caller should pass in either Image Handle or Image Path, but not both.\r
+  //\r
+  ASSERT ((DriverImageHandle == NULL) || (DriverImagePath == NULL));\r
 \r
-  Node = AllocatePool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
+  Node = AllocateZeroPool (sizeof (PCI_DRIVER_OVERRIDE_LIST));\r
   if (Node == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
   Node->Signature         = DRIVER_OVERRIDE_SIGNATURE;\r
   Node->DriverImageHandle = DriverImageHandle;\r
+  Node->DriverImagePath   = DuplicateDevicePath (DriverImagePath);\r
 \r
-  InsertTailList (&PciIoDevice->OptionRomDriverList, &(Node->Link));\r
+  InsertTailList (&PciIoDevice->OptionRomDriverList, &Node->Link);\r
 \r
   PciIoDevice->BusOverride  = TRUE;\r
-\r
-  ImageContext.Handle    = LoadedImage->ImageBase;\r
-  ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
-\r
-  //\r
-  // Get information about the image\r
-  //\r
-  PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
   return EFI_SUCCESS;\r
 }\r
 \r