]> Pileus Git - ~andy/linux/blobdiff - arch/powerpc/kernel/eeh_driver.c
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[~andy/linux] / arch / powerpc / kernel / eeh_driver.c
index baa3b06e6dab045592ecb33567a74643804148c0..7bb30dca4e192f55ca689319eefdc2a50646ff3a 100644 (file)
@@ -373,7 +373,9 @@ static void *eeh_rmv_device(void *data, void *userdata)
        edev->mode |= EEH_DEV_DISCONNECTED;
        (*removed)++;
 
+       pci_lock_rescan_remove();
        pci_stop_and_remove_bus_device(dev);
+       pci_unlock_rescan_remove();
 
        return NULL;
 }
@@ -420,10 +422,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
         * into pcibios_add_pci_devices().
         */
        eeh_pe_state_mark(pe, EEH_PE_KEEP);
-       if (bus)
+       if (bus) {
+               pci_lock_rescan_remove();
                pcibios_remove_pci_devices(bus);
-       else if (frozen_bus)
+               pci_unlock_rescan_remove();
+       } else if (frozen_bus) {
                eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
+       }
 
        /* Reset the pci controller. (Asserts RST#; resets config space).
         * Reconfigure bridges and devices. Don't try to bring the system
@@ -433,6 +438,8 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
        if (rc)
                return rc;
 
+       pci_lock_rescan_remove();
+
        /* Restore PE */
        eeh_ops->configure_bridge(pe);
        eeh_pe_restore_bars(pe);
@@ -466,6 +473,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
        pe->tstamp = tstamp;
        pe->freeze_count = cnt;
 
+       pci_unlock_rescan_remove();
        return 0;
 }
 
@@ -622,8 +630,11 @@ perm_error:
        eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
 
        /* Shut down the device drivers for good. */
-       if (frozen_bus)
+       if (frozen_bus) {
+               pci_lock_rescan_remove();
                pcibios_remove_pci_devices(frozen_bus);
+               pci_unlock_rescan_remove();
+       }
 }
 
 static void eeh_handle_special_event(void)
@@ -693,6 +704,7 @@ static void eeh_handle_special_event(void)
                    rc == EEH_NEXT_ERR_FENCED_PHB) {
                        eeh_handle_normal_event(pe);
                } else {
+                       pci_lock_rescan_remove();
                        list_for_each_entry(hose, &hose_list, list_node) {
                                phb_pe = eeh_phb_pe_get(hose);
                                if (!phb_pe ||
@@ -705,6 +717,7 @@ static void eeh_handle_special_event(void)
                                        eeh_report_failure, NULL);
                                pcibios_remove_pci_devices(bus);
                        }
+                       pci_unlock_rescan_remove();
                }
 
                /*