[Skiboot] [PATCH v5 12/15] PCI: Reinitialize devices on slot reset
Gavin Shan
gwshan at linux.vnet.ibm.com
Mon Apr 27 16:26:30 AEST 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 f985820..66cceb1 100644
--- a/core/pci-slot.c
+++ b/core/pci-slot.c
@@ -306,7 +306,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 c749d2a..5540d75 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 efc2a63..43b8346 100644
--- a/hw/p7ioc-phb.c
+++ b/hw/p7ioc-phb.c
@@ -1522,7 +1522,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;
@@ -1551,6 +1552,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,
@@ -1566,7 +1569,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;
}
@@ -2057,7 +2060,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 633179d..abba1e0 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -395,7 +395,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;
@@ -424,6 +425,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)
@@ -438,7 +441,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;
}
@@ -1811,7 +1814,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 66e22c8..ec104ad 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -188,7 +188,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
--
2.1.0
More information about the Skiboot
mailing list