提交 d41be346 编写于 作者: R Rafael J. Wysocki 提交者: Bjorn Helgaas

ACPI / hotplug / PCI: Check ignore_hotplug for all downstream devices

If the ignore_hotplug flag is set for a PCI device without an ACPI
companion and a bus check notification is received for an ancestor bridge
that is not the device's parent, ACPIPHP will ignore that flag.

Namely, in that case acpiphp_check_bridge() is called for the target bridge
and if all of the devices immediately below the bridge are still present,
trim_stale_devices() will be called for each of them.  That function
recursively walks the hierarchy downwards and removes device objects
corresponding to devices that don't appear to be present any more.
Unfortunately, it only checks ignore_hotplug for devices having ACPI
companions, so it will remove the others (if they don't respond) regardless
of the ignore_hotplug value.

Fix the problem by making trim_stale_devices() take ignore_hotplug into
consideration regardless of whether or not an ACPI companion is present for
the device it has been called for.

[bhelgaas: This may fix bug 61891, depending on whether the bridge above a
device is removed along with the device]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=61891Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
上级 2af31f41
......@@ -632,15 +632,14 @@ static void trim_stale_devices(struct pci_dev *dev)
{
struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
struct pci_bus *bus = dev->subordinate;
bool alive = false;
bool alive = dev->ignore_hotplug;
if (adev) {
acpi_status status;
unsigned long long sta;
status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta);
alive = (ACPI_SUCCESS(status) && device_status_valid(sta))
|| dev->ignore_hotplug;
alive = alive || (ACPI_SUCCESS(status) && device_status_valid(sta));
}
if (!alive)
alive = pci_device_is_present(dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册