These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / powerpc / kernel / eeh_driver.c
index 24768ff..52c1e27 100644 (file)
@@ -416,7 +416,9 @@ static void *eeh_rmv_device(void *data, void *userdata)
        driver = eeh_pcid_get(dev);
        if (driver) {
                eeh_pcid_put(dev);
-               if (driver->err_handler)
+               if (driver->err_handler &&
+                   driver->err_handler->error_detected &&
+                   driver->err_handler->slot_reset)
                        return NULL;
        }
 
@@ -561,6 +563,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
         */
        eeh_pe_state_mark(pe, EEH_PE_KEEP);
        if (bus) {
+               eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
                pci_lock_rescan_remove();
                pcibios_remove_pci_devices(bus);
                pci_unlock_rescan_remove();
@@ -655,12 +658,20 @@ static void eeh_handle_normal_event(struct eeh_pe *pe)
         * to accomplish the reset.  Each child gets a report of the
         * status ... if any child can't handle the reset, then the entire
         * slot is dlpar removed and added.
+        *
+        * When the PHB is fenced, we have to issue a reset to recover from
+        * the error. Override the result if necessary to have partially
+        * hotplug for this case.
         */
        pr_info("EEH: Notify device drivers to shutdown\n");
        eeh_pe_dev_traverse(pe, eeh_report_error, &result);
+       if ((pe->type & EEH_PE_PHB) &&
+           result != PCI_ERS_RESULT_NONE &&
+           result != PCI_ERS_RESULT_NEED_RESET)
+               result = PCI_ERS_RESULT_NEED_RESET;
 
        /* Get the current PCI slot state. This can take a long time,
-        * sometimes over 3 seconds for certain systems.
+        * sometimes over 300 seconds for certain systems.
         */
        rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000);
        if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) {
@@ -792,6 +803,7 @@ perm_error:
         * the their PCI config any more.
         */
        if (frozen_bus) {
+               eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
                eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
 
                pci_lock_rescan_remove();
@@ -875,6 +887,7 @@ static void eeh_handle_special_event(void)
                                        continue;
 
                                /* Notify all devices to be down */
+                               eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
                                bus = eeh_pe_bus_get(phb_pe);
                                eeh_pe_dev_traverse(pe,
                                        eeh_report_failure, NULL);