[Skiboot] [PATCH v4 09/10] PCI: Reinitialize devices on slot reset

Gavin Shan gwshan at linux.vnet.ibm.com
Tue Feb 17 17:48:56 AEDT 2015


After slot reset is completed, we need restore those affected PCI
devices to state before reset. The patch reuses existing callback
(struct phb_ops::device_init()) for the purpose. The function needs
another unused parameter to be called by pci_walk_dev().

Signed-off-by: Gavin Shan <gwshan at linux.vnet.ibm.com>
---
 core/pci-slot.c |  4 +++-
 core/pci.c      |  2 +-
 hw/p7ioc-phb.c  | 12 +++++++++---
 hw/phb3.c       | 12 +++++++++---
 include/pci.h   |  3 ++-
 5 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/core/pci-slot.c b/core/pci-slot.c
index 3692c07..170b4b2 100644
--- a/core/pci-slot.c
+++ b/core/pci-slot.c
@@ -305,7 +305,9 @@ static void pcie_slot_prepare_link_change(struct pci_slot *slot,
 	 */
 	if (is_up) {
 		pci_restore_bridge_buses(phb, pd);
-		pci_device_init(phb, pd);
+		if (phb->ops->device_init)
+			pci_walk_dev(phb, pd,
+				     phb->ops->device_init, NULL);
 	}
 }
 
diff --git a/core/pci.c b/core/pci.c
index 8977690..f5ff2ab 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -249,7 +249,7 @@ static struct pci_device *pci_scan_one(struct phb *phb, struct pci_device *paren
 	 * Call PHB hook
 	 */
 	if (phb->ops->device_init)
-		phb->ops->device_init(phb, pd);
+		phb->ops->device_init(phb, pd, NULL);
 
 	return pd;
  fail:
diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c
index b66bfd3..d95de5d 100644
--- a/hw/p7ioc-phb.c
+++ b/hw/p7ioc-phb.c
@@ -1521,7 +1521,8 @@ static void p7ioc_endpoint_init(struct phb *phb,
 	pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
 }
 
-static void p7ioc_device_init(struct phb *phb, struct pci_device *dev)
+static int p7ioc_device_init(struct phb *phb,
+			     struct pci_device *dev, void *data __unused)
 {
 	int ecap = 0;
 	int aercap = 0;
@@ -1550,6 +1551,8 @@ static void p7ioc_device_init(struct phb *phb, struct pci_device *dev)
 		p7ioc_switch_port_init(phb, dev, ecap, aercap);
 	else
 		p7ioc_endpoint_init(phb, dev, ecap, aercap);
+
+	return 0;
 }
 
 static int64_t p7ioc_pci_reinit(struct phb *phb,
@@ -1565,7 +1568,7 @@ static int64_t p7ioc_pci_reinit(struct phb *phb,
 	if (!pd)
 		return OPAL_PARAMETER;
 
-	p7ioc_device_init(phb, pd);
+	p7ioc_device_init(phb, pd, NULL);
 	return OPAL_SUCCESS;
 }
 
@@ -2056,7 +2059,10 @@ static void p7ioc_prepare_link_change(struct pci_slot *slot,
 		 * it's not harmful to restore the bus numbers, which makes
 		 * the logic simplified
 		 */
-		pci_restore_bridge_buses(&p->phb, NULL);
+		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);
 	}
 }
 
diff --git a/hw/phb3.c b/hw/phb3.c
index b67d38f..a88b202 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -393,7 +393,8 @@ static void phb3_endpoint_init(struct phb *phb,
 	pci_cfg_write32(phb, bdfn, aercap + PCIECAP_AER_CAPCTL, val32);
 }
 
-static void phb3_device_init(struct phb *phb, struct pci_device *dev)
+static int phb3_device_init(struct phb *phb,
+			    struct pci_device *dev, void *data __unused)
 {
 	int ecap = 0;
 	int aercap = 0;
@@ -422,6 +423,8 @@ static void phb3_device_init(struct phb *phb, struct pci_device *dev)
 		phb3_switch_port_init(phb, dev, ecap, aercap);
 	else
 		phb3_endpoint_init(phb, dev, ecap, aercap);
+
+	return 0;
 }
 
 static int64_t phb3_pci_reinit(struct phb *phb, uint64_t scope, uint64_t data)
@@ -436,7 +439,7 @@ static int64_t phb3_pci_reinit(struct phb *phb, uint64_t scope, uint64_t data)
 	if (!pd)
 		return OPAL_PARAMETER;
 
-	phb3_device_init(phb, pd);
+	phb3_device_init(phb, pd, NULL);
 	return OPAL_SUCCESS;
 }
 
@@ -1809,7 +1812,10 @@ static void phb3_prepare_link_change(struct pci_slot *slot,
 		 * it's not harmful to restore the bus numbers, which makes
 		 * the logic simplified
 		 */
-		pci_restore_bridge_buses(&p->phb, NULL);
+		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);
 	}
 }
 
diff --git a/include/pci.h b/include/pci.h
index e1d75a1..3731328 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -168,7 +168,8 @@ struct phb_ops {
 	 * and before probing further. It can alter things like scan_map
 	 * for bridge ports etc...
 	 */
-	void (*device_init)(struct phb *phb, struct pci_device *device);
+	int (*device_init)(struct phb *phb,
+			    struct pci_device *device, void *data);
 
 	/*
 	 * EEH methods
-- 
1.8.3.2



More information about the Skiboot mailing list