aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
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 */