Offset = 0;\r
Status = LocateCapabilityRegBlock (\r
PciIoDevice,\r
- EFI_PCI_CAPABILITY_ID_HOTPLUG,\r
+ EFI_PCI_CAPABILITY_ID_SHPC,\r
&Offset,\r
NULL\r
);\r
return FALSE;\r
}\r
\r
+/**\r
+ Check whether PciIoDevice supports PCIe hotplug.\r
+\r
+ This is equivalent to the following condition:\r
+ - the device is either a PCIe switch downstream port or a root port,\r
+ - and the device has the SlotImplemented bit set in its PCIe capability\r
+ register,\r
+ - and the device has the HotPlugCapable bit set in its slot capabilities\r
+ register.\r
+\r
+ @param[in] PciIoDevice The device being checked.\r
+\r
+ @retval TRUE PciIoDevice is a PCIe port that accepts a hotplugged device.\r
+ @retval FALSE Otherwise.\r
+\r
+**/\r
+BOOLEAN\r
+SupportsPcieHotplug (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ UINT32 Offset;\r
+ EFI_STATUS Status;\r
+ PCI_REG_PCIE_CAPABILITY Capability;\r
+ PCI_REG_PCIE_SLOT_CAPABILITY SlotCapability;\r
+\r
+ if (PciIoDevice == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Read the PCI Express Capabilities Register\r
+ //\r
+ if (!PciIoDevice->IsPciExp) {\r
+ return FALSE;\r
+ }\r
+ Offset = PciIoDevice->PciExpressCapabilityOffset +\r
+ OFFSET_OF (PCI_CAPABILITY_PCIEXP, Capability);\r
+ Status = PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint16,\r
+ Offset,\r
+ 1,\r
+ &Capability\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check the contents of the register\r
+ //\r
+ switch (Capability.Bits.DevicePortType) {\r
+ case PCIE_DEVICE_PORT_TYPE_ROOT_PORT:\r
+ case PCIE_DEVICE_PORT_TYPE_DOWNSTREAM_PORT:\r
+ break;\r
+ default:\r
+ return FALSE;\r
+ }\r
+ if (!Capability.Bits.SlotImplemented) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Read the Slot Capabilities Register\r
+ //\r
+ Offset = PciIoDevice->PciExpressCapabilityOffset +\r
+ OFFSET_OF (PCI_CAPABILITY_PCIEXP, SlotCapability);\r
+ Status = PciIoDevice->PciIo.Pci.Read (\r
+ &PciIoDevice->PciIo,\r
+ EfiPciIoWidthUint32,\r
+ Offset,\r
+ 1,\r
+ &SlotCapability\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check the contents of the register\r
+ //\r
+ if (SlotCapability.Bits.HotPlugCapable) {\r
+ return TRUE;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
/**\r
Get resource padding if the specified PCI bridge is a hot plug bus.\r
\r
return TRUE;\r
}\r
\r
+ if (SupportsPcieHotplug (PciIoDevice)) {\r
+ //\r
+ // If the PPB is a PCIe root complex port or a switch downstream port, and\r
+ // implements a hot-plug capable slot, then also return TRUE.\r
+ //\r
+ return TRUE;\r
+ }\r
+\r
//\r
// Otherwise, see if it is a Root HPC\r
//\r