X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=arch%2Fpowerpc%2Fplatforms%2Fpseries%2Feeh_driver.c;h=68ea5eee39a832ddd054b9fe36d78d301f884f67;hb=2c4aabcca847ac4c92aa5e960c3f6053e1051b62;hp=161a5844ab6c243da27df37ba188fc5e98e72eba;hpb=eedab661a51966c454e38c17266a531aa58b4a98;p=linux-2.6 diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 161a5844ab..68ea5eee39 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -1,6 +1,7 @@ /* * PCI Error Recovery Driver for RPA-compliant PPC64 platform. - * Copyright (C) 2004, 2005 Linas Vepstas + * Copyright IBM Corp. 2004 2005 + * Copyright Linas Vepstas 2004, 2005 * * All rights reserved. * @@ -19,8 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to - * + * Send comments and feedback to Linas Vepstas */ #include #include @@ -105,17 +105,18 @@ static void eeh_report_error(struct pci_dev *dev, void *userdata) return; rc = driver->err_handler->error_detected (dev, pci_channel_io_frozen); + + /* A driver that needs a reset trumps all others */ + if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; - if (*res == PCI_ERS_RESULT_DISCONNECT && - rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; } /** * eeh_report_mmio_enabled - tell drivers that MMIO has been enabled * - * Report an EEH error to each device driver, collect up and - * merge the device driver responses. Cumulative response - * passed back in "userdata". + * Tells each device driver that IO ports, MMIO and config space I/O + * are now enabled. Collects up and merges the device driver responses. + * Cumulative response passed back in "userdata". */ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) @@ -123,17 +124,16 @@ static void eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) enum pci_ers_result rc, *res = userdata; struct pci_driver *driver = dev->driver; - // dev->error_state = pci_channel_mmio_enabled; - if (!driver || !driver->err_handler || !driver->err_handler->mmio_enabled) return; rc = driver->err_handler->mmio_enabled (dev); + + /* A driver that needs a reset trumps all others */ + if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; - if (*res == PCI_ERS_RESULT_DISCONNECT && - rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; } /** @@ -310,8 +310,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) const char *location, *pci_str, *drv_str; frozen_dn = find_device_pe(event->dn); - frozen_bus = pcibios_find_pci_bus(frozen_dn); - if (!frozen_dn) { location = of_get_property(event->dn, "ibm,loc-code", NULL); @@ -321,6 +319,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) location, pci_name(event->dev)); return NULL; } + + frozen_bus = pcibios_find_pci_bus(frozen_dn); location = of_get_property(frozen_dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; @@ -354,13 +354,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) goto excess_failures; - /* Get the current PCI slot state. */ - rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000); - if (rc < 0) { - printk(KERN_WARNING "EEH: Permanent failure\n"); - goto hard_fail; - } - printk(KERN_WARNING "EEH: This PCI device has failed %d times in the last hour:\n", frozen_pdn->eeh_freeze_count); @@ -376,6 +369,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) */ pci_walk_bus(frozen_bus, eeh_report_error, &result); + /* Get the current PCI slot state. This can take a long time, + * sometimes over 3 seconds for certain systems. */ + rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000); + if (rc < 0) { + printk(KERN_WARNING "EEH: Permanent failure\n"); + goto hard_fail; + } + /* Since rtas may enable MMIO when posting the error log, * don't post the error log until after all dev drivers * have been informed.