aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2009-07-23 23:22:11 -0400
committerLen Brown <len.brown@intel.com>2009-08-28 19:40:38 -0400
commit53e9387bdd8bfef6cffff2d2eb6bd28eca812682 (patch)
tree5c69463c9c13640435f2ba91bc194c25b2dbb047 /drivers/acpi/acpica
parente5f69d6ef7a6b0dbad8d4c00d83009960be02155 (diff)
ACPICA: ACPI 4.0 : Add new return package type, restructure module.
Added one new package type, a package that contains a revision number and a variable number of sub-packages. Restructured the module to put the sub-package list traversal in a separate function. 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')
-rw-r--r--drivers/acpi/acpica/acpredef.h5
-rw-r--r--drivers/acpi/acpica/nspredef.c326
2 files changed, 196 insertions, 135 deletions
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 63f656ae3604..144b1f41663f 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -91,6 +91,8 @@
91 * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length 91 * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
92 * (Used for _HPX) 92 * (Used for _HPX)
93 * 93 *
94 * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length
95 *
94 *****************************************************************************/ 96 *****************************************************************************/
95 97
96enum acpi_return_package_types { 98enum acpi_return_package_types {
@@ -101,7 +103,8 @@ enum acpi_return_package_types {
101 ACPI_PTYPE2_COUNT = 5, 103 ACPI_PTYPE2_COUNT = 5,
102 ACPI_PTYPE2_PKG_COUNT = 6, 104 ACPI_PTYPE2_PKG_COUNT = 6,
103 ACPI_PTYPE2_FIXED = 7, 105 ACPI_PTYPE2_FIXED = 7,
104 ACPI_PTYPE2_MIN = 8 106 ACPI_PTYPE2_MIN = 8,
107 ACPI_PTYPE2_REV_FIXED = 9
105}; 108};
106 109
107/* 110/*
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 0091504df074..0b2cdb37a678 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -76,6 +76,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
76 union acpi_operand_object **return_object_ptr); 76 union acpi_operand_object **return_object_ptr);
77 77
78static acpi_status 78static acpi_status
79acpi_ns_check_package_list(struct acpi_predefined_data *data,
80 const union acpi_predefined_info *package,
81 union acpi_operand_object **elements, u32 count);
82
83static acpi_status
79acpi_ns_check_package_elements(struct acpi_predefined_data *data, 84acpi_ns_check_package_elements(struct acpi_predefined_data *data,
80 union acpi_operand_object **elements, 85 union acpi_operand_object **elements,
81 u8 type1, 86 u8 type1,
@@ -393,14 +398,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
393{ 398{
394 union acpi_operand_object *return_object = *return_object_ptr; 399 union acpi_operand_object *return_object = *return_object_ptr;
395 const union acpi_predefined_info *package; 400 const union acpi_predefined_info *package;
396 union acpi_operand_object *sub_package;
397 union acpi_operand_object **elements; 401 union acpi_operand_object **elements;
398 union acpi_operand_object **sub_elements; 402 acpi_status status = AE_OK;
399 acpi_status status;
400 u32 expected_count; 403 u32 expected_count;
401 u32 count; 404 u32 count;
402 u32 i; 405 u32 i;
403 u32 j;
404 406
405 ACPI_FUNCTION_NAME(ns_check_package); 407 ACPI_FUNCTION_NAME(ns_check_package);
406 408
@@ -465,9 +467,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
465 object_type2, 467 object_type2,
466 package->ret_info. 468 package->ret_info.
467 count2, 0); 469 count2, 0);
468 if (ACPI_FAILURE(status)) {
469 return (status);
470 }
471 break; 470 break;
472 471
473 case ACPI_PTYPE1_VAR: 472 case ACPI_PTYPE1_VAR:
@@ -534,6 +533,25 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
534 } 533 }
535 break; 534 break;
536 535
536 case ACPI_PTYPE2_REV_FIXED:
537
538 /* First element is the (Integer) revision */
539
540 status = acpi_ns_check_object_type(data, elements,
541 ACPI_RTYPE_INTEGER, 0);
542 if (ACPI_FAILURE(status)) {
543 return (status);
544 }
545
546 elements++;
547 count--;
548
549 /* Examine the sub-packages */
550
551 status =
552 acpi_ns_check_package_list(data, package, elements, count);
553 break;
554
537 case ACPI_PTYPE2_PKG_COUNT: 555 case ACPI_PTYPE2_PKG_COUNT:
538 556
539 /* First element is the (Integer) count of sub-packages to follow */ 557 /* First element is the (Integer) count of sub-packages to follow */
@@ -556,9 +574,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
556 count = expected_count; 574 count = expected_count;
557 elements++; 575 elements++;
558 576
559 /* Now we can walk the sub-packages */ 577 /* Examine the sub-packages */
560 578
561 /*lint -fallthrough */ 579 status =
580 acpi_ns_check_package_list(data, package, elements, count);
581 break;
562 582
563 case ACPI_PTYPE2: 583 case ACPI_PTYPE2:
564 case ACPI_PTYPE2_FIXED: 584 case ACPI_PTYPE2_FIXED:
@@ -593,175 +613,213 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
593 count = 1; 613 count = 1;
594 } 614 }
595 615
596 /* Validate each sub-Package in the parent Package */ 616 /* Examine the sub-packages */
597 617
598 for (i = 0; i < count; i++) { 618 status =
599 sub_package = *elements; 619 acpi_ns_check_package_list(data, package, elements, count);
600 sub_elements = sub_package->package.elements; 620 break;
601 621
602 /* Each sub-object must be of type Package */ 622 default:
603 623
604 status = acpi_ns_check_object_type(data, &sub_package, 624 /* Should not get here if predefined info table is correct */
605 ACPI_RTYPE_PACKAGE,
606 i);
607 if (ACPI_FAILURE(status)) {
608 return (status);
609 }
610 625
611 /* Examine the different types of sub-packages */ 626 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
627 "Invalid internal return type in table entry: %X",
628 package->ret_info.type));
612 629
613 switch (package->ret_info.type) { 630 return (AE_AML_INTERNAL);
614 case ACPI_PTYPE2: 631 }
615 case ACPI_PTYPE2_PKG_COUNT:
616 632
617 /* Each subpackage has a fixed number of elements */ 633 return (status);
618 634
619 expected_count = 635package_too_small:
620 package->ret_info.count1 +
621 package->ret_info.count2;
622 if (sub_package->package.count !=
623 expected_count) {
624 count = sub_package->package.count;
625 goto package_too_small;
626 }
627 636
628 status = 637 /* Error exit for the case with an incorrect package count */
629 acpi_ns_check_package_elements(data,
630 sub_elements,
631 package->
632 ret_info.
633 object_type1,
634 package->
635 ret_info.
636 count1,
637 package->
638 ret_info.
639 object_type2,
640 package->
641 ret_info.
642 count2, 0);
643 if (ACPI_FAILURE(status)) {
644 return (status);
645 }
646 break;
647 638
648 case ACPI_PTYPE2_FIXED: 639 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
640 "Return Package is too small - found %u elements, expected %u",
641 count, expected_count));
649 642
650 /* Each sub-package has a fixed length */ 643 return (AE_AML_OPERAND_VALUE);
644}
651 645
652 expected_count = package->ret_info2.count; 646/*******************************************************************************
653 if (sub_package->package.count < expected_count) { 647 *
654 count = sub_package->package.count; 648 * FUNCTION: acpi_ns_check_package_list
655 goto package_too_small; 649 *
656 } 650 * PARAMETERS: Data - Pointer to validation data structure
651 * Package - Pointer to package-specific info for method
652 * Elements - Element list of parent package. All elements
653 * of this list should be of type Package.
654 * Count - Count of subpackages
655 *
656 * RETURN: Status
657 *
658 * DESCRIPTION: Examine a list of subpackages
659 *
660 ******************************************************************************/
657 661
658 /* Check the type of each sub-package element */ 662static acpi_status
663acpi_ns_check_package_list(struct acpi_predefined_data *data,
664 const union acpi_predefined_info *package,
665 union acpi_operand_object **elements, u32 count)
666{
667 union acpi_operand_object *sub_package;
668 union acpi_operand_object **sub_elements;
669 acpi_status status;
670 u32 expected_count;
671 u32 i;
672 u32 j;
659 673
660 for (j = 0; j < expected_count; j++) { 674 /* Validate each sub-Package in the parent Package */
661 status =
662 acpi_ns_check_object_type(data,
663 &sub_elements[j],
664 package->ret_info2.object_type[j], j);
665 if (ACPI_FAILURE(status)) {
666 return (status);
667 }
668 }
669 break;
670 675
671 case ACPI_PTYPE2_MIN: 676 for (i = 0; i < count; i++) {
677 sub_package = *elements;
678 sub_elements = sub_package->package.elements;
672 679
673 /* Each sub-package has a variable but minimum length */ 680 /* Each sub-object must be of type Package */
674 681
675 expected_count = package->ret_info.count1; 682 status = acpi_ns_check_object_type(data, &sub_package,
676 if (sub_package->package.count < expected_count) { 683 ACPI_RTYPE_PACKAGE, i);
677 count = sub_package->package.count; 684 if (ACPI_FAILURE(status)) {
678 goto package_too_small; 685 return (status);
679 } 686 }
680 687
681 /* Check the type of each sub-package element */ 688 /* Examine the different types of expected sub-packages */
682 689
683 status = 690 switch (package->ret_info.type) {
684 acpi_ns_check_package_elements(data, 691 case ACPI_PTYPE2:
685 sub_elements, 692 case ACPI_PTYPE2_PKG_COUNT:
686 package-> 693 case ACPI_PTYPE2_REV_FIXED:
687 ret_info. 694
688 object_type1, 695 /* Each subpackage has a fixed number of elements */
689 sub_package-> 696
690 package. 697 expected_count =
691 count, 0, 0, 698 package->ret_info.count1 + package->ret_info.count2;
692 0); 699 if (sub_package->package.count < expected_count) {
693 if (ACPI_FAILURE(status)) { 700 goto package_too_small;
694 return (status); 701 }
695 } 702
696 break; 703 status =
704 acpi_ns_check_package_elements(data, sub_elements,
705 package->ret_info.
706 object_type1,
707 package->ret_info.
708 count1,
709 package->ret_info.
710 object_type2,
711 package->ret_info.
712 count2, 0);
713 if (ACPI_FAILURE(status)) {
714 return (status);
715 }
716 break;
717
718 case ACPI_PTYPE2_FIXED:
719
720 /* Each sub-package has a fixed length */
697 721
698 case ACPI_PTYPE2_COUNT: 722 expected_count = package->ret_info2.count;
723 if (sub_package->package.count < expected_count) {
724 goto package_too_small;
725 }
699 726
700 /* First element is the (Integer) count of elements to follow */ 727 /* Check the type of each sub-package element */
701 728
729 for (j = 0; j < expected_count; j++) {
702 status = 730 status =
703 acpi_ns_check_object_type(data, 731 acpi_ns_check_object_type(data,
704 sub_elements, 732 &sub_elements[j],
705 ACPI_RTYPE_INTEGER, 733 package->
706 0); 734 ret_info2.
735 object_type[j],
736 j);
707 if (ACPI_FAILURE(status)) { 737 if (ACPI_FAILURE(status)) {
708 return (status); 738 return (status);
709 } 739 }
740 }
741 break;
710 742
711 /* Make sure package is large enough for the Count */ 743 case ACPI_PTYPE2_MIN:
712 744
713 expected_count = 745 /* Each sub-package has a variable but minimum length */
714 (u32) (*sub_elements)->integer.value;
715 if (sub_package->package.count < expected_count) {
716 count = sub_package->package.count;
717 goto package_too_small;
718 }
719 746
720 /* Check the type of each sub-package element */ 747 expected_count = package->ret_info.count1;
748 if (sub_package->package.count < expected_count) {
749 goto package_too_small;
750 }
721 751
722 status = 752 /* Check the type of each sub-package element */
723 acpi_ns_check_package_elements(data,
724 (sub_elements
725 + 1),
726 package->
727 ret_info.
728 object_type1,
729 (expected_count
730 - 1), 0, 0,
731 1);
732 if (ACPI_FAILURE(status)) {
733 return (status);
734 }
735 break;
736 753
737 default: 754 status =
738 break; 755 acpi_ns_check_package_elements(data, sub_elements,
756 package->ret_info.
757 object_type1,
758 sub_package->package.
759 count, 0, 0, 0);
760 if (ACPI_FAILURE(status)) {
761 return (status);
739 } 762 }
763 break;
740 764
741 elements++; 765 case ACPI_PTYPE2_COUNT:
742 }
743 break;
744 766
745 default: 767 /*
768 * First element is the (Integer) count of elements, including
769 * the count field.
770 */
771 status = acpi_ns_check_object_type(data, sub_elements,
772 ACPI_RTYPE_INTEGER,
773 0);
774 if (ACPI_FAILURE(status)) {
775 return (status);
776 }
746 777
747 /* Should not get here if predefined info table is correct */ 778 /*
779 * Make sure package is large enough for the Count and is
780 * is as large as the minimum size
781 */
782 expected_count = (u32)(*sub_elements)->integer.value;
783 if (sub_package->package.count < expected_count) {
784 goto package_too_small;
785 }
786 if (sub_package->package.count <
787 package->ret_info.count1) {
788 expected_count = package->ret_info.count1;
789 goto package_too_small;
790 }
748 791
749 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 792 /* Check the type of each sub-package element */
750 "Invalid internal return type in table entry: %X",
751 package->ret_info.type));
752 793
753 return (AE_AML_INTERNAL); 794 status =
795 acpi_ns_check_package_elements(data,
796 (sub_elements + 1),
797 package->ret_info.
798 object_type1,
799 (expected_count - 1),
800 0, 0, 1);
801 if (ACPI_FAILURE(status)) {
802 return (status);
803 }
804 break;
805
806 default: /* Should not get here, type was validated by caller */
807
808 return (AE_AML_INTERNAL);
809 }
810
811 elements++;
754 } 812 }
755 813
756 return (AE_OK); 814 return (AE_OK);
757 815
758 package_too_small: 816package_too_small:
759 817
760 /* Error exit for the case with an incorrect package count */ 818 /* The sub-package count was smaller than required */
761 819
762 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, 820 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
763 "Return Package is too small - found %u, expected %u", 821 "Return Sub-Package[%u] is too small - found %u elements, expected %u",
764 count, expected_count)); 822 i, sub_package->package.count, expected_count));
765 823
766 return (AE_AML_OPERAND_VALUE); 824 return (AE_AML_OPERAND_VALUE);
767} 825}