diff options
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r-- | drivers/acpi/parser/psparse.c | 728 |
1 files changed, 4 insertions, 724 deletions
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index bdbe0d99486f..16b84a3d0436 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
@@ -62,26 +62,6 @@ | |||
62 | ACPI_MODULE_NAME ("psparse") | 62 | ACPI_MODULE_NAME ("psparse") |
63 | 63 | ||
64 | 64 | ||
65 | static u32 acpi_gbl_depth = 0; | ||
66 | |||
67 | /* Local prototypes */ | ||
68 | |||
69 | static acpi_status | ||
70 | acpi_ps_complete_this_op ( | ||
71 | struct acpi_walk_state *walk_state, | ||
72 | union acpi_parse_object *op); | ||
73 | |||
74 | static acpi_status | ||
75 | acpi_ps_next_parse_state ( | ||
76 | struct acpi_walk_state *walk_state, | ||
77 | union acpi_parse_object *op, | ||
78 | acpi_status callback_status); | ||
79 | |||
80 | static acpi_status | ||
81 | acpi_ps_parse_loop ( | ||
82 | struct acpi_walk_state *walk_state); | ||
83 | |||
84 | |||
85 | /******************************************************************************* | 65 | /******************************************************************************* |
86 | * | 66 | * |
87 | * FUNCTION: acpi_ps_get_opcode_size | 67 | * FUNCTION: acpi_ps_get_opcode_size |
@@ -134,8 +114,8 @@ acpi_ps_peek_opcode ( | |||
134 | aml = parser_state->aml; | 114 | aml = parser_state->aml; |
135 | opcode = (u16) ACPI_GET8 (aml); | 115 | opcode = (u16) ACPI_GET8 (aml); |
136 | 116 | ||
137 | if (opcode == AML_EXTOP) { | 117 | if (opcode == AML_EXTENDED_OP_PREFIX) { |
138 | /* Extended opcode */ | 118 | /* Extended opcode, get the second opcode byte */ |
139 | 119 | ||
140 | aml++; | 120 | aml++; |
141 | opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml)); | 121 | opcode = (u16) ((opcode << 8) | ACPI_GET8 (aml)); |
@@ -158,7 +138,7 @@ acpi_ps_peek_opcode ( | |||
158 | * | 138 | * |
159 | ******************************************************************************/ | 139 | ******************************************************************************/ |
160 | 140 | ||
161 | static acpi_status | 141 | acpi_status |
162 | acpi_ps_complete_this_op ( | 142 | acpi_ps_complete_this_op ( |
163 | struct acpi_walk_state *walk_state, | 143 | struct acpi_walk_state *walk_state, |
164 | union acpi_parse_object *op) | 144 | union acpi_parse_object *op) |
@@ -331,7 +311,7 @@ allocate_error: | |||
331 | * | 311 | * |
332 | ******************************************************************************/ | 312 | ******************************************************************************/ |
333 | 313 | ||
334 | static acpi_status | 314 | acpi_status |
335 | acpi_ps_next_parse_state ( | 315 | acpi_ps_next_parse_state ( |
336 | struct acpi_walk_state *walk_state, | 316 | struct acpi_walk_state *walk_state, |
337 | union acpi_parse_object *op, | 317 | union acpi_parse_object *op, |
@@ -441,706 +421,6 @@ acpi_ps_next_parse_state ( | |||
441 | 421 | ||
442 | /******************************************************************************* | 422 | /******************************************************************************* |
443 | * | 423 | * |
444 | * FUNCTION: acpi_ps_parse_loop | ||
445 | * | ||
446 | * PARAMETERS: walk_state - Current state | ||
447 | * | ||
448 | * RETURN: Status | ||
449 | * | ||
450 | * DESCRIPTION: Parse AML (pointed to by the current parser state) and return | ||
451 | * a tree of ops. | ||
452 | * | ||
453 | ******************************************************************************/ | ||
454 | |||
455 | static acpi_status | ||
456 | acpi_ps_parse_loop ( | ||
457 | struct acpi_walk_state *walk_state) | ||
458 | { | ||
459 | acpi_status status = AE_OK; | ||
460 | acpi_status status2; | ||
461 | union acpi_parse_object *op = NULL; /* current op */ | ||
462 | union acpi_parse_object *arg = NULL; | ||
463 | union acpi_parse_object *pre_op = NULL; | ||
464 | struct acpi_parse_state *parser_state; | ||
465 | u8 *aml_op_start = NULL; | ||
466 | |||
467 | |||
468 | ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state); | ||
469 | |||
470 | if (walk_state->descending_callback == NULL) { | ||
471 | return_ACPI_STATUS (AE_BAD_PARAMETER); | ||
472 | } | ||
473 | |||
474 | parser_state = &walk_state->parser_state; | ||
475 | walk_state->arg_types = 0; | ||
476 | |||
477 | #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) | ||
478 | |||
479 | if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) { | ||
480 | /* We are restarting a preempted control method */ | ||
481 | |||
482 | if (acpi_ps_has_completed_scope (parser_state)) { | ||
483 | /* | ||
484 | * We must check if a predicate to an IF or WHILE statement | ||
485 | * was just completed | ||
486 | */ | ||
487 | if ((parser_state->scope->parse_scope.op) && | ||
488 | ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) || | ||
489 | (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) && | ||
490 | (walk_state->control_state) && | ||
491 | (walk_state->control_state->common.state == | ||
492 | ACPI_CONTROL_PREDICATE_EXECUTING)) { | ||
493 | /* | ||
494 | * A predicate was just completed, get the value of the | ||
495 | * predicate and branch based on that value | ||
496 | */ | ||
497 | walk_state->op = NULL; | ||
498 | status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE)); | ||
499 | if (ACPI_FAILURE (status) && | ||
500 | ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) { | ||
501 | if (status == AE_AML_NO_RETURN_VALUE) { | ||
502 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
503 | "Invoked method did not return a value, %s\n", | ||
504 | acpi_format_exception (status))); | ||
505 | |||
506 | } | ||
507 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
508 | "get_predicate Failed, %s\n", | ||
509 | acpi_format_exception (status))); | ||
510 | return_ACPI_STATUS (status); | ||
511 | } | ||
512 | |||
513 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
514 | } | ||
515 | |||
516 | acpi_ps_pop_scope (parser_state, &op, | ||
517 | &walk_state->arg_types, &walk_state->arg_count); | ||
518 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); | ||
519 | } | ||
520 | else if (walk_state->prev_op) { | ||
521 | /* We were in the middle of an op */ | ||
522 | |||
523 | op = walk_state->prev_op; | ||
524 | walk_state->arg_types = walk_state->prev_arg_types; | ||
525 | } | ||
526 | } | ||
527 | #endif | ||
528 | |||
529 | /* Iterative parsing loop, while there is more AML to process: */ | ||
530 | |||
531 | while ((parser_state->aml < parser_state->aml_end) || (op)) { | ||
532 | aml_op_start = parser_state->aml; | ||
533 | if (!op) { | ||
534 | /* Get the next opcode from the AML stream */ | ||
535 | |||
536 | walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml, | ||
537 | parser_state->aml_start); | ||
538 | walk_state->opcode = acpi_ps_peek_opcode (parser_state); | ||
539 | |||
540 | /* | ||
541 | * First cut to determine what we have found: | ||
542 | * 1) A valid AML opcode | ||
543 | * 2) A name string | ||
544 | * 3) An unknown/invalid opcode | ||
545 | */ | ||
546 | walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode); | ||
547 | switch (walk_state->op_info->class) { | ||
548 | case AML_CLASS_ASCII: | ||
549 | case AML_CLASS_PREFIX: | ||
550 | /* | ||
551 | * Starts with a valid prefix or ASCII char, this is a name | ||
552 | * string. Convert the bare name string to a namepath. | ||
553 | */ | ||
554 | walk_state->opcode = AML_INT_NAMEPATH_OP; | ||
555 | walk_state->arg_types = ARGP_NAMESTRING; | ||
556 | break; | ||
557 | |||
558 | case AML_CLASS_UNKNOWN: | ||
559 | |||
560 | /* The opcode is unrecognized. Just skip unknown opcodes */ | ||
561 | |||
562 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
563 | "Found unknown opcode %X at AML address %p offset %X, ignoring\n", | ||
564 | walk_state->opcode, parser_state->aml, walk_state->aml_offset)); | ||
565 | |||
566 | ACPI_DUMP_BUFFER (parser_state->aml, 128); | ||
567 | |||
568 | /* Assume one-byte bad opcode */ | ||
569 | |||
570 | parser_state->aml++; | ||
571 | continue; | ||
572 | |||
573 | default: | ||
574 | |||
575 | /* Found opcode info, this is a normal opcode */ | ||
576 | |||
577 | parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode); | ||
578 | walk_state->arg_types = walk_state->op_info->parse_args; | ||
579 | break; | ||
580 | } | ||
581 | |||
582 | /* Create Op structure and append to parent's argument list */ | ||
583 | |||
584 | if (walk_state->op_info->flags & AML_NAMED) { | ||
585 | /* Allocate a new pre_op if necessary */ | ||
586 | |||
587 | if (!pre_op) { | ||
588 | pre_op = acpi_ps_alloc_op (walk_state->opcode); | ||
589 | if (!pre_op) { | ||
590 | status = AE_NO_MEMORY; | ||
591 | goto close_this_op; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | pre_op->common.value.arg = NULL; | ||
596 | pre_op->common.aml_opcode = walk_state->opcode; | ||
597 | |||
598 | /* | ||
599 | * Get and append arguments until we find the node that contains | ||
600 | * the name (the type ARGP_NAME). | ||
601 | */ | ||
602 | while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && | ||
603 | (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) { | ||
604 | status = acpi_ps_get_next_arg (walk_state, parser_state, | ||
605 | GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg); | ||
606 | if (ACPI_FAILURE (status)) { | ||
607 | goto close_this_op; | ||
608 | } | ||
609 | |||
610 | acpi_ps_append_arg (pre_op, arg); | ||
611 | INCREMENT_ARG_LIST (walk_state->arg_types); | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * Make sure that we found a NAME and didn't run out of | ||
616 | * arguments | ||
617 | */ | ||
618 | if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) { | ||
619 | status = AE_AML_NO_OPERAND; | ||
620 | goto close_this_op; | ||
621 | } | ||
622 | |||
623 | /* We know that this arg is a name, move to next arg */ | ||
624 | |||
625 | INCREMENT_ARG_LIST (walk_state->arg_types); | ||
626 | |||
627 | /* | ||
628 | * Find the object. This will either insert the object into | ||
629 | * the namespace or simply look it up | ||
630 | */ | ||
631 | walk_state->op = NULL; | ||
632 | |||
633 | status = walk_state->descending_callback (walk_state, &op); | ||
634 | if (ACPI_FAILURE (status)) { | ||
635 | ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, | ||
636 | "During name lookup/catalog, %s\n", | ||
637 | acpi_format_exception (status))); | ||
638 | goto close_this_op; | ||
639 | } | ||
640 | |||
641 | if (!op) { | ||
642 | continue; | ||
643 | } | ||
644 | |||
645 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
646 | if (status == AE_CTRL_PENDING) { | ||
647 | status = AE_OK; | ||
648 | goto close_this_op; | ||
649 | } | ||
650 | |||
651 | if (ACPI_FAILURE (status)) { | ||
652 | goto close_this_op; | ||
653 | } | ||
654 | |||
655 | acpi_ps_append_arg (op, pre_op->common.value.arg); | ||
656 | acpi_gbl_depth++; | ||
657 | |||
658 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
659 | /* | ||
660 | * Defer final parsing of an operation_region body, | ||
661 | * because we don't have enough info in the first pass | ||
662 | * to parse it correctly (i.e., there may be method | ||
663 | * calls within the term_arg elements of the body.) | ||
664 | * | ||
665 | * However, we must continue parsing because | ||
666 | * the opregion is not a standalone package -- | ||
667 | * we don't know where the end is at this point. | ||
668 | * | ||
669 | * (Length is unknown until parse of the body complete) | ||
670 | */ | ||
671 | op->named.data = aml_op_start; | ||
672 | op->named.length = 0; | ||
673 | } | ||
674 | } | ||
675 | else { | ||
676 | /* Not a named opcode, just allocate Op and append to parent */ | ||
677 | |||
678 | walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode); | ||
679 | op = acpi_ps_alloc_op (walk_state->opcode); | ||
680 | if (!op) { | ||
681 | status = AE_NO_MEMORY; | ||
682 | goto close_this_op; | ||
683 | } | ||
684 | |||
685 | if (walk_state->op_info->flags & AML_CREATE) { | ||
686 | /* | ||
687 | * Backup to beginning of create_xXXfield declaration | ||
688 | * body_length is unknown until we parse the body | ||
689 | */ | ||
690 | op->named.data = aml_op_start; | ||
691 | op->named.length = 0; | ||
692 | } | ||
693 | |||
694 | acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op); | ||
695 | |||
696 | if ((walk_state->descending_callback != NULL)) { | ||
697 | /* | ||
698 | * Find the object. This will either insert the object into | ||
699 | * the namespace or simply look it up | ||
700 | */ | ||
701 | walk_state->op = op; | ||
702 | |||
703 | status = walk_state->descending_callback (walk_state, &op); | ||
704 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
705 | if (status == AE_CTRL_PENDING) { | ||
706 | status = AE_OK; | ||
707 | goto close_this_op; | ||
708 | } | ||
709 | |||
710 | if (ACPI_FAILURE (status)) { | ||
711 | goto close_this_op; | ||
712 | } | ||
713 | } | ||
714 | } | ||
715 | |||
716 | op->common.aml_offset = walk_state->aml_offset; | ||
717 | |||
718 | if (walk_state->op_info) { | ||
719 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, | ||
720 | "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n", | ||
721 | (u32) op->common.aml_opcode, walk_state->op_info->name, | ||
722 | op, parser_state->aml, op->common.aml_offset)); | ||
723 | } | ||
724 | } | ||
725 | |||
726 | |||
727 | /* | ||
728 | * Start arg_count at zero because we don't know if there are | ||
729 | * any args yet | ||
730 | */ | ||
731 | walk_state->arg_count = 0; | ||
732 | |||
733 | /* Are there any arguments that must be processed? */ | ||
734 | |||
735 | if (walk_state->arg_types) { | ||
736 | /* Get arguments */ | ||
737 | |||
738 | switch (op->common.aml_opcode) { | ||
739 | case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ | ||
740 | case AML_WORD_OP: /* AML_WORDDATA_ARG */ | ||
741 | case AML_DWORD_OP: /* AML_DWORDATA_ARG */ | ||
742 | case AML_QWORD_OP: /* AML_QWORDATA_ARG */ | ||
743 | case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ | ||
744 | |||
745 | /* Fill in constant or string argument directly */ | ||
746 | |||
747 | acpi_ps_get_next_simple_arg (parser_state, | ||
748 | GET_CURRENT_ARG_TYPE (walk_state->arg_types), op); | ||
749 | break; | ||
750 | |||
751 | case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ | ||
752 | |||
753 | status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1); | ||
754 | if (ACPI_FAILURE (status)) { | ||
755 | goto close_this_op; | ||
756 | } | ||
757 | |||
758 | walk_state->arg_types = 0; | ||
759 | break; | ||
760 | |||
761 | default: | ||
762 | /* | ||
763 | * Op is not a constant or string, append each argument | ||
764 | * to the Op | ||
765 | */ | ||
766 | while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && | ||
767 | !walk_state->arg_count) { | ||
768 | walk_state->aml_offset = (u32) | ||
769 | ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start); | ||
770 | |||
771 | status = acpi_ps_get_next_arg (walk_state, parser_state, | ||
772 | GET_CURRENT_ARG_TYPE (walk_state->arg_types), | ||
773 | &arg); | ||
774 | if (ACPI_FAILURE (status)) { | ||
775 | goto close_this_op; | ||
776 | } | ||
777 | |||
778 | if (arg) { | ||
779 | arg->common.aml_offset = walk_state->aml_offset; | ||
780 | acpi_ps_append_arg (op, arg); | ||
781 | } | ||
782 | INCREMENT_ARG_LIST (walk_state->arg_types); | ||
783 | } | ||
784 | |||
785 | /* Special processing for certain opcodes */ | ||
786 | |||
787 | if (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) { | ||
788 | switch (op->common.aml_opcode) { | ||
789 | case AML_IF_OP: | ||
790 | case AML_ELSE_OP: | ||
791 | case AML_WHILE_OP: | ||
792 | |||
793 | /* Skip body of if/else/while in pass 1 */ | ||
794 | |||
795 | parser_state->aml = parser_state->pkg_end; | ||
796 | walk_state->arg_count = 0; | ||
797 | break; | ||
798 | |||
799 | default: | ||
800 | break; | ||
801 | } | ||
802 | } | ||
803 | |||
804 | switch (op->common.aml_opcode) { | ||
805 | case AML_METHOD_OP: | ||
806 | |||
807 | /* | ||
808 | * Skip parsing of control method | ||
809 | * because we don't have enough info in the first pass | ||
810 | * to parse it correctly. | ||
811 | * | ||
812 | * Save the length and address of the body | ||
813 | */ | ||
814 | op->named.data = parser_state->aml; | ||
815 | op->named.length = (u32) (parser_state->pkg_end - | ||
816 | parser_state->aml); | ||
817 | |||
818 | /* Skip body of method */ | ||
819 | |||
820 | parser_state->aml = parser_state->pkg_end; | ||
821 | walk_state->arg_count = 0; | ||
822 | break; | ||
823 | |||
824 | case AML_BUFFER_OP: | ||
825 | case AML_PACKAGE_OP: | ||
826 | case AML_VAR_PACKAGE_OP: | ||
827 | |||
828 | if ((op->common.parent) && | ||
829 | (op->common.parent->common.aml_opcode == AML_NAME_OP) && | ||
830 | (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) { | ||
831 | /* | ||
832 | * Skip parsing of Buffers and Packages | ||
833 | * because we don't have enough info in the first pass | ||
834 | * to parse them correctly. | ||
835 | */ | ||
836 | op->named.data = aml_op_start; | ||
837 | op->named.length = (u32) (parser_state->pkg_end - | ||
838 | aml_op_start); | ||
839 | |||
840 | /* Skip body */ | ||
841 | |||
842 | parser_state->aml = parser_state->pkg_end; | ||
843 | walk_state->arg_count = 0; | ||
844 | } | ||
845 | break; | ||
846 | |||
847 | case AML_WHILE_OP: | ||
848 | |||
849 | if (walk_state->control_state) { | ||
850 | walk_state->control_state->control.package_end = | ||
851 | parser_state->pkg_end; | ||
852 | } | ||
853 | break; | ||
854 | |||
855 | default: | ||
856 | |||
857 | /* No action for all other opcodes */ | ||
858 | break; | ||
859 | } | ||
860 | break; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | /* Check for arguments that need to be processed */ | ||
865 | |||
866 | if (walk_state->arg_count) { | ||
867 | /* | ||
868 | * There are arguments (complex ones), push Op and | ||
869 | * prepare for argument | ||
870 | */ | ||
871 | status = acpi_ps_push_scope (parser_state, op, | ||
872 | walk_state->arg_types, walk_state->arg_count); | ||
873 | if (ACPI_FAILURE (status)) { | ||
874 | goto close_this_op; | ||
875 | } | ||
876 | op = NULL; | ||
877 | continue; | ||
878 | } | ||
879 | |||
880 | /* | ||
881 | * All arguments have been processed -- Op is complete, | ||
882 | * prepare for next | ||
883 | */ | ||
884 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); | ||
885 | if (walk_state->op_info->flags & AML_NAMED) { | ||
886 | if (acpi_gbl_depth) { | ||
887 | acpi_gbl_depth--; | ||
888 | } | ||
889 | |||
890 | if (op->common.aml_opcode == AML_REGION_OP) { | ||
891 | /* | ||
892 | * Skip parsing of control method or opregion body, | ||
893 | * because we don't have enough info in the first pass | ||
894 | * to parse them correctly. | ||
895 | * | ||
896 | * Completed parsing an op_region declaration, we now | ||
897 | * know the length. | ||
898 | */ | ||
899 | op->named.length = (u32) (parser_state->aml - op->named.data); | ||
900 | } | ||
901 | } | ||
902 | |||
903 | if (walk_state->op_info->flags & AML_CREATE) { | ||
904 | /* | ||
905 | * Backup to beginning of create_xXXfield declaration (1 for | ||
906 | * Opcode) | ||
907 | * | ||
908 | * body_length is unknown until we parse the body | ||
909 | */ | ||
910 | op->named.length = (u32) (parser_state->aml - op->named.data); | ||
911 | } | ||
912 | |||
913 | /* This op complete, notify the dispatcher */ | ||
914 | |||
915 | if (walk_state->ascending_callback != NULL) { | ||
916 | walk_state->op = op; | ||
917 | walk_state->opcode = op->common.aml_opcode; | ||
918 | |||
919 | status = walk_state->ascending_callback (walk_state); | ||
920 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
921 | if (status == AE_CTRL_PENDING) { | ||
922 | status = AE_OK; | ||
923 | goto close_this_op; | ||
924 | } | ||
925 | } | ||
926 | |||
927 | |||
928 | close_this_op: | ||
929 | /* | ||
930 | * Finished one argument of the containing scope | ||
931 | */ | ||
932 | parser_state->scope->parse_scope.arg_count--; | ||
933 | |||
934 | /* Finished with pre_op */ | ||
935 | |||
936 | if (pre_op) { | ||
937 | acpi_ps_free_op (pre_op); | ||
938 | pre_op = NULL; | ||
939 | } | ||
940 | |||
941 | /* Close this Op (will result in parse subtree deletion) */ | ||
942 | |||
943 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
944 | if (ACPI_FAILURE (status2)) { | ||
945 | return_ACPI_STATUS (status2); | ||
946 | } | ||
947 | op = NULL; | ||
948 | |||
949 | switch (status) { | ||
950 | case AE_OK: | ||
951 | break; | ||
952 | |||
953 | |||
954 | case AE_CTRL_TRANSFER: | ||
955 | |||
956 | /* We are about to transfer to a called method. */ | ||
957 | |||
958 | walk_state->prev_op = op; | ||
959 | walk_state->prev_arg_types = walk_state->arg_types; | ||
960 | return_ACPI_STATUS (status); | ||
961 | |||
962 | |||
963 | case AE_CTRL_END: | ||
964 | |||
965 | acpi_ps_pop_scope (parser_state, &op, | ||
966 | &walk_state->arg_types, &walk_state->arg_count); | ||
967 | |||
968 | if (op) { | ||
969 | walk_state->op = op; | ||
970 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); | ||
971 | walk_state->opcode = op->common.aml_opcode; | ||
972 | |||
973 | status = walk_state->ascending_callback (walk_state); | ||
974 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
975 | |||
976 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
977 | if (ACPI_FAILURE (status2)) { | ||
978 | return_ACPI_STATUS (status2); | ||
979 | } | ||
980 | op = NULL; | ||
981 | } | ||
982 | status = AE_OK; | ||
983 | break; | ||
984 | |||
985 | |||
986 | case AE_CTRL_BREAK: | ||
987 | case AE_CTRL_CONTINUE: | ||
988 | |||
989 | /* Pop off scopes until we find the While */ | ||
990 | |||
991 | while (!op || (op->common.aml_opcode != AML_WHILE_OP)) { | ||
992 | acpi_ps_pop_scope (parser_state, &op, | ||
993 | &walk_state->arg_types, &walk_state->arg_count); | ||
994 | } | ||
995 | |||
996 | /* Close this iteration of the While loop */ | ||
997 | |||
998 | walk_state->op = op; | ||
999 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); | ||
1000 | walk_state->opcode = op->common.aml_opcode; | ||
1001 | |||
1002 | status = walk_state->ascending_callback (walk_state); | ||
1003 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
1004 | |||
1005 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
1006 | if (ACPI_FAILURE (status2)) { | ||
1007 | return_ACPI_STATUS (status2); | ||
1008 | } | ||
1009 | op = NULL; | ||
1010 | |||
1011 | status = AE_OK; | ||
1012 | break; | ||
1013 | |||
1014 | |||
1015 | case AE_CTRL_TERMINATE: | ||
1016 | |||
1017 | status = AE_OK; | ||
1018 | |||
1019 | /* Clean up */ | ||
1020 | do { | ||
1021 | if (op) { | ||
1022 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
1023 | if (ACPI_FAILURE (status2)) { | ||
1024 | return_ACPI_STATUS (status2); | ||
1025 | } | ||
1026 | } | ||
1027 | acpi_ps_pop_scope (parser_state, &op, | ||
1028 | &walk_state->arg_types, &walk_state->arg_count); | ||
1029 | |||
1030 | } while (op); | ||
1031 | |||
1032 | return_ACPI_STATUS (status); | ||
1033 | |||
1034 | |||
1035 | default: /* All other non-AE_OK status */ | ||
1036 | |||
1037 | do { | ||
1038 | if (op) { | ||
1039 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
1040 | if (ACPI_FAILURE (status2)) { | ||
1041 | return_ACPI_STATUS (status2); | ||
1042 | } | ||
1043 | } | ||
1044 | acpi_ps_pop_scope (parser_state, &op, | ||
1045 | &walk_state->arg_types, &walk_state->arg_count); | ||
1046 | |||
1047 | } while (op); | ||
1048 | |||
1049 | |||
1050 | /* | ||
1051 | * TBD: Cleanup parse ops on error | ||
1052 | */ | ||
1053 | #if 0 | ||
1054 | if (op == NULL) { | ||
1055 | acpi_ps_pop_scope (parser_state, &op, | ||
1056 | &walk_state->arg_types, &walk_state->arg_count); | ||
1057 | } | ||
1058 | #endif | ||
1059 | walk_state->prev_op = op; | ||
1060 | walk_state->prev_arg_types = walk_state->arg_types; | ||
1061 | return_ACPI_STATUS (status); | ||
1062 | } | ||
1063 | |||
1064 | /* This scope complete? */ | ||
1065 | |||
1066 | if (acpi_ps_has_completed_scope (parser_state)) { | ||
1067 | acpi_ps_pop_scope (parser_state, &op, | ||
1068 | &walk_state->arg_types, &walk_state->arg_count); | ||
1069 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op)); | ||
1070 | } | ||
1071 | else { | ||
1072 | op = NULL; | ||
1073 | } | ||
1074 | |||
1075 | } /* while parser_state->Aml */ | ||
1076 | |||
1077 | |||
1078 | /* | ||
1079 | * Complete the last Op (if not completed), and clear the scope stack. | ||
1080 | * It is easily possible to end an AML "package" with an unbounded number | ||
1081 | * of open scopes (such as when several ASL blocks are closed with | ||
1082 | * sequential closing braces). We want to terminate each one cleanly. | ||
1083 | */ | ||
1084 | ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op)); | ||
1085 | do { | ||
1086 | if (op) { | ||
1087 | if (walk_state->ascending_callback != NULL) { | ||
1088 | walk_state->op = op; | ||
1089 | walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode); | ||
1090 | walk_state->opcode = op->common.aml_opcode; | ||
1091 | |||
1092 | status = walk_state->ascending_callback (walk_state); | ||
1093 | status = acpi_ps_next_parse_state (walk_state, op, status); | ||
1094 | if (status == AE_CTRL_PENDING) { | ||
1095 | status = AE_OK; | ||
1096 | goto close_this_op; | ||
1097 | } | ||
1098 | |||
1099 | if (status == AE_CTRL_TERMINATE) { | ||
1100 | status = AE_OK; | ||
1101 | |||
1102 | /* Clean up */ | ||
1103 | do { | ||
1104 | if (op) { | ||
1105 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
1106 | if (ACPI_FAILURE (status2)) { | ||
1107 | return_ACPI_STATUS (status2); | ||
1108 | } | ||
1109 | } | ||
1110 | |||
1111 | acpi_ps_pop_scope (parser_state, &op, | ||
1112 | &walk_state->arg_types, &walk_state->arg_count); | ||
1113 | |||
1114 | } while (op); | ||
1115 | |||
1116 | return_ACPI_STATUS (status); | ||
1117 | } | ||
1118 | |||
1119 | else if (ACPI_FAILURE (status)) { | ||
1120 | /* First error is most important */ | ||
1121 | |||
1122 | (void) acpi_ps_complete_this_op (walk_state, op); | ||
1123 | return_ACPI_STATUS (status); | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | status2 = acpi_ps_complete_this_op (walk_state, op); | ||
1128 | if (ACPI_FAILURE (status2)) { | ||
1129 | return_ACPI_STATUS (status2); | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, | ||
1134 | &walk_state->arg_count); | ||
1135 | |||
1136 | } while (op); | ||
1137 | |||
1138 | return_ACPI_STATUS (status); | ||
1139 | } | ||
1140 | |||
1141 | |||
1142 | /******************************************************************************* | ||
1143 | * | ||
1144 | * FUNCTION: acpi_ps_parse_aml | 424 | * FUNCTION: acpi_ps_parse_aml |
1145 | * | 425 | * |
1146 | * PARAMETERS: walk_state - Current state | 426 | * PARAMETERS: walk_state - Current state |