diff options
author | Bob Moore <robert.moore@intel.com> | 2009-12-11 02:29:44 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-12-15 17:29:37 -0500 |
commit | d4085a3ffee8828f7f1bae7fa3cf5e58f59ba627 (patch) | |
tree | 4c2397ce902284b20c21c3b96d393707311c46d4 /drivers/acpi/acpica/nsrepair2.c | |
parent | e31c32cfe52e98344dad28853c3331879f72c4b0 (diff) |
ACPICA: Predefined name repair: automatically remove null package elements
This change will automatically remove embedded and trailing NULL
package elements from returned package objects that are defined
to containe a variable number of sub-packages. The driver is then
presented with a package with no null elements to deal with.
ACPICA BZ 819.
http://www.acpica.org/bugzilla/show_bug.cgi?id=819
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/nsrepair2.c')
-rw-r--r-- | drivers/acpi/acpica/nsrepair2.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/drivers/acpi/acpica/nsrepair2.c b/drivers/acpi/acpica/nsrepair2.c index e7373eb6cfa5..f13691c1cca5 100644 --- a/drivers/acpi/acpica/nsrepair2.c +++ b/drivers/acpi/acpica/nsrepair2.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
46 | #include "accommon.h" | 46 | #include "accommon.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acpredef.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_NAMESPACE | 50 | #define _COMPONENT ACPI_NAMESPACE |
50 | ACPI_MODULE_NAME("nsrepair2") | 51 | ACPI_MODULE_NAME("nsrepair2") |
@@ -93,9 +94,6 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, | |||
93 | u8 sort_direction, char *sort_key_name); | 94 | u8 sort_direction, char *sort_key_name); |
94 | 95 | ||
95 | static acpi_status | 96 | static acpi_status |
96 | acpi_ns_remove_null_elements(union acpi_operand_object *package); | ||
97 | |||
98 | static acpi_status | ||
99 | acpi_ns_sort_list(union acpi_operand_object **elements, | 97 | acpi_ns_sort_list(union acpi_operand_object **elements, |
100 | u32 count, u32 index, u8 sort_direction); | 98 | u32 count, u32 index, u8 sort_direction); |
101 | 99 | ||
@@ -456,25 +454,10 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, | |||
456 | } | 454 | } |
457 | 455 | ||
458 | /* | 456 | /* |
459 | * Detect any NULL package elements and remove them from the | 457 | * NOTE: assumes list of sub-packages contains no NULL elements. |
460 | * package. | 458 | * Any NULL elements should have been removed by earlier call |
461 | * | 459 | * to acpi_ns_remove_null_elements. |
462 | * TBD: We may want to do this for all predefined names that | ||
463 | * return a variable-length package of packages. | ||
464 | */ | 460 | */ |
465 | status = acpi_ns_remove_null_elements(return_object); | ||
466 | if (status == AE_NULL_ENTRY) { | ||
467 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
468 | "%s: NULL elements removed from package\n", | ||
469 | data->pathname)); | ||
470 | |||
471 | /* Exit if package is now zero length */ | ||
472 | |||
473 | if (!return_object->package.count) { | ||
474 | return (AE_NULL_ENTRY); | ||
475 | } | ||
476 | } | ||
477 | |||
478 | outer_elements = return_object->package.elements; | 461 | outer_elements = return_object->package.elements; |
479 | outer_element_count = return_object->package.count; | 462 | outer_element_count = return_object->package.count; |
480 | if (!outer_element_count) { | 463 | if (!outer_element_count) { |
@@ -544,36 +527,63 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data, | |||
544 | * | 527 | * |
545 | * FUNCTION: acpi_ns_remove_null_elements | 528 | * FUNCTION: acpi_ns_remove_null_elements |
546 | * | 529 | * |
547 | * PARAMETERS: obj_desc - A Package object | 530 | * PARAMETERS: Data - Pointer to validation data structure |
531 | * package_type - An acpi_return_package_types value | ||
532 | * obj_desc - A Package object | ||
548 | * | 533 | * |
549 | * RETURN: Status. AE_NULL_ENTRY means that one or more elements were | 534 | * RETURN: None. |
550 | * removed. | ||
551 | * | 535 | * |
552 | * DESCRIPTION: Remove all NULL package elements and update the package count. | 536 | * DESCRIPTION: Remove all NULL package elements from packages that contain |
537 | * a variable number of sub-packages. | ||
553 | * | 538 | * |
554 | *****************************************************************************/ | 539 | *****************************************************************************/ |
555 | 540 | ||
556 | static acpi_status | 541 | void |
557 | acpi_ns_remove_null_elements(union acpi_operand_object *obj_desc) | 542 | acpi_ns_remove_null_elements(struct acpi_predefined_data *data, |
543 | u8 package_type, | ||
544 | union acpi_operand_object *obj_desc) | ||
558 | { | 545 | { |
559 | union acpi_operand_object **source; | 546 | union acpi_operand_object **source; |
560 | union acpi_operand_object **dest; | 547 | union acpi_operand_object **dest; |
561 | acpi_status status = AE_OK; | ||
562 | u32 count; | 548 | u32 count; |
563 | u32 new_count; | 549 | u32 new_count; |
564 | u32 i; | 550 | u32 i; |
565 | 551 | ||
552 | ACPI_FUNCTION_NAME(ns_remove_null_elements); | ||
553 | |||
554 | /* | ||
555 | * PTYPE1 packages contain no subpackages. | ||
556 | * PTYPE2 packages contain a variable number of sub-packages. We can | ||
557 | * safely remove all NULL elements from the PTYPE2 packages. | ||
558 | */ | ||
559 | switch (package_type) { | ||
560 | case ACPI_PTYPE1_FIXED: | ||
561 | case ACPI_PTYPE1_VAR: | ||
562 | case ACPI_PTYPE1_OPTION: | ||
563 | return; | ||
564 | |||
565 | case ACPI_PTYPE2: | ||
566 | case ACPI_PTYPE2_COUNT: | ||
567 | case ACPI_PTYPE2_PKG_COUNT: | ||
568 | case ACPI_PTYPE2_FIXED: | ||
569 | case ACPI_PTYPE2_MIN: | ||
570 | case ACPI_PTYPE2_REV_FIXED: | ||
571 | break; | ||
572 | |||
573 | default: | ||
574 | return; | ||
575 | } | ||
576 | |||
566 | count = obj_desc->package.count; | 577 | count = obj_desc->package.count; |
567 | new_count = count; | 578 | new_count = count; |
568 | 579 | ||
569 | source = obj_desc->package.elements; | 580 | source = obj_desc->package.elements; |
570 | dest = source; | 581 | dest = source; |
571 | 582 | ||
572 | /* Examine all elements of the package object */ | 583 | /* Examine all elements of the package object, remove nulls */ |
573 | 584 | ||
574 | for (i = 0; i < count; i++) { | 585 | for (i = 0; i < count; i++) { |
575 | if (!*source) { | 586 | if (!*source) { |
576 | status = AE_NULL_ENTRY; | ||
577 | new_count--; | 587 | new_count--; |
578 | } else { | 588 | } else { |
579 | *dest = *source; | 589 | *dest = *source; |
@@ -582,15 +592,18 @@ acpi_ns_remove_null_elements(union acpi_operand_object *obj_desc) | |||
582 | source++; | 592 | source++; |
583 | } | 593 | } |
584 | 594 | ||
585 | if (status == AE_NULL_ENTRY) { | 595 | /* Update parent package if any null elements were removed */ |
596 | |||
597 | if (new_count < count) { | ||
598 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
599 | "%s: Found and removed %u NULL elements\n", | ||
600 | data->pathname, (count - new_count))); | ||
586 | 601 | ||
587 | /* NULL terminate list and update the package count */ | 602 | /* NULL terminate list and update the package count */ |
588 | 603 | ||
589 | *dest = NULL; | 604 | *dest = NULL; |
590 | obj_desc->package.count = new_count; | 605 | obj_desc->package.count = new_count; |
591 | } | 606 | } |
592 | |||
593 | return (status); | ||
594 | } | 607 | } |
595 | 608 | ||
596 | /****************************************************************************** | 609 | /****************************************************************************** |