diff options
author | Bob Moore <robert.moore@intel.com> | 2009-07-23 23:22:11 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-08-28 19:40:38 -0400 |
commit | 53e9387bdd8bfef6cffff2d2eb6bd28eca812682 (patch) | |
tree | 5c69463c9c13640435f2ba91bc194c25b2dbb047 /drivers/acpi/acpica/nspredef.c | |
parent | e5f69d6ef7a6b0dbad8d4c00d83009960be02155 (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/nspredef.c')
-rw-r--r-- | drivers/acpi/acpica/nspredef.c | 326 |
1 files changed, 192 insertions, 134 deletions
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 | ||
78 | static acpi_status | 78 | static acpi_status |
79 | acpi_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 | |||
83 | static acpi_status | ||
79 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, | 84 | acpi_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 = | 635 | package_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 */ | 662 | static acpi_status |
663 | acpi_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: | 816 | package_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 | } |