diff options
author | Bob Moore <robert.moore@intel.com> | 2009-07-24 05:03:09 +0200 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-29 01:40:38 +0200 |
commit | e5f69d6ef7a6b0dbad8d4c00d83009960be02155 (patch) | |
tree | fac155941c084b22c566b4931c67ab098a1488ee /drivers/acpi/acpica/nspredef.c | |
parent | ACPICA: Move predefined repair code to new file, no functional change (diff) | |
download | linux-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.c | 30 |
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; |