[Skiboot] [PATCH 1/2] core/pci: Enforce polling PCIe link in hot-add path

Gavin Shan gwshan at linux.vnet.ibm.com
Tue Dec 20 18:10:27 AEDT 2016

In surprise hot-add path, the power state isn't changed on hardware.
Instead, we set the cached power state (@slot->power_state) and
return OPAL_SUCCESS. The upper layer starts the PCI probing immediately
when receiving OPAL_SUCCESS. However, the PCIe link behind the PCI
slot is likely down. Nothing will be probed from the PCI slot even
we do have PCI adpater connected to the slot.

This fixes the issue by returning OPAL_ASYNC_COMPLETION to force
upper layer to poll the PCIe link before probing the PCI devices
behind the slot in surprise and managed hot-add paths.

Cc: stable # 5.4.0+
Fixes: 51931bad325 ("core/pci: Claim surprise hotplug capability")
Reported-by: Hank Chang <hankmax0000 at gmail.com>
Signed-off-by: Gavin Shan <gwhsan at linux.vnet.ibm.com>
Tested-by: Willie Liauw <williel at supermicro.com.tw>
 core/pcie-slot.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/core/pcie-slot.c b/core/pcie-slot.c
index 4308d0b..e6f3dc1 100644
--- a/core/pcie-slot.c
+++ b/core/pcie-slot.c
@@ -218,9 +218,23 @@ static int64_t pcie_slot_set_power_state_ext(struct pci_slot *slot, uint8_t val,
 	/* The power supply to the slot should be always on when surprise
 	 * hotplug is claimed. For this case, update with the requested
 	 * power state and bail immediately.
+	 *
+	 * The PCIe link is likely down if we're powering on the slot upon
+	 * the detected presence. Nothing behind the slot will be probed if
+	 * we do it immediately even we do have PCI devices connected to the
+	 * slot. For this case, we force upper layer to wait for the PCIe
+	 * link to be up before probing the PCI devices behind the slot. It's
+	 * only concerned in surprise hotplug path. In managed hot-add path,
+	 * the PCIe link should have been ready before we power on the slot.
+	 * However, it's not harmful to do so in managed hot-add path.
 	if (surprise_check && slot->surprise_pluggable) {
 		slot->power_state = val;
+		if (val == PCI_SLOT_POWER_ON) {
+			pci_slot_set_state(slot, PCI_SLOT_STATE_SPOWER_DONE);
+		}
 		return OPAL_SUCCESS;

More information about the Skiboot mailing list