aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/nsrepair2.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-12-11 02:29:44 -0500
committerLen Brown <len.brown@intel.com>2009-12-15 17:29:37 -0500
commitd4085a3ffee8828f7f1bae7fa3cf5e58f59ba627 (patch)
tree4c2397ce902284b20c21c3b96d393707311c46d4 /drivers/acpi/acpica/nsrepair2.c
parente31c32cfe52e98344dad28853c3331879f72c4b0 (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.c79
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
50ACPI_MODULE_NAME("nsrepair2") 51ACPI_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
95static acpi_status 96static acpi_status
96acpi_ns_remove_null_elements(union acpi_operand_object *package);
97
98static acpi_status
99acpi_ns_sort_list(union acpi_operand_object **elements, 97acpi_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
556static acpi_status 541void
557acpi_ns_remove_null_elements(union acpi_operand_object *obj_desc) 542acpi_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/******************************************************************************