]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
MdeModulePkg/PciBusDxe: Fix small memory leak in FreePciDevice
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciLib.c
index bfb7e5bee98ac5edeaae027b32296766cf6cda71..b81f81a1368a028dfb1c5bbd6df4ca714318959a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Internal library implementation for PCI Bus module.\r
 \r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -29,6 +29,43 @@ CHAR16 *mBarTypeStr[] = {
   L"Unknow"\r
   };\r
 \r
+/**\r
+  Retrieve the max bus number that is assigned to the Root Bridge hierarchy.\r
+  It can support the case that there are multiple bus ranges.\r
+\r
+  @param  Bridge           Bridge device instance.\r
+\r
+  @retval                  The max bus number that is assigned to this Root Bridge hierarchy.\r
+\r
+**/\r
+UINT16\r
+PciGetMaxBusNumber (\r
+  IN PCI_IO_DEVICE                      *Bridge\r
+  )\r
+{\r
+  PCI_IO_DEVICE                      *RootBridge;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *BusNumberRanges;\r
+  UINT64                             MaxNumberInRange;\r
+\r
+  //\r
+  // Get PCI Root Bridge device\r
+  //\r
+  RootBridge = Bridge;\r
+  while (RootBridge->Parent != NULL) {\r
+    RootBridge = RootBridge->Parent;\r
+  }\r
+  MaxNumberInRange = 0;\r
+  //\r
+  // Iterate the bus number ranges to get max PCI bus number\r
+  //\r
+  BusNumberRanges = RootBridge->BusNumberRanges;\r
+  while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+    MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;\r
+    BusNumberRanges++;\r
+  }\r
+  return (UINT16) MaxNumberInRange;\r
+}\r
+\r
 /**\r
   Retrieve the PCI Card device BAR information via PciIo interface.\r
 \r
@@ -232,11 +269,11 @@ DumpBridgeResource (
 \r
 /**\r
   Find the corresponding resource node for the Device in child list of BridgeResource.\r
-  \r
+\r
   @param[in]  Device          Pointer to PCI_IO_DEVICE.\r
   @param[in]  BridgeResource  Pointer to PCI_RESOURCE_NODE.\r
   @param[out] DeviceResources Pointer to a buffer to receive resources for the Device.\r
-  \r
+\r
   @return Count of the resource descriptors returned.\r
 **/\r
 UINTN\r
