aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nspredef.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
-rw-r--r--drivers/acpi/acpica/nspredef.c93
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
241check_validation_status: 250exit:
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