Переглянути джерело

Merge branches 'acpi-dock', 'acpi-scan' and 'acpi-pci-hotplug'

* acpi-dock:
  ACPI / dock: Use acpi_device_enumerated() to check if dock is present

* acpi-scan:
  ACPI / container: Fix error code path in container_device_attach()

* acpi-pci-hotplug:
  ACPI / hotplug / PCI: Relax the checking of _STA return values
Rafael J. Wysocki 11 роки тому
батько
коміт
d990ce0d5b
2 змінених файлів з 16 додано та 4 видалено
  1. 3 2
      drivers/acpi/container.c
  2. 13 2
      drivers/pci/hotplug/acpiphp_glue.c

+ 3 - 2
drivers/acpi/container.c

@@ -79,9 +79,10 @@ static int container_device_attach(struct acpi_device *adev,
 	ACPI_COMPANION_SET(dev, adev);
 	dev->release = acpi_container_release;
 	ret = device_register(dev);
-	if (ret)
+	if (ret) {
+		put_device(dev);
 		return ret;
-
+	}
 	adev->driver_data = dev;
 	return 1;
 }

+ 13 - 2
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_status_valid(unsigned int sta)
+{
+	/*
+	 * ACPI spec says that _STA may return bit 0 clear with bit 3 set
+	 * if the device is valid but does not require a device driver to be
+	 * loaded (Section 6.3.7 of ACPI 5.0A).
+	 */
+	unsigned int 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_status_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_status_valid(get_slot_status(slot))) {
 			/* remove stale devices if any */
 			list_for_each_entry_safe_reverse(dev, tmp,
 							 &bus->devices, bus_list)