diff options
-rw-r--r-- | core/fast-reboot.c | 13 | ||||
-rw-r--r-- | core/pci.c | 11 | ||||
-rw-r--r-- | include/pci.h | 2 |
3 files changed, 18 insertions, 8 deletions
diff --git a/core/fast-reboot.c b/core/fast-reboot.c index 1c76c08..382e781 100644 --- a/core/fast-reboot.c +++ b/core/fast-reboot.c @@ -348,7 +348,18 @@ void __noreturn fast_reboot_entry(void) } /* Remove all PCI devices */ - pci_reset(); + if (pci_reset()) { + prlog(PR_NOTICE, "RESET: Fast reboot failed to reset PCI\n"); + + /* + * Can't return to caller here because we're past no-return. + * Attempt an IPL here which is what the caller would do. + */ + if (platform.cec_reboot) + platform.cec_reboot(); + for (;;) + ; + } ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT); @@ -1668,7 +1668,7 @@ static void __pci_reset(struct list_head *list) } } -void pci_reset(void) +int64_t pci_reset(void) { unsigned int i; struct pci_slot *slot; @@ -1695,11 +1695,9 @@ void pci_reset(void) rc = slot->ops.run_sm(slot); } if (rc < 0) { - PCIERR(phb, 0, "Complete reset failed, aborting" - "fast reboot (rc=%lld)\n", rc); - if (platform.cec_reboot) - platform.cec_reboot(); - while (true) {} + PCIERR(phb, 0, "Complete reset failed " + "(rc=%lld)\n", rc); + return rc; } } @@ -1710,6 +1708,7 @@ void pci_reset(void) /* Re-Initialize all discovered PCI slots */ pci_init_slots(); + return 0; } static void pci_do_jobs(void (*fn)(void *)) diff --git a/include/pci.h b/include/pci.h index c085b6b..508ebf4 100644 --- a/include/pci.h +++ b/include/pci.h @@ -475,7 +475,7 @@ extern void pci_std_swizzle_irq_map(struct dt_node *dt_node, /* Initialize all PCI slots */ extern void pci_init_slots(void); -extern void pci_reset(void); +extern int64_t pci_reset(void); extern void opal_pci_eeh_set_evt(uint64_t phb_id); extern void opal_pci_eeh_clear_evt(uint64_t phb_id); |