diff options
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 1971d2943de4..9d6e535e74a1 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -528,6 +528,16 @@ static void check_hotplug_bridge(struct acpiphp_slot *slot, struct pci_dev *dev) | |||
528 | } | 528 | } |
529 | } | 529 | } |
530 | 530 | ||
531 | static int acpiphp_rescan_slot(struct acpiphp_slot *slot) | ||
532 | { | ||
533 | struct acpiphp_func *func; | ||
534 | |||
535 | list_for_each_entry(func, &slot->funcs, sibling) | ||
536 | acpiphp_bus_add(func_to_handle(func)); | ||
537 | |||
538 | return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0)); | ||
539 | } | ||
540 | |||
531 | /** | 541 | /** |
532 | * enable_slot - enable, configure a slot | 542 | * enable_slot - enable, configure a slot |
533 | * @slot: slot to be enabled | 543 | * @slot: slot to be enabled |
@@ -544,10 +554,7 @@ static void __ref enable_slot(struct acpiphp_slot *slot) | |||
544 | LIST_HEAD(add_list); | 554 | LIST_HEAD(add_list); |
545 | int nr_found; | 555 | int nr_found; |
546 | 556 | ||
547 | list_for_each_entry(func, &slot->funcs, sibling) | 557 | nr_found = acpiphp_rescan_slot(slot); |
548 | acpiphp_bus_add(func_to_handle(func)); | ||
549 | |||
550 | nr_found = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
551 | max = acpiphp_max_busnr(bus); | 558 | max = acpiphp_max_busnr(bus); |
552 | for (pass = 0; pass < 2; pass++) { | 559 | for (pass = 0; pass < 2; pass++) { |
553 | list_for_each_entry(dev, &bus->devices, bus_list) { | 560 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -840,11 +847,22 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) | |||
840 | case ACPI_NOTIFY_DEVICE_CHECK: | 847 | case ACPI_NOTIFY_DEVICE_CHECK: |
841 | /* device check */ | 848 | /* device check */ |
842 | dbg("%s: Device check notify on %s\n", __func__, objname); | 849 | dbg("%s: Device check notify on %s\n", __func__, objname); |
843 | if (bridge) | 850 | if (bridge) { |
844 | acpiphp_check_bridge(bridge); | 851 | acpiphp_check_bridge(bridge); |
845 | else | 852 | } else { |
846 | acpiphp_check_bridge(func->parent); | 853 | struct acpiphp_slot *slot = func->slot; |
854 | int ret; | ||
847 | 855 | ||
856 | /* | ||
857 | * Check if anything has changed in the slot and rescan | ||
858 | * from the parent if that's the case. | ||
859 | */ | ||
860 | mutex_lock(&slot->crit_sect); | ||
861 | ret = acpiphp_rescan_slot(slot); | ||
862 | mutex_unlock(&slot->crit_sect); | ||
863 | if (ret) | ||
864 | acpiphp_check_bridge(func->parent); | ||
865 | } | ||
848 | break; | 866 | break; |
849 | 867 | ||
850 | case ACPI_NOTIFY_EJECT_REQUEST: | 868 | case ACPI_NOTIFY_EJECT_REQUEST: |