[Skiboot] [PATCH v3] pci: Avoid hot resets at boot time

Russell Currey ruscur at russell.cc
Wed Oct 12 14:56:25 AEDT 2016


In the PCI post-fundamental reset code, a hot reset is performed at the
end.  This is causing issues at boot time as a reset signal is being sent
downstream before the links are up, which is causing issues on adapters
behind switches.  No errors result in skiboot, but the adapters are not
usable in Linux as a result.

Hot resets also occur in the FSP platform-specific code for conventional
PCI slots, which could cause issues.

This patch fixes some adapters not being configurable in Linux on some
systems.  The issue was not present in skiboot 5.2.x.

Cc: stable # 5.3.x
Signed-off-by: Russell Currey <ruscur at russell.cc>
---
v3: Skip to bringing the links up in the FSP code thanks to Gavin
---
 hw/p7ioc-phb.c                  |  4 ++--
 hw/phb3.c                       |  4 ++--
 hw/phb4.c                       |  8 -------
 platforms/ibm-fsp/firenze-pci.c | 47 ++++++-----------------------------------
 4 files changed, 10 insertions(+), 53 deletions(-)

diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c
index d2a18a3..1f1b362 100644
--- a/hw/p7ioc-phb.c
+++ b/hw/p7ioc-phb.c
@@ -2234,8 +2234,8 @@ static int64_t p7ioc_freset(struct pci_slot *slot)
 			return slot->ops.pfreset(slot);
 		}
 
-		pci_slot_set_state(slot, P7IOC_SLOT_HRESET_START);
-		return slot->ops.hreset(slot);
+		pci_slot_set_state(slot, P7IOC_SLOT_LINK_START);
+		return slot->ops.poll_link(slot);
 	default:
 		PHBERR(p, "FRESET: Unexpected slot state %08x\n",
 		       slot->state);
diff --git a/hw/phb3.c b/hw/phb3.c
index d0b5010..817137b 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -2240,8 +2240,8 @@ static int64_t phb3_pfreset(struct pci_slot *slot)
 		/* CAPP FPGA requires 1s to flash before polling link */
 		return pci_slot_set_sm_timeout(slot, secs_to_tb(1));
 	case PHB3_SLOT_PFRESET_DEASSERT_DELAY:
-		pci_slot_set_state(slot, PHB3_SLOT_HRESET_START);
-		return slot->ops.hreset(slot);
+		pci_slot_set_state(slot, PHB3_SLOT_LINK_START);
+		return slot->ops.poll_link(slot);
 	default:
 		PHBERR(p, "Unexpected slot state %08x\n", slot->state);
 	}
diff --git a/hw/phb4.c b/hw/phb4.c
index 385ce8c..efb6a5f 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -1951,16 +1951,8 @@ static int64_t phb4_pfreset(struct pci_slot *slot)
 		/* CAPP FPGA requires 1s to flash before polling link */
 		return pci_slot_set_sm_timeout(slot, secs_to_tb(1));
 	case PHB4_SLOT_PFRESET_DEASSERT_DELAY:
-#if 0 	/* PHB3 does a Hreset here. It's unnecessary I think and it's
-	 * causing problems with the simulator croc model so don't do
-	 * it until I figure out Gavin's reasons
-	 */
-		pci_slot_set_state(slot, PHB4_SLOT_HRESET_START);
-		return slot->ops.hreset(slot);
-#else
 		pci_slot_set_state(slot, PHB4_SLOT_LINK_START);
 		return slot->ops.poll_link(slot);
-#endif
 	default:
 		PHBERR(p, "Unexpected slot state %08x\n", slot->state);
 	}
diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c
index 4cc0284..1d83409 100644
--- a/platforms/ibm-fsp/firenze-pci.c
+++ b/platforms/ibm-fsp/firenze-pci.c
@@ -40,6 +40,8 @@
  * when you're going to change below values.
  */
 #define FIRENZE_PCI_SLOT_NORMAL			0x00000000
+#define FIRENZE_PCI_SLOT_LINK			0x00000100
+#define   FIRENZE_PCI_SLOT_LINK_START		0x00000101
 #define FIRENZE_PCI_SLOT_HRESET			0x00000200
 #define   FIRENZE_PCI_SLOT_HRESET_START		0x00000201
 #define FIRENZE_PCI_SLOT_FRESET			0x00000300
@@ -535,26 +537,8 @@ static int64_t firenze_pci_slot_freset(struct pci_slot *slot)
 		pval = (uint8_t *)(plat_slot->req->rw_buf);
 		*plat_slot->power_status = *pval;
 
-		/* PHB3 slot supports post fundamental reset, we switch
-		 * to that. For normal PCI slot, we switch to hot reset
-		 * instead.
-		 */
-		if (slot->ops.pfreset) {
-			prlog(PR_DEBUG, "%016llx FRESET: Switch to PFRESET\n",
-			      slot->id);
-			pci_slot_set_state(slot,
-				FIRENZE_PCI_SLOT_PFRESET_START);
-			return slot->ops.pfreset(slot);
-		} else if (slot->ops.hreset) {
-			prlog(PR_DEBUG, "%016llx FRESET: Switch to HRESET\n",
-			      slot->id);
-			pci_slot_set_state(slot,
-				FIRENZE_PCI_SLOT_HRESET_START);
-			return slot->ops.hreset(slot);
-		}
-
-		pci_slot_set_state(slot, FIRENZE_PCI_SLOT_NORMAL);
-		return OPAL_SUCCESS;
+		pci_slot_set_state(slot, FIRENZE_PCI_SLOT_LINK_START);
+		return slot->ops.poll_link(slot);
 	default:
 		prlog(PR_DEBUG, "%016llx FRESET: Unexpected state %08x\n",
 		      slot->id, slot->state);
@@ -615,27 +599,8 @@ static int64_t firenze_pci_slot_perst(struct pci_slot *slot)
 			FIRENZE_PCI_SLOT_PERST_DELAY);
 		return pci_slot_set_sm_timeout(slot, msecs_to_tb(1500));
 	case FIRENZE_PCI_SLOT_PERST_DELAY:
-		/*
-		 * Switch to post fundamental reset if the slot supports
-		 * that. Otherwise, we issue a proceeding hot reset on
-		 * the slot.
-		 */
-		if (slot->ops.pfreset) {
-			prlog(PR_DEBUG, "%016llx PERST: Switch to PFRESET\n",
-			      slot->id);
-			pci_slot_set_state(slot,
-				FIRENZE_PCI_SLOT_PFRESET_START);
-			return slot->ops.pfreset(slot);
-		} else if (slot->ops.hreset) {
-			prlog(PR_DEBUG, "%016llx PERST: Switch to HRESET\n",
-			      slot->id);
-			pci_slot_set_state(slot,
-				FIRENZE_PCI_SLOT_HRESET_START);
-			return slot->ops.hreset(slot);
-		}
-
-		pci_slot_set_state(slot, FIRENZE_PCI_SLOT_NORMAL);
-		return OPAL_SUCCESS;
+		pci_slot_set_state(slot, FIRENZE_PCI_SLOT_LINK_START);
+		return slot->ops.poll_link(slot);
 	default:
 		prlog(PR_DEBUG, "%016llx PERST: Unexpected state %08x\n",
 		      slot->id, slot->state);
-- 
2.10.0



More information about the Skiboot mailing list