git: 2a535edd3560 - stable/15 - acpi: parse resources of not-present devices that are kept enabled

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Sun, 01 Nov 2026 18:35:46 UTC
The branch stable/15 has been updated by seuros:

URL: https://cgit.FreeBSD.org/src/commit/?id=2a535edd3560aad2e024f7d33049b3fddca26590

commit 2a535edd3560aad2e024f7d33049b3fddca26590
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-07-31 21:25:52 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-11-01 17:01:42 +0000

    acpi: parse resources of not-present devices that are kept enabled
    
    acpi_probe_child() keeps PCI link devices, the RTC,
    and docking stations enabled even when _STA reports them not present,
    but skipped acpi_parse_resources() for them. With an empty resource
    list, resource-based hint matching (BUS_HINT_DEVICE_UNIT) cannot wire
    such a device to its hinted unit, and the hinted ISA device is then
    created as a duplicate.
    
    Modern AMI firmware reports the PNP0B00 RTC as not present while
    handing timekeeping to the ACPI Time-and-Alarm device.
    
    Reviewed by:    adrian, jhb
    Differential Revision:  https://reviews.freebsd.org/D58047
    
    (cherry picked from commit 21bc31ce2e4a7106ec352c9e30fc6d948b881653)
---
 sys/dev/acpica/acpi.c | 59 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 24 deletions(-)

diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index b413404e3903..40a70cd31fba 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -2347,6 +2347,34 @@ acpi_probe_order(ACPI_HANDLE handle, int *order)
 		*order = 4;
 }
 
+/*
+ * Some devices must remain enabled even when _STA (ACPI 6.5, section 6.3.7)
+ * reports them as not present:
+ *
+ * - PCI link devices (_HID PNP0C0F, section 6.1.5), which sometimes report
+ *   "present" but not "functional" (i.e. if disabled).
+ * - The RTC (_HID PNP0B00), which is needed for CMOS register space unless
+ *   the FADT indicates it is not present (checked in the RTC probe routine).
+ * - Docking stations, which have a _DCK method (section 6.5.2), since the
+ *   system may be undocked at boot.
+ */
+static bool
+acpi_always_present(ACPI_HANDLE handle)
+{
+    ACPI_HANDLE h;
+
+    if (acpi_MatchHid(handle, "PNP0C0F"))
+	return (true);
+
+    if (acpi_MatchHid(handle, "PNP0B00"))
+	return (true);
+
+    if (ACPI_SUCCESS(AcpiGetHandle(handle, "_DCK", &h)))
+	return (true);
+
+    return (false);
+}
+
 /*
  * Evaluate a child device and determine whether we might attach a device to
  * it.
@@ -2358,7 +2386,6 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
     struct acpi_device	*ad;
     struct acpi_prw_data prw;
     ACPI_OBJECT_TYPE type;
-    ACPI_HANDLE h;
     device_t bus, child;
     char *handle_str;
     int d, order;
@@ -2422,30 +2449,14 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status)
 	     * leave it disabled (so that we have a device_t attached to
 	     * the handle, but we don't probe it).
 	     *
-	     * XXX PCI link devices sometimes report "present" but not
-	     * "functional" (i.e. if disabled).  Go ahead and probe them
-	     * anyway since we may enable them later.
+	     * Devices that are kept enabled still have their resources
+	     * parsed below so that resource-based hint matching
+	     * (BUS_HINT_DEVICE_UNIT) can wire their unit numbers;
+	     * otherwise a hinted ISA device can duplicate the ACPI
+	     * device.
 	     */
-	    if (type == ACPI_TYPE_DEVICE && !acpi_DeviceIsPresent(child)) {
-		/* Never disable PCI link devices. */
-		if (acpi_MatchHid(handle, "PNP0C0F"))
-		    break;
-
-		/*
-		 * RTC Device should be enabled for CMOS register space
-		 * unless FADT indicate it is not present.
-		 * (checked in RTC probe routine.)
-		 */
-		if (acpi_MatchHid(handle, "PNP0B00"))
-		    break;
-
-		/*
-		 * Docking stations should remain enabled since the system
-		 * may be undocked at boot.
-		 */
-		if (ACPI_SUCCESS(AcpiGetHandle(handle, "_DCK", &h)))
-		    break;
-
+	    if (type == ACPI_TYPE_DEVICE && !acpi_DeviceIsPresent(child) &&
+		!acpi_always_present(handle)) {
 		device_disable(child);
 		break;
 	    }