aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2007-02-02 11:48:18 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:20 -0500
commit24058054d781934df526be114c612cf2b29cf4e7 (patch)
tree66ca3e558fea81ec8ec38127f49df17c88f51115 /drivers/acpi
parentc9e3ba2c1d178195e17bb4f1d49c32e0be8dbb16 (diff)
ACPICA: Handle mis-matched package length
Implement support within the AML interpreter for package objects that contain a mismatch between the AML length and package element count. In this case, the lesser of the two is used. Some BIOS code apparently modifies the package length on the fly, and this change supports this. Provides compatibility with the MS AML interpreter. Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/dispatcher/dsobject.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
index 72190abb1d59..aaeb9f987ecc 100644
--- a/drivers/acpi/dispatcher/dsobject.c
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -318,9 +318,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
318 obj_desc->package.node = parent->common.node; 318 obj_desc->package.node = parent->common.node;
319 } 319 }
320 320
321 obj_desc->package.count = package_length; 321 /* Count the *actual* number of items in the package list */
322
323 /* Count the number of items in the package list */
324 322
325 arg = op->common.value.arg; 323 arg = op->common.value.arg;
326 arg = arg->common.next; 324 arg = arg->common.next;
@@ -329,11 +327,24 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
329 } 327 }
330 328
331 /* 329 /*
332 * The package length (number of elements) will be the greater 330 * The number of elements in the package will be the lesser of the
333 * of the specified length and the length of the initializer list 331 * specified element count and the length of the initializer list.
332 *
333 * Even though the ASL compilers do not allow this to happen (for the
334 * fixed length package opcode), some BIOS code modifies the AML on the
335 * fly to adjust the package length, and this code compensates for that.
336 * This also provides compatibility with other AML interpreters.
334 */ 337 */
335 if (package_list_length > package_length) { 338 obj_desc->package.count = package_length;
336 obj_desc->package.count = package_list_length; 339
340 if (package_list_length != package_length) {
341 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
342 "Package length mismatch, using lesser of %X(Length Arg) and %X(AML Length)\n",
343 package_length, package_list_length));
344
345 if (package_list_length < package_length) {
346 obj_desc->package.count = package_list_length;
347 }
337 } 348 }
338 349
339 /* 350 /*
@@ -356,7 +367,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
356 */ 367 */
357 arg = op->common.value.arg; 368 arg = op->common.value.arg;
358 arg = arg->common.next; 369 arg = arg->common.next;
359 for (i = 0; arg; i++) { 370 for (i = 0; i < obj_desc->package.count; i++) {
360 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) { 371 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
361 372
362 /* Object (package or buffer) is already built */ 373 /* Object (package or buffer) is already built */