diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2013-07-13 17:27:26 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-07-22 22:00:26 -0400 |
commit | b91182a67c53db227e34921838dd683090ecfabc (patch) | |
tree | 33231ed2f87c8ad870a97ee3f5c40f38b9420480 | |
parent | 55502ddb2d83ada0661733361ec14b9cbef157a5 (diff) |
ACPI / hotplug / PCI: Allow slots without new devices to be rescanned
Currently, enable_device() checks the return value of pci_scan_slot()
and returns immediately if that's 0 (meaning that no new functions
have been found in the slot). However, if one of the functions in
the slot is a bridge, some new devices may appear below it even if
the bridge itself is present continuously, so it generally is
necessary to do the rescan anyway just in case. [In particular,
that's necessary with the Thunderbolt daisy chaining in which case
new devices may be connected to the existing ones down the chain.]
The correctness of this change relies on the ability of
pcibios_resource_survey_bus() to detect if it has already been called
for the given bus and to skip it if so. Failure to do that will lead
to resource allocation conflicts.
[rjw: Changelog]
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 11 |
1 files changed, 2 insertions, 9 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index c7a668e1fc12..21a6269501e1 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -542,18 +542,13 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
542 | struct pci_dev *dev; | 542 | struct pci_dev *dev; |
543 | struct pci_bus *bus = slot->bus; | 543 | struct pci_bus *bus = slot->bus; |
544 | struct acpiphp_func *func; | 544 | struct acpiphp_func *func; |
545 | int num, max, pass; | 545 | int max, pass; |
546 | LIST_HEAD(add_list); | 546 | LIST_HEAD(add_list); |
547 | 547 | ||
548 | list_for_each_entry(func, &slot->funcs, sibling) | 548 | list_for_each_entry(func, &slot->funcs, sibling) |
549 | acpiphp_bus_add(func_to_handle(func)); | 549 | acpiphp_bus_add(func_to_handle(func)); |
550 | 550 | ||
551 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | 551 | pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
552 | if (num == 0) { | ||
553 | /* Maybe only part of funcs are added. */ | ||
554 | dbg("No new device found\n"); | ||
555 | goto err_exit; | ||
556 | } | ||
557 | 552 | ||
558 | max = acpiphp_max_busnr(bus); | 553 | max = acpiphp_max_busnr(bus); |
559 | for (pass = 0; pass < 2; pass++) { | 554 | for (pass = 0; pass < 2; pass++) { |
@@ -599,8 +594,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
599 | } | 594 | } |
600 | } | 595 | } |
601 | 596 | ||
602 | |||
603 | err_exit: | ||
604 | return 0; | 597 | return 0; |
605 | } | 598 | } |
606 | 599 | ||