/** @file\r
Internal library implementation for PCI Bus module.\r
\r
-Copyright (c) 2006 - 2016, 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
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
\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
\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
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
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
}\r
\r
BusRange = 0;\r
+ NextDescriptors = Descriptors;\r
Status = PciGetBusRange (\r
- &Descriptors,\r
+ &NextDescriptors,\r
NULL,\r
NULL,\r
&BusRange\r
\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
// 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