|
@@ -350,6 +350,7 @@ enum hv_pcibus_state {
|
|
|
hv_pcibus_init = 0,
|
|
|
hv_pcibus_probed,
|
|
|
hv_pcibus_installed,
|
|
|
+ hv_pcibus_removed,
|
|
|
hv_pcibus_maximum
|
|
|
};
|
|
|
|
|
@@ -1504,13 +1505,24 @@ static void pci_devices_present_work(struct work_struct *work)
|
|
|
put_pcichild(hpdev, hv_pcidev_ref_initial);
|
|
|
}
|
|
|
|
|
|
- /* Tell the core to rescan bus because there may have been changes. */
|
|
|
- if (hbus->state == hv_pcibus_installed) {
|
|
|
+ switch(hbus->state) {
|
|
|
+ case hv_pcibus_installed:
|
|
|
+ /*
|
|
|
+ * Tell the core to rescan bus
|
|
|
+ * because there may have been changes.
|
|
|
+ */
|
|
|
pci_lock_rescan_remove();
|
|
|
pci_scan_child_bus(hbus->pci_bus);
|
|
|
pci_unlock_rescan_remove();
|
|
|
- } else {
|
|
|
+ break;
|
|
|
+
|
|
|
+ case hv_pcibus_init:
|
|
|
+ case hv_pcibus_probed:
|
|
|
survey_child_resources(hbus);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
up(&hbus->enum_sem);
|
|
@@ -2185,6 +2197,7 @@ static int hv_pci_probe(struct hv_device *hdev,
|
|
|
hbus = kzalloc(sizeof(*hbus), GFP_KERNEL);
|
|
|
if (!hbus)
|
|
|
return -ENOMEM;
|
|
|
+ hbus->state = hv_pcibus_init;
|
|
|
|
|
|
/*
|
|
|
* The PCI bus "domain" is what is called "segment" in ACPI and
|
|
@@ -2348,6 +2361,7 @@ static int hv_pci_remove(struct hv_device *hdev)
|
|
|
pci_stop_root_bus(hbus->pci_bus);
|
|
|
pci_remove_root_bus(hbus->pci_bus);
|
|
|
pci_unlock_rescan_remove();
|
|
|
+ hbus->state = hv_pcibus_removed;
|
|
|
}
|
|
|
|
|
|
hv_pci_bus_exit(hdev);
|