diff options
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
-rw-r--r-- | drivers/acpi/acpica/nspredef.c | 93 |
1 files changed, 37 insertions, 56 deletions
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index b05f42903c86..d34fa59548f7 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -216,29 +216,38 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, | |||
216 | data->pathname = pathname; | 216 | data->pathname = pathname; |
217 | 217 | ||
218 | /* | 218 | /* |
219 | * Check that the type of the return object is what is expected for | 219 | * Check that the type of the main return object is what is expected |
220 | * this predefined name | 220 | * for this predefined name |
221 | */ | 221 | */ |
222 | status = acpi_ns_check_object_type(data, return_object_ptr, | 222 | status = acpi_ns_check_object_type(data, return_object_ptr, |
223 | predefined->info.expected_btypes, | 223 | predefined->info.expected_btypes, |
224 | ACPI_NOT_PACKAGE_ELEMENT); | 224 | ACPI_NOT_PACKAGE_ELEMENT); |
225 | if (ACPI_FAILURE(status)) { | 225 | if (ACPI_FAILURE(status)) { |
226 | goto check_validation_status; | 226 | goto exit; |
227 | } | 227 | } |
228 | 228 | ||
229 | /* For returned Package objects, check the type of all sub-objects */ | 229 | /* |
230 | 230 | * For returned Package objects, check the type of all sub-objects. | |
231 | if (return_object->common.type == ACPI_TYPE_PACKAGE) { | 231 | * Note: Package may have been newly created by call above. |
232 | */ | ||
233 | if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) { | ||
232 | status = acpi_ns_check_package(data, return_object_ptr); | 234 | status = acpi_ns_check_package(data, return_object_ptr); |
235 | if (ACPI_FAILURE(status)) { | ||
236 | goto exit; | ||
237 | } | ||
233 | } | 238 | } |
234 | 239 | ||
235 | /* | 240 | /* |
236 | * Perform additional, more complicated repairs on a per-name | 241 | * The return object was OK, or it was successfully repaired above. |
237 | * basis. | 242 | * Now make some additional checks such as verifying that package |
243 | * objects are sorted correctly (if required) or buffer objects have | ||
244 | * the correct data width (bytes vs. dwords). These repairs are | ||
245 | * performed on a per-name basis, i.e., the code is specific to | ||
246 | * particular predefined names. | ||
238 | */ | 247 | */ |
239 | status = acpi_ns_complex_repairs(data, node, status, return_object_ptr); | 248 | status = acpi_ns_complex_repairs(data, node, status, return_object_ptr); |
240 | 249 | ||
241 | check_validation_status: | 250 | exit: |
242 | /* | 251 | /* |
243 | * If the object validation failed or if we successfully repaired one | 252 | * If the object validation failed or if we successfully repaired one |
244 | * or more objects, mark the parent node to suppress further warning | 253 | * or more objects, mark the parent node to suppress further warning |
@@ -427,6 +436,13 @@ acpi_ns_check_package(struct acpi_predefined_data *data, | |||
427 | data->pathname, package->ret_info.type, | 436 | data->pathname, package->ret_info.type, |
428 | return_object->package.count)); | 437 | return_object->package.count)); |
429 | 438 | ||
439 | /* | ||
440 | * For variable-length Packages, we can safely remove all embedded | ||
441 | * and trailing NULL package elements | ||
442 | */ | ||
443 | acpi_ns_remove_null_elements(data, package->ret_info.type, | ||
444 | return_object); | ||
445 | |||
430 | /* Extract package count and elements array */ | 446 | /* Extract package count and elements array */ |
431 | 447 | ||
432 | elements = return_object->package.elements; | 448 | elements = return_object->package.elements; |
@@ -461,11 +477,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data, | |||
461 | if (count < expected_count) { | 477 | if (count < expected_count) { |
462 | goto package_too_small; | 478 | goto package_too_small; |
463 | } else if (count > expected_count) { | 479 | } else if (count > expected_count) { |
464 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | 480 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, |
465 | data->node_flags, | 481 | "%s: Return Package is larger than needed - " |
466 | "Return Package is larger than needed - " | 482 | "found %u, expected %u\n", |
467 | "found %u, expected %u", count, | 483 | data->pathname, count, |
468 | expected_count)); | 484 | expected_count)); |
469 | } | 485 | } |
470 | 486 | ||
471 | /* Validate all elements of the returned package */ | 487 | /* Validate all elements of the returned package */ |
@@ -680,53 +696,18 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data, | |||
680 | union acpi_operand_object *sub_package; | 696 | union acpi_operand_object *sub_package; |
681 | union acpi_operand_object **sub_elements; | 697 | union acpi_operand_object **sub_elements; |
682 | acpi_status status; | 698 | acpi_status status; |
683 | u8 non_trailing_null = FALSE; | ||
684 | u32 expected_count; | 699 | u32 expected_count; |
685 | u32 i; | 700 | u32 i; |
686 | u32 j; | 701 | u32 j; |
687 | 702 | ||
688 | /* Validate each sub-Package in the parent Package */ | 703 | /* |
689 | 704 | * Validate each sub-Package in the parent Package | |
705 | * | ||
706 | * NOTE: assumes list of sub-packages contains no NULL elements. | ||
707 | * Any NULL elements should have been removed by earlier call | ||
708 | * to acpi_ns_remove_null_elements. | ||
709 | */ | ||
690 | for (i = 0; i < count; i++) { | 710 | for (i = 0; i < count; i++) { |
691 | /* | ||
692 | * Handling for NULL package elements. For now, we will simply allow | ||
693 | * a parent package with trailing NULL elements. This can happen if | ||
694 | * the package was defined to be longer than the initializer list. | ||
695 | * This is legal as per the ACPI specification. It is often used | ||
696 | * to allow for dynamic initialization of a Package. | ||
697 | * | ||
698 | * A future enhancement may be to simply truncate the package to | ||
699 | * remove the trailing NULL elements. | ||
700 | */ | ||
701 | if (!(*elements)) { | ||
702 | if (!non_trailing_null) { | ||
703 | |||
704 | /* Ensure the remaining elements are all NULL */ | ||
705 | |||
706 | for (j = 1; j < (count - i + 1); j++) { | ||
707 | if (elements[j]) { | ||
708 | non_trailing_null = TRUE; | ||
709 | } | ||
710 | } | ||
711 | |||
712 | if (!non_trailing_null) { | ||
713 | |||
714 | /* Ignore the trailing NULL elements */ | ||
715 | |||
716 | return (AE_OK); | ||
717 | } | ||
718 | } | ||
719 | |||
720 | /* There are trailing non-null elements, issue warning */ | ||
721 | |||
722 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, | ||
723 | data->node_flags, | ||
724 | "Found NULL element at package index %u", | ||
725 | i)); | ||
726 | elements++; | ||
727 | continue; | ||
728 | } | ||
729 | |||
730 | sub_package = *elements; | 711 | sub_package = *elements; |
731 | sub_elements = sub_package->package.elements; | 712 | sub_elements = sub_package->package.elements; |
732 | 713 | ||