aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/pci.c15
-rw-r--r--include/pci.h2
2 files changed, 12 insertions, 5 deletions
diff --git a/core/pci.c b/core/pci.c
index aceaa35..56f0b2a 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -307,10 +307,12 @@ static struct pci_device *pci_scan_one(struct phb *phb, struct pci_device *paren
* everything (default state of our backend) so
* we just check and clear the state of PE#0
*
+ * returns true if a freeze was detected
+ *
* NOTE: We currently only handle simple PE freeze, not PHB fencing
* (or rather our backend does)
*/
-static void pci_check_clear_freeze(struct phb *phb)
+bool pci_check_clear_freeze(struct phb *phb)
{
uint8_t freeze_state;
uint16_t pci_error_type, sev;
@@ -321,23 +323,26 @@ static void pci_check_clear_freeze(struct phb *phb)
if (phb->ops->get_reserved_pe_number)
pe_number = phb->ops->get_reserved_pe_number(phb);
if (pe_number < 0)
- return;
+ return false;
/* Retrieve the frozen state */
rc = phb->ops->eeh_freeze_status(phb, pe_number, &freeze_state,
&pci_error_type, &sev);
if (rc)
- return;
+ return true; /* phb fence? */
+
if (freeze_state == OPAL_EEH_STOPPED_NOT_FROZEN)
- return;
+ return false;
/* We can't handle anything worse than an ER here */
if (sev > OPAL_EEH_SEV_NO_ERROR &&
sev < OPAL_EEH_SEV_PE_ER) {
PCIERR(phb, 0, "Fatal probe in %s error !\n", __func__);
- return;
+ return true;
}
+
phb->ops->eeh_freeze_clear(phb, pe_number,
OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+ return true;
}
/*
diff --git a/include/pci.h b/include/pci.h
index b840409..18deb2f 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -392,6 +392,8 @@ static inline void phb_unlock(struct phb *phb)
unlock(&phb->lock);
}
+bool pci_check_clear_freeze(struct phb *phb);
+
/* Config space ops wrappers */
static inline int64_t pci_cfg_read8(struct phb *phb, uint32_t bdfn,
uint32_t offset, uint8_t *data)