aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psparse.c
diff options
context:
space:
mode:
authorRobert Moore <robert.moore@intel.com>2005-06-24 00:00:00 -0400
committerLen Brown <len.brown@intel.com>2005-07-13 23:45:36 -0400
commit73459f73e5d1602c59ebec114fc45185521353c1 (patch)
tree56c2183e345784d2be09c2f5d2530cf36221c55e /drivers/acpi/parser/psparse.c
parent88ac00f5a841dcfc5c682000f4a6add0add8caac (diff)
ACPICA 20050617-0624 from Bob Moore <robert.moore@intel.com>
ACPICA 20050617: Moved the object cache operations into the OS interface layer (OSL) to allow the host OS to handle these operations if desired (for example, the Linux OSL will invoke the slab allocator). This support is optional; the compile time define ACPI_USE_LOCAL_CACHE may be used to utilize the original cache code in the ACPI CA core. The new OSL interfaces are shown below. See utalloc.c for an example implementation, and acpiosxf.h for the exact interface definitions. Thanks to Alexey Starikovskiy. acpi_os_create_cache acpi_os_delete_cache acpi_os_purge_cache acpi_os_acquire_object acpi_os_release_object Modified the interfaces to acpi_os_acquire_lock and acpi_os_release_lock to return and restore a flags parameter. This fits better with many OS lock models. Note: the current execution state (interrupt handler or not) is no longer passed to these interfaces. If necessary, the OSL must determine this state by itself, a simple and fast operation. Thanks to Alexey Starikovskiy. Fixed a problem in the ACPI table handling where a valid XSDT was assumed present if the revision of the RSDP was 2 or greater. According to the ACPI specification, the XSDT is optional in all cases, and the table manager therefore now checks for both an RSDP >=2 and a valid XSDT pointer. Otherwise, the RSDT pointer is used. Some ACPI 2.0 compliant BIOSs contain only the RSDT. Fixed an interpreter problem with the Mid() operator in the case of an input string where the resulting output string is of zero length. It now correctly returns a valid, null terminated string object instead of a string object with a null pointer. Fixed a problem with the control method argument handling to allow a store to an Arg object that already contains an object of type Device. The Device object is now correctly overwritten. Previously, an error was returned. ACPICA 20050624: Modified the new OSL cache interfaces to use ACPI_CACHE_T as the type for the host-defined cache object. This allows the OSL implementation to define and type this object in any manner desired, simplifying the OSL implementation. For example, ACPI_CACHE_T is defined as kmem_cache_t for Linux, and should be defined in the OS-specific header file for other operating systems as required. Changed the interface to AcpiOsAcquireObject to directly return the requested object as the function return (instead of ACPI_STATUS.) This change was made for performance reasons, since this is the purpose of the interface in the first place. acpi_os_acquire_object is now similar to the acpi_os_allocate interface. Thanks to Alexey Starikovskiy. Modified the initialization sequence in acpi_initialize_subsystem to call the OSL interface acpi_osl_initialize first, before any local initialization. This change was required because the global initialization now calls OSL interfaces. Restructured the code base to split some files because of size and/or because the code logically belonged in a separate file. New files are listed below. utilities/utcache.c /* Local cache interfaces */ utilities/utmutex.c /* Local mutex support */ utilities/utstate.c /* State object support */ parser/psloop.c /* Main AML parse loop */ Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/parser/psparse.c')
-rw-r--r--drivers/acpi/parser/psparse.c728
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
65static u32 acpi_gbl_depth = 0;
66
67/* Local prototypes */
68
69static acpi_status
70acpi_ps_complete_this_op (
71 struct acpi_walk_state *walk_state,
72 union acpi_parse_object *op);
73
74static acpi_status
75acpi_ps_next_parse_state (
76 struct acpi_walk_state *walk_state,
77 union acpi_parse_object *op,
78 acpi_status callback_status);
79
80static acpi_status
81acpi_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
161static acpi_status 141acpi_status
162acpi_ps_complete_this_op ( 142acpi_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
334static acpi_status 314acpi_status
335acpi_ps_next_parse_state ( 315acpi_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
455static acpi_status
456acpi_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
928close_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