[PATCH] acpi: update checks of _BIX return package

Alex Hung alex.hung at canonical.com
Wed Nov 8 08:40:17 UTC 2017


ACPI 6.0 introduced a new change "Swapping Capability" to _BIX method in
mantis 1284.

Signed-off-by: Alex Hung <alex.hung at canonical.com>
---
 src/acpi/devices/battery/battery.c | 82 ++++++++++++++++++++++++++++++++------
 src/acpi/method/method.c           | 66 ++++++++++++++++++++++++++++--
 2 files changed, 132 insertions(+), 16 deletions(-)

diff --git a/src/acpi/devices/battery/battery.c b/src/acpi/devices/battery/battery.c
index f692232..dcdb762 100644
--- a/src/acpi/devices/battery/battery.c
+++ b/src/acpi/devices/battery/battery.c
@@ -223,7 +223,9 @@ static void method_test_BIX_return(
 	void *private)
 {
 	bool failed = false;
+	uint64_t revision = 0;
 
+	/* Revision 0 in ACPI 5.x */
 	static const fwts_package_element elements[] = {
 		{ ACPI_TYPE_INTEGER,	"Revision" },
 		{ ACPI_TYPE_INTEGER,	"Power Unit" },
@@ -247,21 +249,65 @@ static void method_test_BIX_return(
 		{ ACPI_TYPE_STRING,	"OEM Information" }
 	};
 
+	/* Revision 1 in ACPI 6.x introduces swapping capability */
+	static const fwts_package_element elements_v1[] = {
+		{ ACPI_TYPE_INTEGER,	"Revision" },
+		{ ACPI_TYPE_INTEGER,	"Power Unit" },
+		{ ACPI_TYPE_INTEGER,	"Design Capacity" },
+		{ ACPI_TYPE_INTEGER,	"Last Full Charge Capacity" },
+		{ ACPI_TYPE_INTEGER,	"Battery Technology" },
+		{ ACPI_TYPE_INTEGER,	"Design Voltage" },
+		{ ACPI_TYPE_INTEGER,	"Design Capacity of Warning" },
+		{ ACPI_TYPE_INTEGER,	"Design Capactty of Low" },
+		{ ACPI_TYPE_INTEGER,	"Cycle Count" },
+		{ ACPI_TYPE_INTEGER,	"Measurement Accuracy" },
+		{ ACPI_TYPE_INTEGER,	"Max Sampling Time" },
+		{ ACPI_TYPE_INTEGER,	"Min Sampling Time" },
+		{ ACPI_TYPE_INTEGER,	"Max Averaging Interval" },
+		{ ACPI_TYPE_INTEGER,	"Min Averaging Interval" },
+		{ ACPI_TYPE_INTEGER,	"Battery Capacity Granularity 1" },
+		{ ACPI_TYPE_INTEGER,	"Battery Capacity Granularity 2" },
+		{ ACPI_TYPE_STRING,	"Model Number" },
+		{ ACPI_TYPE_STRING,	"Serial Number" },
+		{ ACPI_TYPE_STRING,	"Battery Type" },
+		{ ACPI_TYPE_STRING,	"OEM Information" },
+		{ ACPI_TYPE_INTEGER,	"Battery Swapping Capability" }
+	};
+
 	FWTS_UNUSED(private);
 
 	if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_PACKAGE) != FWTS_OK)
 		return;
 
-	if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 20) != FWTS_OK)
-		return;
+	if (obj->Package.Count > 1 && obj->Package.Elements[0].Type == ACPI_TYPE_INTEGER)
+		revision = obj->Package.Elements[0].Integer.Value;
 
