summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nspredef.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-07-24 05:03:09 +0200
committerLen Brown <len.brown@intel.com>2009-08-29 01:40:38 +0200
commite5f69d6ef7a6b0dbad8d4c00d83009960be02155 (patch)
treefac155941c084b22c566b4931c67ab098a1488ee /drivers/acpi/acpica/nspredef.c
parentACPICA: Move predefined repair code to new file, no functional change (diff)
downloadlinux-e5f69d6ef7a6b0dbad8d4c00d83009960be02155.tar.xz
linux-e5f69d6ef7a6b0dbad8d4c00d83009960be02155.zip
ACPICA: Add repair for predefined methods that return nested packages
Fixes a problem where a predefined method is defined to return a variable-length Package of sub-packages. If the length is one, the BIOS code occasionally creates a simple single package with no sub-packages. This code attempts to fix the problem by wrapping a new package object around the existing package. ACPICA BZ 790. http://acpica.org/bugzilla/show_bug.cgi?id=790 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
-rw-r--r--drivers/acpi/acpica/nspredef.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index e3f08dcb5275..0091504df074 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -566,9 +566,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
case ACPI_PTYPE2_COUNT:
/*
- * These types all return a single package that consists of a
- * variable number of sub-packages.
+ * These types all return a single Package that consists of a
+ * variable number of sub-Packages.
+ *
+ * First, ensure that the first element is a sub-Package. If not,
+ * the BIOS may have incorrectly returned the object as a single
+ * package instead of a Package of Packages (a common error if
+ * there is only one entry). We may be able to repair this by
+ * wrapping the returned Package with a new outer Package.
*/
+ if ((*elements)->common.type != ACPI_TYPE_PACKAGE) {
+
+ /* Create the new outer package and populate it */
+
+ status =
+ acpi_ns_repair_package_list(data,
+ return_object_ptr);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Update locals to point to the new package (of 1 element) */
+
+ return_object = *return_object_ptr;
+ elements = return_object->package.elements;
+ count = 1;
+ }
+
+ /* Validate each sub-Package in the parent Package */
+
for (i = 0; i < count; i++) {
sub_package = *elements;
sub_elements = sub_package->package.elements;