Skip to content

Commit f188b99

Browse files
westeribjorn-helgaas
authored andcommitted
ACPI / hotplug / PCI: Don't scan for non-hotplug bridges if slot is not bridge
HP 6730b laptop has an ethernet NIC connected to one of the PCIe root ports. The root ports themselves are native PCIe hotplug capable. Now, during boot after PCI devices are scanned the BIOS triggers ACPI bus check directly to the NIC: ACPI: \_SB_.PCI0.RP06.NIC_: Bus check in hotplug_event() It is not clear why it is sending bus check but regardless the ACPI hotplug notify handler calls enable_slot() directly (instead of going through acpiphp_check_bridge() as there is no bridge), which ends up handling special case for non-hotplug bridges with native PCIe hotplug. This results a crash of some kind but the reporter only sees black screen so it is hard to figure out the exact spot and what actually happens. Based on a few fix proposals it was tracked to crash somewhere inside pci_assign_unassigned_bridge_resources(). In any case we should not really be in that special branch at all because the ACPI notify happened to a slot that is not a PCI bridge (it is just a regular PCI device). Fix this so that we only go to that special branch if we are calling enable_slot() for a bridge (e.g., the ACPI notification was for the bridge). Link: https://bugzilla.kernel.org/show_bug.cgi?id=201127 Fixes: 84c8b58 ("ACPI / hotplug / PCI: Don't scan bridges managed by native hotplug") Reported-by: Peter Anemone <peter.anemone@gmail.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> CC: stable@vger.kernel.org # v4.18+
1 parent 9024143 commit f188b99

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

drivers/pci/hotplug/acpiphp_glue.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -457,17 +457,18 @@ static void acpiphp_native_scan_bridge(struct pci_dev *bridge)
457457
/**
458458
* enable_slot - enable, configure a slot
459459
* @slot: slot to be enabled
460+
* @bridge: true if enable is for the whole bridge (not a single slot)
460461
*
461462
* This function should be called per *physical slot*,
462463
* not per each slot object in ACPI namespace.
463464
*/
464-
static void enable_slot(struct acpiphp_slot *slot)
465+
static void enable_slot(struct acpiphp_slot *slot, bool bridge)
465466
{
466467
struct pci_dev *dev;
467468
struct pci_bus *bus = slot->bus;
468469
struct acpiphp_func *func;
469470

470-
if (bus->self && hotplug_is_native(bus->self)) {
471+
if (bridge && bus->self && hotplug_is_native(bus->self)) {
471472
/*
472473
* If native hotplug is used, it will take care of hotplug
473474
* slot management and resource allocation for hotplug
@@ -701,7 +702,7 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
701702
trim_stale_devices(dev);
702703

703704
/* configure all functions */
704-
enable_slot(slot);
705+
enable_slot(slot, true);
705706
} else {
706707
disable_slot(slot);
707708
}
@@ -785,7 +786,7 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
785786
if (bridge)
786787
acpiphp_check_bridge(bridge);
787788
else if (!(slot->flags & SLOT_IS_GOING_AWAY))
788-
enable_slot(slot);
789+
enable_slot(slot, false);
789790

790791
break;
791792

@@ -973,7 +974,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
973974

974975
/* configure all functions */
975976
if (!(slot->flags & SLOT_ENABLED))
976-
enable_slot(slot);
977+
enable_slot(slot, false);
977978

978979
pci_unlock_rescan_remove();
979980
return 0;

0 commit comments

Comments
 (0)