git: 3c59c4453f0e - stable/14 - ACPI: Treat all 20-element _BIX entires as revision 0

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 07 Dec 2024 00:17:20 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=3c59c4453f0efbb606da9bf6a879f53ae980a645

commit 3c59c4453f0efbb606da9bf6a879f53ae980a645
Author:     Bartosz Fabianowski <freebsd@chillt.de>
AuthorDate: 2024-10-02 18:21:28 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-12-07 00:11:27 +0000

    ACPI: Treat all 20-element _BIX entires as revision 0
    
    Some Fujitsu Lifebooks return an invalid _BIX object. The first element
    of _BIX is a revision number, which indicates what elements will follow:
    * ACPI 4.0 defined _BIX revision 0 with 20 elements.
    * ACPI 6.0 introduced _BIX revision 1 with 21 elements.
    The problem is that the offending Lifebooks have the a non-zero _BIX
    revision, but provide 20 fields only.
    
    The ACPICA parser chokes on this [1], but that seems to be
    inconsequential. More importantly, our own battery info handling code
    also verifies that for revision > 0, there are at least 21 fields - and
    refuses to process the invalid _BIX. One workaround would be to
    introduce special case / quirk handling for Fujitsu Lifebooks. A better
    one is to relax the requirements check: If there are only 20 elements,
    treat the _BIX as revision 0, no matter what revision number was
    provided by the device.
    
    Linux doesn't run into this problem by the way because it only supports
    the 20 fields defined in the ACPI 4.0 spec [3]. It never looks at the
    revision number or the 21st field added in ACPI 6.0.
    
    [1] https://cgit.freebsd.org/src/tree/sys/contrib/dev/acpica/components/namespace/nsprepkg.c#n815
    [2] https://cgit.freebsd.org/src/tree/sys/dev/acpica/acpi_cmbat.c#n371
    [3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/acpi/battery.c#n418
    
    PR: 252030
    Reviewed by: imp
    MFC After: 2 weeks
    
    (cherry picked from commit cd8c3af747cc300c8257c315c7576644e2bb86ff)
---
 sys/dev/acpica/acpi_cmbat.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys/dev/acpica/acpi_cmbat.c b/sys/dev/acpica/acpi_cmbat.c
index 8c08868456d7..e85967aed9c9 100644
--- a/sys/dev/acpica/acpi_cmbat.c
+++ b/sys/dev/acpica/acpi_cmbat.c
@@ -398,8 +398,17 @@ acpi_cmbat_get_bix(void *arg)
 	        sc->bix.rev != ACPI_BIX_REV_1)
 		ACPI_BIX_REV_MISMATCH_ERR(sc->bix.rev, ACPI_BIX_REV_1);
 	} else if (ACPI_PKG_VALID_EQ(res, 20)) {/* ACPI 4.0 _BIX */
-	    if (sc->bix.rev != ACPI_BIX_REV_0)
-		ACPI_BIX_REV_MISMATCH_ERR(sc->bix.rev, ACPI_BIX_REV_0);
+	    /*
+	     * Some models claim to be rev.1, but have a _BIX with only 20
+	     * members. Be lenient and treat this as a valid rev.0 _BIX.
+	     */
+	    if (sc->bix.rev != ACPI_BIX_REV_0) {
+		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
+		    "_BIX containing too few objects for revision %u. "
+		    "Treating as revision %u instead.\n",
+		    sc->bix.rev, ACPI_BIX_REV_0);
+		sc->bix.rev = ACPI_BIX_REV_0;
+            }
 	} else if (ACPI_PKG_VALID(res, 22)) {
 	    /* _BIX with 22 or more members. */
 	    if (ACPI_BIX_REV_MIN_CHECK(sc->bix.rev, ACPI_BIX_REV_1 + 1)) {