/** @file\r
PCI Hot Plug support functions implementation for PCI Bus module..\r
\r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-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
}\r
\r
/**\r
- Compare two device pathes to check if they are exactly same.\r
+ Compare two device paths to check if they are exactly same.\r
\r
@param DevicePath1 A pointer to the first device path data structure.\r
@param DevicePath2 A pointer to the second device path data structure.\r
private data structure.\r
\r
@retval EFI_SUCCESS They are same.\r
- @retval EFI_UNSUPPORTED No PCI Hot Plug controler on the platform.\r
+ @retval EFI_UNSUPPORTED No PCI Hot Plug controller on the platform.\r
@retval EFI_OUT_OF_RESOURCES No memory to constructor root hot plug private\r
data structure.\r
\r
\r
@param HpbDevicePath A pointer to device path data structure to be tested.\r
@param HpIndex If HpIndex is not NULL, return the index of root hot\r
- plug in global array when TRUE is retuned.\r
+ plug in global array when TRUE is returned.\r
\r
@retval TRUE The device path is for root pci hot plug bus.\r
@retval FALSE The device path is not for root pci hot plug bus.\r
\r
@param HpcDevicePath A pointer to device path data structure to be tested.\r
@param HpIndex If HpIndex is not NULL, return the index of root hot\r
- plug in global array when TRUE is retuned.\r
+ plug in global array when TRUE is returned.\r
\r
@retval TRUE The device path is for root pci hot plug controller.\r
@retval FALSE The device path is not for root pci hot plug controller.\r
Creating event object for PCI Hot Plug controller.\r
\r
@param HpIndex Index of hot plug device in global array.\r
- @param Event The retuned event that invoke this function.\r
+ @param Event The returned event that invoke this function.\r
\r
- @return Status of create event invoken.\r
+ @return Status of create event.\r
\r
**/\r
EFI_STATUS\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 hot-plugged 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