-	if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements, 20) != FWTS_OK)
-		return;
+	if (revision == 0) {
+		if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 20) != FWTS_OK)
+			return;
+
+		if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements, 20) != FWTS_OK)
+			return;
+	} else if (revision == 1) {
+		if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 21) != FWTS_OK)
+			return;
+
+		if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements_v1, 21) != FWTS_OK)
+			return;
+	} else {
+		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+			"Method_BIXRevision",
+			"%s: Expected %s (Element 0) to be "
+			"0 or 1, got 0x%8.8" PRIx64 ".",
+			name, elements_v1[0].name,
+			(uint64_t)obj->Package.Elements[0].Integer.Value);
+		failed = true;
+	}
 
 	/* Sanity check each field */
 	/* Power Unit */
 	if (obj->Package.Elements[1].Integer.Value > 0x00000002) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_MEDIUM,
 			"Method_BIXPowerUnit",
 			"%s: Expected %s (Element 1) to be "
 			"0 (mWh) or 1 (mAh), got 0x%8.8" PRIx64 ".",
@@ -273,10 +319,10 @@ static void method_test_BIX_return(
 	/*
 	 * Since this information may be evaluated by communicating with
 	 * the EC we skip these checks as we can't do this from userspace
-	 */
+ 	 */
 	/* Design Capacity */
 	if (obj->Package.Elements[2].Integer.Value > 0x7fffffff) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_LOW,
 			"Method_BIXDesignCapacity",
 			"%s: %s (Element 2) is "
 			"unknown: 0x%8.8" PRIx64 ".",
@@ -286,7 +332,7 @@ static void method_test_BIX_return(
 	}
 	/* Last Full Charge Capacity */
 	if (obj->Package.Elements[3].Integer.Value > 0x7fffffff) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_LOW,
 			"Method_BIXFullChargeCapacity",
 			"%s: %s (Element 3) "
 			"is unknown: 0x%8.8" PRIx64 ".",
@@ -310,10 +356,10 @@ static void method_test_BIX_return(
 	/*
 	 * Since this information may be evaluated by communicating with
 	 * the EC we skip these checks as we can't do this from userspace
-	 */
+ 	 */
 	/* Design Voltage */
 	if (obj->Package.Elements[5].Integer.Value > 0x7fffffff) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_LOW,
 			"Method_BIXDesignVoltage",
 			"%s: %s (Element 5) is unknown: "
 			"0x%8.8" PRIx64 ".",
@@ -323,7 +369,7 @@ static void method_test_BIX_return(
 	}
 	/* Design capacity warning */
 	if (obj->Package.Elements[6].Integer.Value > 0x7fffffff) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_LOW,
 			"Method_BIXDesignCapacityE6",
 			"%s: %s (Element 6) "
 			"is unknown: 0x%8.8" PRIx64 ".",
@@ -333,7 +379,7 @@ static void method_test_BIX_return(
 	}
 	/* Design capacity low */
 	if (obj->Package.Elements[7].Integer.Value > 0x7fffffff) {
-		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+		fwts_failed(fw, LOG_LEVEL_LOW,
 			"Method_BIXDesignCapacityE7",
 			"%s: %s (Element 7) "
 			"is unknown: 0x%8.8" PRIx64 ".",
@@ -355,6 +401,18 @@ static void method_test_BIX_return(
 	}
 
 #endif
+
+	/* Swapping Capability */
+	if (revision == 1 && obj->Package.Elements[20].Integer.Value > 2) {
+		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+			"Method_BIXSwappingCapability",
+			"%s: %s (Element 20) "
+			"is unknown: 0x%8.8" PRIx64 ".",
+			name, elements_v1[20].name,
+			obj->Package.Elements[20].Integer.Value);
+		failed = true;
+	}
+
 	if (failed)
 		fwts_advice(fw,
 			"Battery %s package contains errors. It is "
diff --git a/src/acpi/method/method.c b/src/acpi/method/method.c
index 509424f..d0958f3 100644
--- a/src/acpi/method/method.c
+++ b/src/acpi/method/method.c
@@ -4047,7 +4047,9 @@ static void method_test_BIX_return(
 	void *private)
 {
 	bool failed = false;
+	uint64_t revision = 0;
 
+	/* Revision 0 in ACPI 5.x */
 	static const fwts_package_element elements[] = {
 		{ ACPI_TYPE_INTEGER,	"Revision" },
 		{ ACPI_TYPE_INTEGER,	"Power Unit" },
@@ -4071,16 +4073,60 @@ static void method_test_BIX_return(
 		{ ACPI_TYPE_STRING,	"OEM Information" }
 	};
 
+	/* Revision 1 in ACPI 6.x introduces swapping capability */
+	static const fwts_package_element elements_v1[] = {
+		{ ACPI_TYPE_INTEGER,	"Revision" },
+		{ ACPI_TYPE_INTEGER,	"Power Unit" },
+		{ ACPI_TYPE_INTEGER,	"Design Capacity" },
+		{ ACPI_TYPE_INTEGER,	"Last Full Charge Capacity" },
+		{ ACPI_TYPE_INTEGER,	"Battery Technology" },
+		{ ACPI_TYPE_INTEGER,	"Design Voltage" },
+		{ ACPI_TYPE_INTEGER,	"Design Capacity of Warning" },
+		{ ACPI_TYPE_INTEGER,	"Design Capactty of Low" },
+		{ ACPI_TYPE_INTEGER,	"Cycle Count" },
+		{ ACPI_TYPE_INTEGER,	"Measurement Accuracy" },
+		{ ACPI_TYPE_INTEGER,	"Max Sampling Time" },
+		{ ACPI_TYPE_INTEGER,	"Min Sampling Time" },
+		{ ACPI_TYPE_INTEGER,	"Max Averaging Interval" },
+		{ ACPI_TYPE_INTEGER,	"Min Averaging Interval" },
+		{ ACPI_TYPE_INTEGER,	"Battery Capacity Granularity 1" },
+		{ ACPI_TYPE_INTEGER,	"Battery Capacity Granularity 2" },
+		{ ACPI_TYPE_STRING,	"Model Number" },
+		{ ACPI_TYPE_STRING,	"Serial Number" },
+		{ ACPI_TYPE_STRING,	"Battery Type" },
+		{ ACPI_TYPE_STRING,	"OEM Information" },
+		{ ACPI_TYPE_INTEGER,	"Battery Swapping Capability" }
+	};
+
 	FWTS_UNUSED(private);
 
 	if (fwts_method_check_type(fw, name, buf, ACPI_TYPE_PACKAGE) != FWTS_OK)
 		return;
 
-	if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 20) != FWTS_OK)
-		return;
+	if (obj->Package.Count > 1 && obj->Package.Elements[0].Type == ACPI_TYPE_INTEGER)
+		revision = obj->Package.Elements[0].Integer.Value;
 
-	if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements, 20) != FWTS_OK)
-		return;
+	if (revision == 0) {
+		if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 20) != FWTS_OK)
+			return;
+
+		if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements, 20) != FWTS_OK)
+			return;
+	} else if (revision == 1) {
+		if (fwts_method_package_count_equal(fw, name, "_BIX", obj, 21) != FWTS_OK)
+			return;
+
+		if (fwts_method_package_elements_type(fw, name, "_BIX", obj, elements_v1, 21) != FWTS_OK)
+			return;
+	} else {
+		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+			"Method_BIXRevision",
+			"%s: Expected %s (Element 0) to be "
+			"0 or 1, got 0x%8.8" PRIx64 ".",
+			name, elements_v1[0].name,
+			(uint64_t)obj->Package.Elements[0].Integer.Value);
+		failed = true;
+	}
 
 	/* Sanity check each field */
 	/* Power Unit */
@@ -4179,6 +4225,18 @@ static void method_test_BIX_return(
 	}
 
 #endif
+
+	/* Swapping Capability */
+	if (revision == 1 && obj->Package.Elements[20].Integer.Value > 2) {
+		fwts_failed(fw, LOG_LEVEL_CRITICAL,
+			"Method_BIXSwappingCapability",
+			"%s: %s (Element 20) "
+			"is unknown: 0x%8.8" PRIx64 ".",
+			name, elements_v1[20].name,
+			obj->Package.Elements[20].Integer.Value);
+		failed = true;
+	}
+
 	if (failed)
 		fwts_advice(fw,
 			"Battery %s package contains errors. It is "
-- 
2.7.4




More information about the fwts-devel mailing list