diff mbox series

phb4: Restore bus numbers after CRS

Message ID 20180411032508.17651-1-mikey@neuling.org
State Accepted
Headers show
Series phb4: Restore bus numbers after CRS | expand

Commit Message

Michael Neuling April 11, 2018, 3:25 a.m. UTC
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@neuling.org>
---
 core/pci.c    | 16 ++++++++++++++++
 hw/phb4.c     | 13 +------------
 include/pci.h |  1 +
 3 files changed, 18 insertions(+), 12 deletions(-)

Comments

Stewart Smith April 12, 2018, 6:23 a.m. UTC | #1
Michael Neuling <mikey@neuling.org> writes:
> 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@neuling.org>
> ---
>  core/pci.c    | 16 ++++++++++++++++
>  hw/phb4.c     | 13 +------------
>  include/pci.h |  1 +
>  3 files changed, 18 insertions(+), 12 deletions(-)

Cheers, merged to master as of 00521231c8260a5c5ec3389aa79394708a9b98ce
diff mbox series

Patch

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,