On Tuesday, February 11, 2014 12:42:37 PM Mika Westerberg wrote: > On Mon, Feb 10, 2014 at 11:39:29PM +0100, Rafael J. Wysocki wrote: > > > _STA() returns 0x0A instead of 0x0F. Could there be something missing in > > > the ACPI hotplug code that overlooks this and removes the device on > > > resume? > > > > That is possible. Actually even quite likely, but let's wait for the > > response > > from Peter. > > Here's a hack that should take the 0xa return value into consideration. It > turned out that this case is even mentioned in the ACPI spec.
Looks reasonable. Peter, please check if this one makes a difference for you. > diff --git a/drivers/pci/hotplug/acpiphp_glue.c > b/drivers/pci/hotplug/acpiphp_glue.c > index e2a783fdb98f..014381b42d86 100644 > --- a/drivers/pci/hotplug/acpiphp_glue.c > +++ b/drivers/pci/hotplug/acpiphp_glue.c > @@ -730,6 +730,17 @@ static unsigned int get_slot_status(struct acpiphp_slot > *slot) > return (unsigned int)sta; > } > > +static inline bool device_sta_valid(unsigned long long sta) > +{ > + /* > + * ACPI spec says that _STA may return bit 0 clear with bit 8 set > + * if the device is valid but does not require device driver to be > + * loaded (chapter 6.3.7). > + */ > + unsigned mask = ACPI_STA_DEVICE_ENABLED | ACPI_STA_DEVICE_FUNCTIONING; > + return (sta & mask) == mask; > +} > + > /** > * trim_stale_devices - remove PCI devices that are not responding. > * @dev: PCI device to start walking the hierarchy from. > @@ -745,7 +756,7 @@ static void trim_stale_devices(struct pci_dev *dev) > unsigned long long sta; > > status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); > - alive = (ACPI_SUCCESS(status) && sta == ACPI_STA_ALL) > + alive = (ACPI_SUCCESS(status) && device_sta_valid(sta)) > || acpiphp_no_hotplug(handle); > } > if (!alive) { > @@ -792,7 +803,7 @@ static void acpiphp_check_bridge(struct acpiphp_bridge > *bridge) > mutex_lock(&slot->crit_sect); > if (slot_no_hotplug(slot)) { > ; /* do nothing */ > - } else if (get_slot_status(slot) == ACPI_STA_ALL) { > + } else if (device_sta_valid(get_slot_status(slot))) { > /* remove stale devices if any */ > list_for_each_entry_safe_reverse(dev, tmp, > &bus->devices, > bus_list) > > -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/