aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-07-23 23:03:09 -0400
committerLen Brown <len.brown@intel.com>2009-08-28 19:40:38 -0400
commite5f69d6ef7a6b0dbad8d4c00d83009960be02155 (patch)
treefac155941c084b22c566b4931c67ab098a1488ee
parentb2deadd53c3630786e73746fb0ad8450f4e015bf (diff)
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>
-rw-r--r--drivers/acpi/acpica/acnamesp.h4
-rw-r--r--drivers/acpi/acpica/nspredef.c30
-rw-r--r--drivers/acpi/acpica/nsrepair.c52
3 files changed, 84 insertions, 2 deletions
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 908cfdd3b89..f75a7a01b87 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -278,6 +278,10 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
278 u32 package_index, 278 u32 package_index,
279 union acpi_operand_object **return_object_ptr); 279 union acpi_operand_object **return_object_ptr);
280 280
281acpi_status
282acpi_ns_repair_package_list(struct acpi_predefined_data *data,
283 union acpi_operand_object **obj_desc_ptr);
284
281/* 285/*
282 * nssearch - Namespace searching and entry 286 * nssearch - Namespace searching and entry
283 */ 287 */
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index e3f08dcb527..0091504df07 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,
566 case ACPI_PTYPE2_COUNT: 566 case ACPI_PTYPE2_COUNT:
567 567
568 /* 568 /*
569 * These types all return a single package that consists of a 569 * These types all return a single Package that consists of a
570 * variable number of sub-packages. 570 * variable number of sub-Packages.
571 *
572 * First, ensure that the first element is a sub-Package. If not,
573 * the BIOS may have incorrectly returned the object as a single
574 * package instead of a Package of Packages (a common error if
575 * there is only one entry). We may be able to repair this by
576 * wrapping the returned Package with a new outer Package.
571 */ 577 */
578 if ((*elements)->common.type != ACPI_TYPE_PACKAGE) {
579
580 /* Create the new outer package and populate it */
581
582 status =
583 acpi_ns_repair_package_list(data,
584 return_object_ptr);
585 if (ACPI_FAILURE(status)) {
586 return (status);
587 }
588
589 /* Update locals to point to the new package (of 1 element) */
590
591 return_object = *return_object_ptr;
592 elements = return_object->package.elements;
593 count = 1;
594 }
595
596 /* Validate each sub-Package in the parent Package */
597
572 for (i = 0; i < count; i++) { 598 for (i = 0; i < count; i++) {
573 sub_package = *elements; 599 sub_package = *elements;
574 sub_elements = sub_package->package.elements; 600 sub_elements = sub_package->package.elements;
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index b64751eacc5..db2b2a99c3a 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -149,3 +149,55 @@ acpi_ns_repair_object(struct acpi_predefined_data *data,
149 149
150 return (AE_AML_OPERAND_TYPE); 150 return (AE_AML_OPERAND_TYPE);
151} 151}
152
153/*******************************************************************************
154 *
155 * FUNCTION: acpi_ns_repair_package_list
156 *
157 * PARAMETERS: Data - Pointer to validation data structure
158 * obj_desc_ptr - Pointer to the object to repair. The new
159 * package object is returned here,
160 * overwriting the old object.
161 *
162 * RETURN: Status, new object in *obj_desc_ptr
163 *
164 * DESCRIPTION: Repair a common problem with objects that are defined to return
165 * a variable-length Package of Packages. If the variable-length
166 * is one, some BIOS code mistakenly simply declares a single
167 * Package instead of a Package with one sub-Package. This
168 * function attempts to repair this error by wrapping a Package
169 * object around the original Package, creating the correct
170 * Package with one sub-Package.
171 *
172 * Names that can be repaired in this manner include:
173 * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS
174 *
175 ******************************************************************************/
176
177acpi_status
178acpi_ns_repair_package_list(struct acpi_predefined_data *data,
179 union acpi_operand_object **obj_desc_ptr)
180{
181 union acpi_operand_object *pkg_obj_desc;
182
183 /*
184 * Create the new outer package and populate it. The new package will
185 * have a single element, the lone subpackage.
186 */
187 pkg_obj_desc = acpi_ut_create_package_object(1);
188 if (!pkg_obj_desc) {
189 return (AE_NO_MEMORY);
190 }
191
192 pkg_obj_desc->package.elements[0] = *obj_desc_ptr;
193
194 /* Return the new object in the object pointer */
195
196 *obj_desc_ptr = pkg_obj_desc;
197 data->flags |= ACPI_OBJECT_REPAIRED;
198
199 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
200 "Incorrectly formed Package, attempting repair"));
201
202 return (AE_OK);
203}