|
@@ -369,7 +369,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;
|
|
|
}
|
|
@@ -416,10 +418,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
|
|
@@ -429,6 +434,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);
|
|
@@ -462,6 +469,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;
|
|
|
}
|
|
|
|
|
@@ -618,8 +626,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)
|
|
@@ -692,6 +703,7 @@ static void eeh_handle_special_event(void)
|
|
|
if (rc == 2 || rc == 1)
|
|
|
eeh_handle_normal_event(pe);
|
|
|
else {
|
|
|
+ pci_lock_rescan_remove();
|
|
|
list_for_each_entry_safe(hose, tmp,
|
|
|
&hose_list, list_node) {
|
|
|
phb_pe = eeh_phb_pe_get(hose);
|
|
@@ -703,6 +715,7 @@ static void eeh_handle_special_event(void)
|
|
|
eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
|
|
|
pcibios_remove_pci_devices(bus);
|
|
|
}
|
|
|
+ pci_unlock_rescan_remove();
|
|
|
}
|
|
|
}
|
|
|
|