On Thu, Feb 09, 2023 at 09:20:10PM +0300, Mikhail wrote: > >Synopsis: wrong ECDT EC_ID handling > >Category: acpi > >Environment: > System : OpenBSD 7.2 > Details : OpenBSD 7.2-current (GENERIC.MP) #1021: Sun Feb 5 > 09:52:50 MST 2023 > > [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP > > Architecture: OpenBSD.amd64 > Machine : amd64 > >Description: > Currently the kernel doesn't check if EC_ID presented in > ECDT is correct, it looks like wrong EC_ID is fairly common > mistake in (at least) Lenovo firmware. As consequences - > CapsLock LED, brightness keys and apm battery status doesn't > work. Similar problem affects at least one more person: > https://marc.info/?l=openbsd-tech&m=166654588612920&w=2 [he is cc'ed] > > I asked for BIOS update from semi-official support forum > forums.lenovo.com and from official [email protected] - in first case > there no meaningful answer for about 4 months and second one sent to > partner's service-center for assistance. > > I think it's hopeless to wait for ECDT correction, or ECDT > removal from the vendor, so I decided to propose a patch for the > OS. > > >How-To-Repeat: > Test on Lenovo IdeaPad 3 14itl05, BIOS GCCN32WW > >Fix: > I propose to add a check for wrong EC_ID, and if the check fails - do > not attach ECDT, we still will attach EC after that, but with another > procedure, inlined patch makes my CapsLock LED, brightness buttons and > apm battery status work. > > diff /usr/src > commit - b7cf571f83522f53df8a14fa01dcbeff8df0f02a > path + /usr/src > blob - 5ef24d5179de52d5321e578b3b73dd9524e7c1de > file + sys/dev/acpi/acpiec.c > --- sys/dev/acpi/acpiec.c > +++ sys/dev/acpi/acpiec.c > @@ -429,6 +429,14 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_att > > /* Check if this is ECDT initialization */ > if (ecdt) { > + /* Get devnode from header */ > + sc->sc_devnode = aml_searchname(sc->sc_acpi->sc_root, > + ecdt->ec_id); > + if (sc->sc_devnode == NULL) { > + printf("acpiec wrong ECDT EC_ID, broken BIOS\n"); > + return (1); > + } > + > /* Get GPE, Data and Control segments */ > sc->sc_gpe = ecdt->gpe_bit; > > @@ -444,10 +452,6 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_att > sc->sc_data_bt = sc->sc_acpi->sc_memt; > sc->sc_ec_data = ecdt->ec_data.address; > > - /* Get devnode from header */ > - sc->sc_devnode = aml_searchname(sc->sc_acpi->sc_root, > - ecdt->ec_id); > - > goto ecdtdone; > }
ping
