diff options
Diffstat (limited to 'drivers/acpi/acpica/nspredef.c')
-rw-r--r-- | drivers/acpi/acpica/nspredef.c | 581 |
1 files changed, 1 insertions, 580 deletions
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 1f0e93401436..909520923fbe 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c | |||
@@ -73,27 +73,6 @@ ACPI_MODULE_NAME("nspredef") | |||
73 | ******************************************************************************/ | 73 | ******************************************************************************/ |
74 | /* Local prototypes */ | 74 | /* Local prototypes */ |
75 | static acpi_status | 75 | static acpi_status |
76 | acpi_ns_check_package(struct acpi_predefined_data *data, | ||
77 | union acpi_operand_object **return_object_ptr); | ||
78 | |||
79 | static acpi_status | ||
80 | acpi_ns_check_package_list(struct acpi_predefined_data *data, | ||
81 | const union acpi_predefined_info *package, | ||
82 | union acpi_operand_object **elements, u32 count); | ||
83 | |||
84 | static acpi_status | ||
85 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, | ||
86 | union acpi_operand_object **elements, | ||
87 | u8 type1, | ||
88 | u32 count1, | ||
89 | u8 type2, u32 count2, u32 start_index); | ||
90 | |||
91 | static acpi_status | ||
92 | acpi_ns_check_object_type(struct acpi_predefined_data *data, | ||
93 | union acpi_operand_object **return_object_ptr, | ||
94 | u32 expected_btypes, u32 package_index); | ||
95 | |||
96 | static acpi_status | ||
97 | acpi_ns_check_reference(struct acpi_predefined_data *data, | 76 | acpi_ns_check_reference(struct acpi_predefined_data *data, |
98 | union acpi_operand_object *return_object); | 77 | union acpi_operand_object *return_object); |
99 | 78 | ||
@@ -407,564 +386,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct | |||
407 | 386 | ||
408 | /******************************************************************************* | 387 | /******************************************************************************* |
409 | * | 388 | * |
410 | * FUNCTION: acpi_ns_check_package | ||
411 | * | ||
412 | * PARAMETERS: data - Pointer to validation data structure | ||
413 | * return_object_ptr - Pointer to the object returned from the | ||
414 | * evaluation of a method or object | ||
415 | * | ||
416 | * RETURN: Status | ||
417 | * | ||
418 | * DESCRIPTION: Check a returned package object for the correct count and | ||
419 | * correct type of all sub-objects. | ||
420 | * | ||
421 | ******************************************************************************/ | ||
422 | |||
423 | static acpi_status | ||
424 | acpi_ns_check_package(struct acpi_predefined_data *data, | ||
425 | union acpi_operand_object **return_object_ptr) | ||
426 | { | ||
427 | union acpi_operand_object *return_object = *return_object_ptr; | ||
428 | const union acpi_predefined_info *package; | ||
429 | union acpi_operand_object **elements; | ||
430 | acpi_status status = AE_OK; | ||
431 | u32 expected_count; | ||
432 | u32 count; | ||
433 | u32 i; | ||
434 | |||
435 | ACPI_FUNCTION_NAME(ns_check_package); | ||
436 | |||
437 | /* The package info for this name is in the next table entry */ | ||
438 | |||
439 | package = data->predefined + 1; | ||
440 | |||
441 | ACPI_DEBUG_PRINT((ACPI_DB_NAMES, | ||
442 | "%s Validating return Package of Type %X, Count %X\n", | ||
443 | data->pathname, package->ret_info.type, | ||
444 | return_object->package.count)); | ||
445 | |||
446 | /* | ||
447 | * For variable-length Packages, we can safely remove all embedded | ||
448 | * and trailing NULL package elements | ||
449 | */ | ||
450 | acpi_ns_remove_null_elements(data, package->ret_info.type, | ||
451 | return_object); | ||
452 | |||
453 | /* Extract package count and elements array */ | ||
454 | |||
455 | elements = return_object->package.elements; | ||
456 | count = return_object->package.count; | ||
457 | |||
458 | /* The package must have at least one element, else invalid */ | ||
459 | |||
460 | if (!count) { | ||
461 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
462 | "Return Package has no elements (empty)")); | ||
463 | |||
464 | return (AE_AML_OPERAND_VALUE); | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * Decode the type of the expected package contents | ||
469 | * | ||
470 | * PTYPE1 packages contain no subpackages | ||
471 | * PTYPE2 packages contain sub-packages | ||
472 | */ | ||
473 | switch (package->ret_info.type) { | ||
474 | case ACPI_PTYPE1_FIXED: | ||
475 | |||
476 | /* | ||
477 | * The package count is fixed and there are no sub-packages | ||
478 | * | ||
479 | * If package is too small, exit. | ||
480 | * If package is larger than expected, issue warning but continue | ||
481 | */ | ||
482 | expected_count = | ||
483 | package->ret_info.count1 + package->ret_info.count2; | ||
484 | if (count < expected_count) { | ||
485 | goto package_too_small; | ||
486 | } else if (count > expected_count) { | ||
487 | ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, | ||
488 | "%s: Return Package is larger than needed - " | ||
489 | "found %u, expected %u\n", | ||
490 | data->pathname, count, | ||
491 | expected_count)); | ||
492 | } | ||
493 | |||
494 | /* Validate all elements of the returned package */ | ||
495 | |||
496 | status = acpi_ns_check_package_elements(data, elements, | ||
497 | package->ret_info. | ||
498 | object_type1, | ||
499 | package->ret_info. | ||
500 | count1, | ||
501 | package->ret_info. | ||
502 | object_type2, | ||
503 | package->ret_info. | ||
504 | count2, 0); | ||
505 | break; | ||
506 | |||
507 | case ACPI_PTYPE1_VAR: | ||
508 | |||
509 | /* | ||
510 | * The package count is variable, there are no sub-packages, and all | ||
511 | * elements must be of the same type | ||
512 | */ | ||
513 | for (i = 0; i < count; i++) { | ||
514 | status = acpi_ns_check_object_type(data, elements, | ||
515 | package->ret_info. | ||
516 | object_type1, i); | ||
517 | if (ACPI_FAILURE(status)) { | ||
518 | return (status); | ||
519 | } | ||
520 | elements++; | ||
521 | } | ||
522 | break; | ||
523 | |||
524 | case ACPI_PTYPE1_OPTION: | ||
525 | |||
526 | /* | ||
527 | * The package count is variable, there are no sub-packages. There are | ||
528 | * a fixed number of required elements, and a variable number of | ||
529 | * optional elements. | ||
530 | * | ||
531 | * Check if package is at least as large as the minimum required | ||
532 | */ | ||
533 | expected_count = package->ret_info3.count; | ||
534 | if (count < expected_count) { | ||
535 | goto package_too_small; | ||
536 | } | ||
537 | |||
538 | /* Variable number of sub-objects */ | ||
539 | |||
540 | for (i = 0; i < count; i++) { | ||
541 | if (i < package->ret_info3.count) { | ||
542 | |||
543 | /* These are the required package elements (0, 1, or 2) */ | ||
544 | |||
545 | status = | ||
546 | acpi_ns_check_object_type(data, elements, | ||
547 | package-> | ||
548 | ret_info3. | ||
549 | object_type[i], | ||
550 | i); | ||
551 | if (ACPI_FAILURE(status)) { | ||
552 | return (status); | ||
553 | } | ||
554 | } else { | ||
555 | /* These are the optional package elements */ | ||
556 | |||
557 | status = | ||
558 | acpi_ns_check_object_type(data, elements, | ||
559 | package-> | ||
560 | ret_info3. | ||
561 | tail_object_type, | ||
562 | i); | ||
563 | if (ACPI_FAILURE(status)) { | ||
564 | return (status); | ||
565 | } | ||
566 | } | ||
567 | elements++; | ||
568 | } | ||
569 | break; | ||
570 | |||
571 | case ACPI_PTYPE2_REV_FIXED: | ||
572 | |||
573 | /* First element is the (Integer) revision */ | ||
574 | |||
575 | status = acpi_ns_check_object_type(data, elements, | ||
576 | ACPI_RTYPE_INTEGER, 0); | ||
577 | if (ACPI_FAILURE(status)) { | ||
578 | return (status); | ||
579 | } | ||
580 | |||
581 | elements++; | ||
582 | count--; | ||
583 | |||
584 | /* Examine the sub-packages */ | ||
585 | |||
586 | status = | ||
587 | acpi_ns_check_package_list(data, package, elements, count); | ||
588 | break; | ||
589 | |||
590 | case ACPI_PTYPE2_PKG_COUNT: | ||
591 | |||
592 | /* First element is the (Integer) count of sub-packages to follow */ | ||
593 | |||
594 | status = acpi_ns_check_object_type(data, elements, | ||
595 | ACPI_RTYPE_INTEGER, 0); | ||
596 | if (ACPI_FAILURE(status)) { | ||
597 | return (status); | ||
598 | } | ||
599 | |||
600 | /* | ||
601 | * Count cannot be larger than the parent package length, but allow it | ||
602 | * to be smaller. The >= accounts for the Integer above. | ||
603 | */ | ||
604 | expected_count = (u32) (*elements)->integer.value; | ||
605 | if (expected_count >= count) { | ||
606 | goto package_too_small; | ||
607 | } | ||
608 | |||
609 | count = expected_count; | ||
610 | elements++; | ||
611 | |||
612 | /* Examine the sub-packages */ | ||
613 | |||
614 | status = | ||
615 | acpi_ns_check_package_list(data, package, elements, count); | ||
616 | break; | ||
617 | |||
618 | case ACPI_PTYPE2: | ||
619 | case ACPI_PTYPE2_FIXED: | ||
620 | case ACPI_PTYPE2_MIN: | ||
621 | case ACPI_PTYPE2_COUNT: | ||
622 | case ACPI_PTYPE2_FIX_VAR: | ||
623 | |||
624 | /* | ||
625 | * These types all return a single Package that consists of a | ||
626 | * variable number of sub-Packages. | ||
627 | * | ||
628 | * First, ensure that the first element is a sub-Package. If not, | ||
629 | * the BIOS may have incorrectly returned the object as a single | ||
630 | * package instead of a Package of Packages (a common error if | ||
631 | * there is only one entry). We may be able to repair this by | ||
632 | * wrapping the returned Package with a new outer Package. | ||
633 | */ | ||
634 | if (*elements | ||
635 | && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) { | ||
636 | |||
637 | /* Create the new outer package and populate it */ | ||
638 | |||
639 | status = | ||
640 | acpi_ns_wrap_with_package(data, return_object, | ||
641 | return_object_ptr); | ||
642 | if (ACPI_FAILURE(status)) { | ||
643 | return (status); | ||
644 | } | ||
645 | |||
646 | /* Update locals to point to the new package (of 1 element) */ | ||
647 | |||
648 | return_object = *return_object_ptr; | ||
649 | elements = return_object->package.elements; | ||
650 | count = 1; | ||
651 | } | ||
652 | |||
653 | /* Examine the sub-packages */ | ||
654 | |||
655 | status = | ||
656 | acpi_ns_check_package_list(data, package, elements, count); | ||
657 | break; | ||
658 | |||
659 | default: | ||
660 | |||
661 | /* Should not get here if predefined info table is correct */ | ||
662 | |||
663 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
664 | "Invalid internal return type in table entry: %X", | ||
665 | package->ret_info.type)); | ||
666 | |||
667 | return (AE_AML_INTERNAL); | ||
668 | } | ||
669 | |||
670 | return (status); | ||
671 | |||
672 | package_too_small: | ||
673 | |||
674 | /* Error exit for the case with an incorrect package count */ | ||
675 | |||
676 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
677 | "Return Package is too small - found %u elements, expected %u", | ||
678 | count, expected_count)); | ||
679 | |||
680 | return (AE_AML_OPERAND_VALUE); | ||
681 | } | ||
682 | |||
683 | /******************************************************************************* | ||
684 | * | ||
685 | * FUNCTION: acpi_ns_check_package_list | ||
686 | * | ||
687 | * PARAMETERS: data - Pointer to validation data structure | ||
688 | * package - Pointer to package-specific info for method | ||
689 | * elements - Element list of parent package. All elements | ||
690 | * of this list should be of type Package. | ||
691 | * count - Count of subpackages | ||
692 | * | ||
693 | * RETURN: Status | ||
694 | * | ||
695 | * DESCRIPTION: Examine a list of subpackages | ||
696 | * | ||
697 | ******************************************************************************/ | ||
698 | |||
699 | static acpi_status | ||
700 | acpi_ns_check_package_list(struct acpi_predefined_data *data, | ||
701 | const union acpi_predefined_info *package, | ||
702 | union acpi_operand_object **elements, u32 count) | ||
703 | { | ||
704 | union acpi_operand_object *sub_package; | ||
705 | union acpi_operand_object **sub_elements; | ||
706 | acpi_status status; | ||
707 | u32 expected_count; | ||
708 | u32 i; | ||
709 | u32 j; | ||
710 | |||
711 | /* | ||
712 | * Validate each sub-Package in the parent Package | ||
713 | * | ||
714 | * NOTE: assumes list of sub-packages contains no NULL elements. | ||
715 | * Any NULL elements should have been removed by earlier call | ||
716 | * to acpi_ns_remove_null_elements. | ||
717 | */ | ||
718 | for (i = 0; i < count; i++) { | ||
719 | sub_package = *elements; | ||
720 | sub_elements = sub_package->package.elements; | ||
721 | data->parent_package = sub_package; | ||
722 | |||
723 | /* Each sub-object must be of type Package */ | ||
724 | |||
725 | status = acpi_ns_check_object_type(data, &sub_package, | ||
726 | ACPI_RTYPE_PACKAGE, i); | ||
727 | if (ACPI_FAILURE(status)) { | ||
728 | return (status); | ||
729 | } | ||
730 | |||
731 | /* Examine the different types of expected sub-packages */ | ||
732 | |||
733 | data->parent_package = sub_package; | ||
734 | switch (package->ret_info.type) { | ||
735 | case ACPI_PTYPE2: | ||
736 | case ACPI_PTYPE2_PKG_COUNT: | ||
737 | case ACPI_PTYPE2_REV_FIXED: | ||
738 | |||
739 | /* Each subpackage has a fixed number of elements */ | ||
740 | |||
741 | expected_count = | ||
742 | package->ret_info.count1 + package->ret_info.count2; | ||
743 | if (sub_package->package.count < expected_count) { | ||
744 | goto package_too_small; | ||
745 | } | ||
746 | |||
747 | status = | ||
748 | acpi_ns_check_package_elements(data, sub_elements, | ||
749 | package->ret_info. | ||
750 | object_type1, | ||
751 | package->ret_info. | ||
752 | count1, | ||
753 | package->ret_info. | ||
754 | object_type2, | ||
755 | package->ret_info. | ||
756 | count2, 0); | ||
757 | if (ACPI_FAILURE(status)) { | ||
758 | return (status); | ||
759 | } | ||
760 | break; | ||
761 | |||
762 | case ACPI_PTYPE2_FIX_VAR: | ||
763 | /* | ||
764 | * Each subpackage has a fixed number of elements and an | ||
765 | * optional element | ||
766 | */ | ||
767 | expected_count = | ||
768 | package->ret_info.count1 + package->ret_info.count2; | ||
769 | if (sub_package->package.count < expected_count) { | ||
770 | goto package_too_small; | ||
771 | } | ||
772 | |||
773 | status = | ||
774 | acpi_ns_check_package_elements(data, sub_elements, | ||
775 | package->ret_info. | ||
776 | object_type1, | ||
777 | package->ret_info. | ||
778 | count1, | ||
779 | package->ret_info. | ||
780 | object_type2, | ||
781 | sub_package->package. | ||
782 | count - | ||
783 | package->ret_info. | ||
784 | count1, 0); | ||
785 | if (ACPI_FAILURE(status)) { | ||
786 | return (status); | ||
787 | } | ||
788 | break; | ||
789 | |||
790 | case ACPI_PTYPE2_FIXED: | ||
791 | |||
792 | /* Each sub-package has a fixed length */ | ||
793 | |||
794 | expected_count = package->ret_info2.count; | ||
795 | if (sub_package->package.count < expected_count) { | ||
796 | goto package_too_small; | ||
797 | } | ||
798 | |||
799 | /* Check the type of each sub-package element */ | ||
800 | |||
801 | for (j = 0; j < expected_count; j++) { | ||
802 | status = | ||
803 | acpi_ns_check_object_type(data, | ||
804 | &sub_elements[j], | ||
805 | package-> | ||
806 | ret_info2. | ||
807 | object_type[j], | ||
808 | j); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | return (status); | ||
811 | } | ||
812 | } | ||
813 | break; | ||
814 | |||
815 | case ACPI_PTYPE2_MIN: | ||
816 | |||
817 | /* Each sub-package has a variable but minimum length */ | ||
818 | |||
819 | expected_count = package->ret_info.count1; | ||
820 | if (sub_package->package.count < expected_count) { | ||
821 | goto package_too_small; | ||
822 | } | ||
823 | |||
824 | /* Check the type of each sub-package element */ | ||
825 | |||
826 | status = | ||
827 | acpi_ns_check_package_elements(data, sub_elements, | ||
828 | package->ret_info. | ||
829 | object_type1, | ||
830 | sub_package->package. | ||
831 | count, 0, 0, 0); | ||
832 | if (ACPI_FAILURE(status)) { | ||
833 | return (status); | ||
834 | } | ||
835 | break; | ||
836 | |||
837 | case ACPI_PTYPE2_COUNT: | ||
838 | |||
839 | /* | ||
840 | * First element is the (Integer) count of elements, including | ||
841 | * the count field (the ACPI name is num_elements) | ||
842 | */ | ||
843 | status = acpi_ns_check_object_type(data, sub_elements, | ||
844 | ACPI_RTYPE_INTEGER, | ||
845 | 0); | ||
846 | if (ACPI_FAILURE(status)) { | ||
847 | return (status); | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | * Make sure package is large enough for the Count and is | ||
852 | * is as large as the minimum size | ||
853 | */ | ||
854 | expected_count = (u32)(*sub_elements)->integer.value; | ||
855 | if (sub_package->package.count < expected_count) { | ||
856 | goto package_too_small; | ||
857 | } | ||
858 | if (sub_package->package.count < | ||
859 | package->ret_info.count1) { | ||
860 | expected_count = package->ret_info.count1; | ||
861 | goto package_too_small; | ||
862 | } | ||
863 | if (expected_count == 0) { | ||
864 | /* | ||
865 | * Either the num_entries element was originally zero or it was | ||
866 | * a NULL element and repaired to an Integer of value zero. | ||
867 | * In either case, repair it by setting num_entries to be the | ||
868 | * actual size of the subpackage. | ||
869 | */ | ||
870 | expected_count = sub_package->package.count; | ||
871 | (*sub_elements)->integer.value = expected_count; | ||
872 | } | ||
873 | |||
874 | /* Check the type of each sub-package element */ | ||
875 | |||
876 | status = | ||
877 | acpi_ns_check_package_elements(data, | ||
878 | (sub_elements + 1), | ||
879 | package->ret_info. | ||
880 | object_type1, | ||
881 | (expected_count - 1), | ||
882 | 0, 0, 1); | ||
883 | if (ACPI_FAILURE(status)) { | ||
884 | return (status); | ||
885 | } | ||
886 | break; | ||
887 | |||
888 | default: /* Should not get here, type was validated by caller */ | ||
889 | |||
890 | return (AE_AML_INTERNAL); | ||
891 | } | ||
892 | |||
893 | elements++; | ||
894 | } | ||
895 | |||
896 | return (AE_OK); | ||
897 | |||
898 | package_too_small: | ||
899 | |||
900 | /* The sub-package count was smaller than required */ | ||
901 | |||
902 | ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, | ||
903 | "Return Sub-Package[%u] is too small - found %u elements, expected %u", | ||
904 | i, sub_package->package.count, expected_count)); | ||
905 | |||
906 | return (AE_AML_OPERAND_VALUE); | ||
907 | } | ||
908 | |||
909 | /******************************************************************************* | ||
910 | * | ||
911 | * FUNCTION: acpi_ns_check_package_elements | ||
912 | * | ||
913 | * PARAMETERS: data - Pointer to validation data structure | ||
914 | * elements - Pointer to the package elements array | ||
915 | * type1 - Object type for first group | ||
916 | * count1 - Count for first group | ||
917 | * type2 - Object type for second group | ||
918 | * count2 - Count for second group | ||
919 | * start_index - Start of the first group of elements | ||
920 | * | ||
921 | * RETURN: Status | ||
922 | * | ||
923 | * DESCRIPTION: Check that all elements of a package are of the correct object | ||
924 | * type. Supports up to two groups of different object types. | ||
925 | * | ||
926 | ******************************************************************************/ | ||
927 | |||
928 | static acpi_status | ||
929 | acpi_ns_check_package_elements(struct acpi_predefined_data *data, | ||
930 | union acpi_operand_object **elements, | ||
931 | u8 type1, | ||
932 | u32 count1, | ||
933 | u8 type2, u32 count2, u32 start_index) | ||
934 | { | ||
935 | union acpi_operand_object **this_element = elements; | ||
936 | acpi_status status; | ||
937 | u32 i; | ||
938 | |||
939 | /* | ||
940 | * Up to two groups of package elements are supported by the data | ||
941 | * structure. All elements in each group must be of the same type. | ||
942 | * The second group can have a count of zero. | ||
943 | */ | ||
944 | for (i = 0; i < count1; i++) { | ||
945 | status = acpi_ns_check_object_type(data, this_element, | ||
946 | type1, i + start_index); | ||
947 | if (ACPI_FAILURE(status)) { | ||
948 | return (status); | ||
949 | } | ||
950 | this_element++; | ||
951 | } | ||
952 | |||
953 | for (i = 0; i < count2; i++) { | ||
954 | status = acpi_ns_check_object_type(data, this_element, | ||
955 | type2, | ||
956 | (i + count1 + start_index)); | ||
957 | if (ACPI_FAILURE(status)) { | ||
958 | return (status); | ||
959 | } | ||
960 | this_element++; | ||
961 | } | ||
962 | |||
963 | return (AE_OK); | ||
964 | } | ||
965 | |||
966 | /******************************************************************************* | ||
967 | * | ||
968 | * FUNCTION: acpi_ns_check_object_type | 389 | * FUNCTION: acpi_ns_check_object_type |
969 | * | 390 | * |
970 | * PARAMETERS: data - Pointer to validation data structure | 391 | * PARAMETERS: data - Pointer to validation data structure |
@@ -982,7 +403,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data, | |||
982 | * | 403 | * |
983 | ******************************************************************************/ | 404 | ******************************************************************************/ |
984 | 405 | ||
985 | static acpi_status | 406 | acpi_status |
986 | acpi_ns_check_object_type(struct acpi_predefined_data *data, | 407 | acpi_ns_check_object_type(struct acpi_predefined_data *data, |
987 | union acpi_operand_object **return_object_ptr, | 408 | union acpi_operand_object **return_object_ptr, |
988 | u32 expected_btypes, u32 package_index) | 409 | u32 expected_btypes, u32 package_index) |