[Bug 297326] acpi_ec: duplicate attach when the DSDT EC device has no _UID

[email protected]
Newsgroups gmane.os.freebsd.bugs
Message-ID <[email protected]/bugzilla/>
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=297326

            Bug ID: 297326
           Summary: acpi_ec: duplicate attach when the DSDT EC device has
                    no _UID
           Product: Base System
           Version: 15.1-RELEASE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 273519
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=273519&action=edit
asl ecdt and ec device

I am a FreeBSD user, not a kernel developer. The observations are from my
machine and accurate; the code analysis was done with AI assistance and I
cannot
verify it myself. I am not able to run follow-up experiments beyond simple
commands.

## Summary

On firmware that provides both an ECDT and a `PNP0C09` device in the DSDT,
FreeBSD attaches the EC twice. The second attach fails on the already claimed
I/O ports, and its error path removes the GPE and address space handlers that
the *working* instance installed. Consequences: WMI cannot find the EC, GPE is
disabled, `_PTS` fails and the machine does not power off.

## Observed

FreeBSD 15.1-RELEASE-p2 amd64, Schenker KEY 18 Pro E25 (Clevo X585WNX),
BIOS 1.07.11RTR.

```
acpi_ec1: <Embedded Controller: GPE 0x46, ECDT> port 0x62,0x66 on acpi0
acpi_ec0: <Embedded Controller: GPE 0x46> port 0x62,0x66 on acpi0
acpi_ec0: can't allocate data port
device_attach: acpi_ec0 attach returned 6

acpi_wmi0..4: cannot find EC device
ACPI Error: No handler or method for GPE 46, disabling event (evgpe-1061)

[on shutdown]
ACPI Error: No handler for Region [EC81] [EmbeddedControl] (evregion-292)
acpi0: AcpiEnterSleepStatePrep failed - AE_NOT_EXIST
-> "The operating system has halted", machine stays powered on
```

ECDT: `EC_ID=\_SB.PC00.LPCB.EC`, `UID=0x1`, `GPE_BIT=0x46`.
DSDT: `Device (EC)` under `Scope (_SB.PC00.LPCB)`, `_HID = PNP0C09`, **no
`_UID`**. Exactly one EC device exists in the namespace.

Reading still works (`hw.acpi.battery.life` is correct via `_BST`), only events
and device-tree lookups break — which makes this easy to miss.

## Analysis

`sys/dev/acpica/acpi_ec.c`, `acpi_ec_probe()`:

```c
status = acpi_GetInteger(h, "_UID", &params->uid);
if (ACPI_FAILURE(status))
        params->uid = 0;
...
peer = devclass_get_device(device_get_devclass(dev), params->uid);
if (peer != NULL && device_is_alive(peer)) {
        device_disable(dev); goto out;
}
```

The ECDT child is created as unit 1 (`ecdt->Uid`). The DSDT child finds no
`_UID`, falls back to 0, looks for a peer at unit 0, misses the live unit 1 and
proceeds. The damage happens in the error path of `acpi_ec_attach()`, which
removes the handlers for `sc->ec_handle` — the same namespace node the working
instance registered on.

Linux matches the duplicate on the namespace location of the `PNP0C09` device
rather than on `_UID`, and takes only the GPE from the ECDT.

## Workaround (verified)

```
hint.acpi_ec.0.disabled="1"      # loader.conf
```

Prevents the DSDT device from being probed, so the ECDT instance survives.
Result: one `acpi_ec`, zero ACPI errors, all WMI devices bound, GPE active,
`shutdown -p now` powers the machine off, `Unsafe shutdowns` stays constant.

Disabling the ECDT instance instead (`hint.acpi_ec.1.disabled="1"`) also
removes
the duplicate and restores power-off, but the EC is then only available after
the namespace walk and early methods (`_OSC`, `U4EC`, `DOCM`, `TBTD`) fail with
`AE_NOT_EXIST`.

`debug.acpi.avoid` with the exact path (`_SB.PC00.LPCB.EC__`, from
`dev.acpi_ec.1.%location`) did not prevent the second attach.

Overriding the DSDT to add a `_UID` was also attempted and produced a
non-functional table, but that experiment ran while the machine had unrelated
storage corruption (see the geli/TRIM PR), so the input files and the toolchain
may have been affected — it should not be taken as evidence that the approach
does not work.

## Suggested fix

Match the duplicate on the ACPI handle or on the I/O port addresses instead of
`_UID`. Alternatively, make the error path in `acpi_ec_attach()` remove only
handlers it installed itself.

-- 
You are receiving this mail because:
You are the assignee for the bug.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.