[Bug 297326] acpi_ec: duplicate attach when the DSDT EC device has no _UID
Date: Fri, 07 Aug 2026 04:53:44 UTC
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: bugs@FreeBSD.org
Reporter: dr.johannes.bruegmann@gmail.com
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", ¶ms->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.