@@ -269,7 +306,7 @@ FindResourceNode (
 \r
 /**\r
   Dump the resource map of all the devices under Bridge.\r
-  \r
+\r
   @param[in] Bridge        Bridge device instance.\r
   @param[in] Resources     Resource descriptors for the bridge device.\r
   @param[in] ResourceCount Count of resource descriptors.\r
@@ -429,7 +466,7 @@ PciHostBridgeResourceAllocator (
       //\r
 \r
       //\r
-      // If non-stardard PCI Bridge I/O window alignment is supported,\r
+      // If non-standard PCI Bridge I/O window alignment is supported,\r
       // set I/O aligment to minimum possible alignment for root bridge.\r
       //\r
       IoBridge = CreateResourceNode (\r
@@ -522,7 +559,7 @@ PciHostBridgeResourceAllocator (
       }\r
 \r
       //\r
-      // Based on the all the resource tree, contruct ACPI resource node to\r
+      // Based on the all the resource tree, construct ACPI resource node to\r
       // submit the resource aperture to pci host bridge protocol\r
       //\r
       Status = ConstructAcpiResourceRequestor (\r
@@ -868,7 +905,7 @@ PciHostBridgeResourceAllocator (
       Resources[2] = PMem32Bridge;\r
       Resources[3] = Mem64Bridge;\r
       Resources[4] = PMem64Bridge;\r
-      DumpResourceMap (RootBridgeDev, Resources, sizeof (Resources) / sizeof (Resources[0]));\r
+      DumpResourceMap (RootBridgeDev, Resources, ARRAY_SIZE (Resources));\r
     );\r
 \r
     FreePool (AcpiConfig);\r
@@ -976,7 +1013,8 @@ PciScanBus (
   UINT8                             Device;\r
   UINT8                             Func;\r
   UINT64                            Address;\r
-  UINTN                             SecondBus;\r
+  UINT8                             SecondBus;\r
+  UINT8                             PaddedSubBus;\r
   UINT16                            Register;\r
   UINTN                             HpIndex;\r
   PCI_IO_DEVICE                     *PciDevice;\r
@@ -985,6 +1023,7 @@ PciScanBus (
   UINT64                            PciAddress;\r
   EFI_HPC_PADDING_ATTRIBUTES        Attributes;\r
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *NextDescriptors;\r
   UINT16                            BusRange;\r
   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL   *PciRootBridgeIo;\r
   BOOLEAN                           BusPadding;\r
@@ -1123,14 +1162,14 @@ PciScanBus (
           BusPadding = FALSE;\r
           if (gPciHotPlugInit != NULL) {\r
 \r
-            if (IsRootPciHotPlugBus (PciDevice->DevicePath, &HpIndex)) {\r
+            if (IsPciHotPlugBus (PciDevice)) {\r
 \r
               //\r
               // If it is initialized, get the padded bus range\r
               //\r
               Status = gPciHotPlugInit->GetResourcePadding (\r
                                           gPciHotPlugInit,\r
-                                          gPciRootHpcPool[HpIndex].HpbDevicePath,\r
+                                          PciDevice->DevicePath,\r
                                           PciAddress,\r
                                           &State,\r
                                           (VOID **) &Descriptors,\r
@@ -1142,8 +1181,9 @@ PciScanBus (
               }\r
 \r
               BusRange = 0;\r
+              NextDescriptors = Descriptors;\r
               Status = PciGetBusRange (\r
-                        &Descriptors,\r
+                        &NextDescriptors,\r
                         NULL,\r
                         NULL,\r
                         &BusRange\r
@@ -1151,11 +1191,14 @@ PciScanBus (
 \r
               FreePool (Descriptors);\r
 \r
-              if (EFI_ERROR (Status)) {\r
+              if (!EFI_ERROR (Status)) {\r
+                BusPadding = TRUE;\r
+              } else if (Status != EFI_NOT_FOUND) {\r
+                //\r
+                // EFI_NOT_FOUND is not a real error. It indicates no bus number padding requested.\r
+                //\r
                 return Status;\r
               }\r
-\r
-              BusPadding = TRUE;\r
             }\r
           }\r
         }\r
@@ -1187,7 +1230,7 @@ PciScanBus (
           // Temporarily initialize SubBusNumber to maximum bus number to ensure the\r
           // PCI configuration transaction to go through any PPB\r
           //\r
-          Register  = 0xFF;\r
+          Register  = PciGetMaxBusNumber (Bridge);\r
           Address   = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET);\r
           Status = PciRootBridgeIo->Pci.Write (\r
                                           PciRootBridgeIo,\r
@@ -1210,7 +1253,7 @@ PciScanBus (
 \r
           Status = PciScanBus (\r
                     PciDevice,\r
-                    (UINT8) (SecondBus),\r
+                    SecondBus,\r
                     SubBusNumber,\r
                     PaddedBusRange\r
                     );\r
@@ -1226,12 +1269,16 @@ PciScanBus (
           if ((Attributes == EfiPaddingPciRootBridge) &&\r
               (State & EFI_HPC_STATE_ENABLED) != 0    &&\r
               (State & EFI_HPC_STATE_INITIALIZED) != 0) {\r
-            *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
+            *PaddedBusRange = (UINT8) ((UINT8) (BusRange) + *PaddedBusRange);\r
           } else {\r
-            Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (BusRange), SubBusNumber);\r
+            //\r
+            // Reserve the larger one between the actual occupied bus number and padded bus number\r
+            //\r
+            Status = PciAllocateBusNumber (PciDevice, SecondBus, (UINT8) (BusRange), &PaddedSubBus);\r
             if (EFI_ERROR (Status)) {\r
               return Status;\r
             }\r
+            *SubBusNumber = MAX (PaddedSubBus, *SubBusNumber);\r
           }\r
         }\r
 \r