[Skiboot] [PATCH] phb4: Restore bus numbers after CRS

Michael Neuling mikey at neuling.org
Wed Apr 11 13:25:08 AEST 2018


Currently we restore PCIe bus numbers right after the link is
up. Unfortunately as this point we haven't done CRS so config space
may not be accessible.

This moves the bus number restore till after CRS has happened.

Signed-off-by: Michael Neuling <mikey at neuling.org>
---
 core/pci.c    | 16 ++++++++++++++++
 hw/phb4.c     | 13 +------------
 include/pci.h |  1 +
 3 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/core/pci.c b/core/pci.c
index b5a1c62de1..98d8b541f6 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1886,6 +1886,22 @@ void pci_restore_bridge_buses(struct phb *phb, struct pci_device *pd)
 	pci_walk_dev(phb, pd, __pci_restore_bridge_buses, NULL);
 }
 
+void pci_restore_slot_bus_configs(struct pci_slot *slot)
+{
+	/*
+	 * We might lose the bus numbers during the reset operation
+	 * and we need to restore them. Otherwise, some adapters (e.g.
+	 * IPR) can't be probed properly by the kernel. We don't need
+	 * to restore bus numbers for every kind of reset, however,
+	 * it's not harmful to always restore the bus numbers, which
+	 * simplifies the logic.
+	 */
+	pci_restore_bridge_buses(slot->phb, slot->pd);
+	if (slot->phb->ops->device_init)
+		pci_walk_dev(slot->phb, slot->pd,
+			     slot->phb->ops->device_init, NULL);
+}
+
 struct pci_cfg_reg_filter *pci_find_cfg_reg_filter(struct pci_device *pd,
 						   uint32_t start, uint32_t len)
 {
diff --git a/hw/phb4.c b/hw/phb4.c
index 823ed431cf..e249f7b08f 100644
--- a/hw/phb4.c
+++ b/hw/phb4.c
@@ -2146,18 +2146,6 @@ static void phb4_prepare_link_change(struct pci_slot *slot, bool is_up)
 		out_be64(p->regs + PHB_REGB_ERR_FAT_ENABLE,
 			 0xde0fff91035743ffull);
 
-		/*
-		 * We might lose the bus numbers during the reset operation
-		 * and we need to restore them. Otherwise, some adapters (e.g.
-		 * IPR) can't be probed properly by the kernel. We don't need
-		 * to restore bus numbers for every kind of reset, however,
-		 * it's not harmful to always restore the bus numbers, which
-		 * simplifies the logic.
-		 */
-		pci_restore_bridge_buses(slot->phb, slot->pd);
-		if (slot->phb->ops->device_init)
-			pci_walk_dev(slot->phb, slot->pd,
-				     slot->phb->ops->device_init, NULL);
 	} else {
 		/* Mask AER receiver error */
 		phb4_pcicfg_read32(&p->phb, 0, p->aercap +
@@ -2691,6 +2679,7 @@ static int64_t phb4_poll_link(struct pci_slot *slot)
 				 */
 				PHBERR(p, "LINK: Degraded but no more retries\n");
 			}
+			pci_restore_slot_bus_configs(slot);
 			pci_slot_set_state(slot, PHB4_SLOT_NORMAL);
 			return OPAL_SUCCESS;
 		}
diff --git a/include/pci.h b/include/pci.h
index 0c2858c8b2..6141159f2f 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -436,6 +436,7 @@ extern int64_t pci_find_ecap(struct phb *phb, uint16_t bdfn, uint16_t cap,
 			     uint8_t *version);
 extern void pci_init_capabilities(struct phb *phb, struct pci_device *pd);
 extern bool pci_wait_crs(struct phb *phb, uint16_t bdfn, uint32_t *out_vdid);
+extern void pci_restore_slot_bus_configs(struct pci_slot *slot);
 extern void pci_device_init(struct phb *phb, struct pci_device *pd);
 extern struct pci_device *pci_walk_dev(struct phb *phb,
 				       struct pci_device *pd,
-- 
2.14.1



More information about the Skiboot mailing list