]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
MdeModulePkg PciBusDxe: The PCI Bus Driver is updated to support multiple PCI bus...
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / PciBusDxe / PciLib.c
index eba5efdce215fed643dcef540c946b7fba940462..87ee61956ac92f501c181294b7cde4534fe1ab71 100644 (file)
@@ -896,6 +896,64 @@ PciHostBridgeResourceAllocator (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Allocate NumberOfBuses buses and return the next available PCI bus number.\r
+\r
+  @param  Bridge           Bridge device instance.\r
+  @param  StartBusNumber   Current available PCI bus number.\r
+  @param  NumberOfBuses    Number of buses enumerated below the StartBusNumber.\r
+  @param  NextBusNumber    Next available PCI bus number.\r
+\r
+  @retval EFI_SUCCESS           Available bus number resource is enough. Next available PCI bus number\r
+                                is returned in NextBusNumber.\r
+  @retval EFI_OUT_OF_RESOURCES  Available bus number resource is not enough for allocation.\r
+\r
+**/\r
+EFI_STATUS\r
+PciAllocateBusNumber (\r
+  IN PCI_IO_DEVICE                      *Bridge,\r
+  IN UINT8                              StartBusNumber,\r
+  IN UINT8                              NumberOfBuses,\r
+  OUT UINT8                             *NextBusNumber\r
+  )\r
+{\r
+  PCI_IO_DEVICE                      *RootBridge;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR  *BusNumberRanges;\r
+  UINT8                              NextNumber;\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
+\r
+  //\r
+  // Get next available PCI bus number\r
+  //\r
+  BusNumberRanges = RootBridge->BusNumberRanges;\r
+  while (BusNumberRanges->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
+    MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;\r
+    if (StartBusNumber >= BusNumberRanges->AddrRangeMin && StartBusNumber <=  MaxNumberInRange) {\r
+      NextNumber = StartBusNumber + NumberOfBuses;\r
+      while (NextNumber > MaxNumberInRange) {\r
+        ++BusNumberRanges;\r
+        if (BusNumberRanges->Desc == ACPI_END_TAG_DESCRIPTOR) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        NextNumber += (UINT8)(BusNumberRanges->AddrRangeMin - (MaxNumberInRange + 1));\r
+        MaxNumberInRange = BusNumberRanges->AddrRangeMin + BusNumberRanges->AddrLen - 1;\r
+      }\r
+      *NextBusNumber = NextNumber;\r
+      return EFI_SUCCESS;\r
+    }\r
+    BusNumberRanges++;\r
+  }\r
+  return EFI_OUT_OF_RESOURCES;\r
+}\r
+\r
 /**\r
   Scan pci bus and assign bus number to the given PCI bus system.\r
 \r
@@ -1100,15 +1158,10 @@ PciScanBus (
           }\r
         }\r
 \r
-        //\r
-        // Add feature to support customized secondary bus number\r
-        //\r
-        if (*SubBusNumber == 0) {\r
-          *SubBusNumber   = *PaddedBusRange;\r
-          *PaddedBusRange = 0;\r
+        Status = PciAllocateBusNumber (Bridge, *SubBusNumber, 1, SubBusNumber);\r
+        if (EFI_ERROR (Status)) {\r
+          return Status;\r
         }\r
-\r
-        (*SubBusNumber)++;\r
         SecondBus = *SubBusNumber;\r
 \r
         Register  = (UINT16) ((SecondBus << 8) | (UINT16) StartBusNumber);\r
@@ -1173,7 +1226,10 @@ PciScanBus (
               (State & EFI_HPC_STATE_INITIALIZED) != 0) {\r
             *PaddedBusRange = (UINT8) ((UINT8) (BusRange) +*PaddedBusRange);\r
           } else {\r
-            *SubBusNumber = (UINT8) ((UINT8) (BusRange) +*SubBusNumber);\r
+            Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (BusRange), SubBusNumber);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
           }\r
         }\r
 \r
@@ -1197,7 +1253,10 @@ PciScanBus (
         if (PcdGetBool (PcdSrIovSupport) && PciDevice->SrIovCapabilityOffset != 0) {\r
           if (TempReservedBusNum < PciDevice->ReservedBusNum) {\r
 \r
-            (*SubBusNumber) = (UINT8)((*SubBusNumber) + PciDevice->ReservedBusNum - TempReservedBusNum);\r
+            Status = PciAllocateBusNumber (PciDevice, *SubBusNumber, (UINT8) (PciDevice->ReservedBusNum - TempReservedBusNum), SubBusNumber);\r
+            if (EFI_ERROR (Status)) {\r
+              return Status;\r
+            }\r
             TempReservedBusNum = PciDevice->ReservedBusNum;\r
 \r
             if (Func == 0) {\r