diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/dispatcher/dsobject.c | 27 |
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 */ |