[Skiboot] [PATCH 2/2] core/pci: More reliable way to update PCI slot power state

Gavin Shan gwshan at linux.vnet.ibm.com
Fri Nov 18 15:53:20 AEDT 2016


The power control bit (SLOT_CTL, offset: PCIe cap + 0x18) isn't
reliable enough to reflect the PCI slot's power state. Instead,
the power indication bits are more reliable comparatively. This
leads to mismatch between the cached power state and PCI slot's
presence state, resulting in the hotplug driver in kernel refuses
to unplug the devices properly on the request. The issue was
found on below NVMe card on "ibm,powernvsupermicro,p8dtu2u" machine.
It's not existing on the integrated PLX 8718 switch.

 # lspci
 0022:01:00.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:02:01.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:02:04.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:02:05.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:02:06.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:02:07.0 PCI bridge: PLX Technology, Inc. PEX 9733 33-lane, \
              9-port PCI Express Gen 3 (8.0 GT/s) Switch (rev aa)
 0022:17:00.0 Non-Volatile memory controller: Device 19e5:0123 (rev 45)

This updates the cached PCI slot's power state using the power
indication bits instead of power control bit, to fix above issue.

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pcie-slot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/core/pcie-slot.c b/core/pcie-slot.c
index 109d2cb..b877cec 100644
--- a/core/pcie-slot.c
+++ b/core/pcie-slot.c
@@ -454,7 +454,7 @@ struct pci_slot *pcie_slot_create(struct phb *phb, struct pci_device *pd)
 		ecap = pci_cap(pd, PCI_CFG_CAP_ID_EXP, false);
 		pci_cfg_read16(phb, pd->bdfn,
 			       ecap + PCICAP_EXP_SLOTCTL, &slot_ctl);
-		if (slot_ctl & PCICAP_EXP_SLOTCTL_PWRCTLR)
+		if (((slot_ctl & PCICAP_EXP_SLOTCTL_PWRI) >> 8) == PCIE_INDIC_OFF)
 			slot->power_state = PCI_SLOT_POWER_OFF;
 	}
 
-- 
2.1.0



More information about the Skiboot mailing list