2 /******************************************************************************
4 * Module Name: asltree - parse tree management
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2012, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
48 #include <contrib/dev/acpica/include/acapps.h>
51 #define _COMPONENT ACPI_COMPILER
52 ACPI_MODULE_NAME ("asltree")
54 /* Local prototypes */
56 static ACPI_PARSE_OBJECT *
65 /*******************************************************************************
67 * FUNCTION: TrGetNextNode
71 * RETURN: New parse node. Aborts on allocation failure
73 * DESCRIPTION: Allocate a new parse node for the parse tree. Bypass the local
74 * dynamic memory manager for performance reasons (This has a
75 * major impact on the speed of the compiler.)
77 ******************************************************************************/
79 static ACPI_PARSE_OBJECT *
84 if (Gbl_NodeCacheNext >= Gbl_NodeCacheLast)
86 Gbl_NodeCacheNext = UtLocalCalloc (sizeof (ACPI_PARSE_OBJECT) *
88 Gbl_NodeCacheLast = Gbl_NodeCacheNext + ASL_NODE_CACHE_SIZE;
91 return (Gbl_NodeCacheNext++);
95 /*******************************************************************************
97 * FUNCTION: TrAllocateNode
99 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
101 * RETURN: New parse node. Aborts on allocation failure
103 * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
105 ******************************************************************************/
111 ACPI_PARSE_OBJECT *Op;
114 Op = TrGetNextNode ();
116 Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
117 Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
118 Op->Asl.LineNumber = Gbl_CurrentLineNumber;
119 Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
120 Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
121 Op->Asl.Column = Gbl_CurrentColumn;
123 UtSetParseOpName (Op);
128 /*******************************************************************************
130 * FUNCTION: TrReleaseNode
132 * PARAMETERS: Op - Op to be released
136 * DESCRIPTION: "release" a node. In truth, nothing is done since the node
137 * is part of a larger buffer
139 ******************************************************************************/
143 ACPI_PARSE_OBJECT *Op)
150 /*******************************************************************************
152 * FUNCTION: TrUpdateNode
154 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
155 * Op - An existing parse node
157 * RETURN: The updated node
159 * DESCRIPTION: Change the parse opcode assigned to a node. Usually used to
160 * change an opcode to DEFAULT_ARG so that the node is ignored
161 * during the code generation. Also used to set generic integers
162 * to a specific size (8, 16, 32, or 64 bits)
164 ******************************************************************************/
169 ACPI_PARSE_OBJECT *Op)
177 DbgPrint (ASL_PARSE_OUTPUT,
178 "\nUpdateNode: Old - %s, New - %s\n\n",
179 UtGetOpName (Op->Asl.ParseOpcode),
180 UtGetOpName (ParseOpcode));
182 /* Assign new opcode and name */
184 if (Op->Asl.ParseOpcode == PARSEOP_ONES)
188 case PARSEOP_BYTECONST:
189 Op->Asl.Value.Integer = 0xFF;
192 case PARSEOP_WORDCONST:
193 Op->Asl.Value.Integer = 0xFFFF;
196 case PARSEOP_DWORDCONST:
197 Op->Asl.Value.Integer = 0xFFFFFFFF;
201 /* Don't care about others, don't need to check QWORD */
206 Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
207 UtSetParseOpName (Op);
210 * For the BYTE, WORD, and DWORD constants, make sure that the integer
211 * that was passed in will actually fit into the data type
215 case PARSEOP_BYTECONST:
216 Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX);
219 case PARSEOP_WORDCONST:
220 Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX);
223 case PARSEOP_DWORDCONST:
224 Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX);
228 /* Don't care about others, don't need to check QWORD */
236 /*******************************************************************************
238 * FUNCTION: TrGetNodeFlagName
240 * PARAMETERS: Flags - Flags word to be decoded
242 * RETURN: Name string. Always returns a valid string pointer.
244 * DESCRIPTION: Decode a flags word
246 ******************************************************************************/
256 return ("NODE_VISITED");
258 case NODE_AML_PACKAGE:
259 return ("NODE_AML_PACKAGE");
262 return ("NODE_IS_TARGET");
264 case NODE_IS_RESOURCE_DESC:
265 return ("NODE_IS_RESOURCE_DESC");
267 case NODE_IS_RESOURCE_FIELD:
268 return ("NODE_IS_RESOURCE_FIELD");
270 case NODE_HAS_NO_EXIT:
271 return ("NODE_HAS_NO_EXIT");
273 case NODE_IF_HAS_NO_EXIT:
274 return ("NODE_IF_HAS_NO_EXIT");
276 case NODE_NAME_INTERNALIZED:
277 return ("NODE_NAME_INTERNALIZED");
279 case NODE_METHOD_NO_RETVAL:
280 return ("NODE_METHOD_NO_RETVAL");
282 case NODE_METHOD_SOME_NO_RETVAL:
283 return ("NODE_METHOD_SOME_NO_RETVAL");
285 case NODE_RESULT_NOT_USED:
286 return ("NODE_RESULT_NOT_USED");
288 case NODE_METHOD_TYPED:
289 return ("NODE_METHOD_TYPED");
291 case NODE_COMPILE_TIME_CONST:
292 return ("NODE_COMPILE_TIME_CONST");
294 case NODE_IS_TERM_ARG:
295 return ("NODE_IS_TERM_ARG");
297 case NODE_WAS_ONES_OP:
298 return ("NODE_WAS_ONES_OP");
300 case NODE_IS_NAME_DECLARATION:
301 return ("NODE_IS_NAME_DECLARATION");
304 return ("Multiple Flags (or unknown flag) set");
309 /*******************************************************************************
311 * FUNCTION: TrSetNodeFlags
313 * PARAMETERS: Op - An existing parse node
314 * Flags - New flags word
316 * RETURN: The updated parser op
318 * DESCRIPTION: Set bits in the node flags word. Will not clear bits, only set
320 ******************************************************************************/
324 ACPI_PARSE_OBJECT *Op,
328 DbgPrint (ASL_PARSE_OUTPUT,
329 "\nSetNodeFlags: Op %p, %8.8X %s\n\n", Op, Flags,
330 TrGetNodeFlagName (Flags));
337 Op->Asl.CompileFlags |= Flags;
343 /*******************************************************************************
345 * FUNCTION: TrSetEndLineNumber
347 * PARAMETERS: Op - An existing parse node
351 * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
352 * parse node to the current line numbers.
354 ******************************************************************************/
358 ACPI_PARSE_OBJECT *Op)
361 /* If the end line # is already set, just return */
368 Op->Asl.EndLine = Gbl_CurrentLineNumber;
369 Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber;
373 /*******************************************************************************
375 * FUNCTION: TrCreateLeafNode
377 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
379 * RETURN: Pointer to the new node. Aborts on allocation failure
381 * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
382 * assigned to the node)
384 ******************************************************************************/
390 ACPI_PARSE_OBJECT *Op;
393 Op = TrAllocateNode (ParseOpcode);
395 DbgPrint (ASL_PARSE_OUTPUT,
396 "\nCreateLeafNode Ln/Col %u/%u NewNode %p Op %s\n\n",
397 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode));
403 /*******************************************************************************
405 * FUNCTION: TrCreateConstantLeafNode
407 * PARAMETERS: ParseOpcode - The constant opcode
409 * RETURN: Pointer to the new node. Aborts on allocation failure
411 * DESCRIPTION: Create a leaf node (no children or peers) for one of the
412 * special constants - __LINE__, __FILE__, and __DATE__.
414 * Note: An implemenation of __FUNC__ cannot happen here because we don't
415 * have a full parse tree at this time and cannot find the parent control
416 * method. If it is ever needed, __FUNC__ must be implemented later, after
417 * the parse tree has been fully constructed.
419 ******************************************************************************/
422 TrCreateConstantLeafNode (
425 ACPI_PARSE_OBJECT *Op = NULL;
427 char *StaticTimeString;
435 case PARSEOP___LINE__:
436 Op = TrAllocateNode (PARSEOP_INTEGER);
437 Op->Asl.Value.Integer = Op->Asl.LineNumber;
440 case PARSEOP___PATH__:
441 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
443 /* Op.Asl.Filename contains the full pathname to the file */
445 Op->Asl.Value.String = Op->Asl.Filename;
448 case PARSEOP___FILE__:
449 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
451 /* Get the simple filename from the full path */
453 FlSplitInputPathname (Op->Asl.Filename, &Path, &Filename);
455 Op->Asl.Value.String = Filename;
458 case PARSEOP___DATE__:
459 Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
461 /* Get a copy of the current time */
463 CurrentTime = time (NULL);
464 StaticTimeString = ctime (&CurrentTime);
465 TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
466 strcpy (TimeString, StaticTimeString);
468 TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
469 Op->Asl.Value.String = TimeString;
472 default: /* This would be an internal error */
476 DbgPrint (ASL_PARSE_OUTPUT,
477 "\nCreateConstantLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X ",
478 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
479 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
484 /*******************************************************************************
486 * FUNCTION: TrCreateValuedLeafNode
488 * PARAMETERS: ParseOpcode - New opcode to be assigned to the node
489 * Value - Value to be assigned to the node
491 * RETURN: Pointer to the new node. Aborts on allocation failure
493 * DESCRIPTION: Create a leaf node (no children or peers) with a value
496 ******************************************************************************/
499 TrCreateValuedLeafNode (
503 ACPI_PARSE_OBJECT *Op;
506 Op = TrAllocateNode (ParseOpcode);
508 DbgPrint (ASL_PARSE_OUTPUT,
509 "\nCreateValuedLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X ",
510 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
511 ACPI_FORMAT_UINT64 (Value));
512 Op->Asl.Value.Integer = Value;
516 case PARSEOP_STRING_LITERAL:
517 DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
520 case PARSEOP_NAMESEG:
521 DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
524 case PARSEOP_NAMESTRING:
525 DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
529 DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
533 DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
536 case PARSEOP_INTEGER:
537 DbgPrint (ASL_PARSE_OUTPUT, "INTEGER");
544 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
549 /*******************************************************************************
551 * FUNCTION: TrCreateNode
553 * PARAMETERS: ParseOpcode - Opcode to be assigned to the node
554 * NumChildren - Number of children to follow
555 * ... - A list of child nodes to link to the new
556 * node. NumChildren long.
558 * RETURN: Pointer to the new node. Aborts on allocation failure
560 * DESCRIPTION: Create a new parse node and link together a list of child
561 * nodes underneath the new node.
563 ******************************************************************************/
571 ACPI_PARSE_OBJECT *Op;
572 ACPI_PARSE_OBJECT *Child;
573 ACPI_PARSE_OBJECT *PrevChild;
579 va_start (ap, NumChildren);
581 /* Allocate one new node */
583 Op = TrAllocateNode (ParseOpcode);
585 DbgPrint (ASL_PARSE_OUTPUT,
586 "\nCreateNode Ln/Col %u/%u NewParent %p Child %u Op %s ",
587 Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode));
589 /* Some extra debug output based on the parse opcode */
593 case PARSEOP_DEFINITIONBLOCK:
595 DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
598 case PARSEOP_OPERATIONREGION:
599 DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
603 DbgPrint (ASL_PARSE_OUTPUT, "OR->");
607 /* Nothing to do for other opcodes */
611 /* Link the new node to its children */
615 for (i = 0; i < NumChildren; i++)
617 /* Get the next child */
619 Child = va_arg (ap, ACPI_PARSE_OBJECT *);
620 DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
623 * If child is NULL, this means that an optional argument
624 * was omitted. We must create a placeholder with a special
625 * opcode (DEFAULT_ARG) so that the code generator will know
626 * that it must emit the correct default for this argument
630 Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
633 /* Link first child to parent */
638 Op->Asl.Child = Child;
641 /* Point all children to parent */
643 Child->Asl.Parent = Op;
645 /* Link children in a peer list */
649 PrevChild->Asl.Next = Child;
653 * This child might be a list, point all nodes in the list
656 while (Child->Asl.Next)
658 Child = Child->Asl.Next;
659 Child->Asl.Parent = Op;
666 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
671 /*******************************************************************************
673 * FUNCTION: TrLinkChildren
675 * PARAMETERS: Op - An existing parse node
676 * NumChildren - Number of children to follow
677 * ... - A list of child nodes to link to the new
678 * node. NumChildren long.
680 * RETURN: The updated (linked) node
682 * DESCRIPTION: Link a group of nodes to an existing parse node
684 ******************************************************************************/
688 ACPI_PARSE_OBJECT *Op,
692 ACPI_PARSE_OBJECT *Child;
693 ACPI_PARSE_OBJECT *PrevChild;
699 va_start (ap, NumChildren);
702 TrSetEndLineNumber (Op);
704 DbgPrint (ASL_PARSE_OUTPUT,
705 "\nLinkChildren Line [%u to %u] NewParent %p Child %u Op %s ",
706 Op->Asl.LineNumber, Op->Asl.EndLine,
707 Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode));
709 switch (Op->Asl.ParseOpcode)
711 case PARSEOP_DEFINITIONBLOCK:
713 DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
716 case PARSEOP_OPERATIONREGION:
717 DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
721 DbgPrint (ASL_PARSE_OUTPUT, "OR->");
725 /* Nothing to do for other opcodes */
729 /* Link the new node to it's children */
733 for (i = 0; i < NumChildren; i++)
735 Child = va_arg (ap, ACPI_PARSE_OBJECT *);
737 if ((Child == PrevChild) && (Child != NULL))
739 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child,
740 "Child node list invalid");
744 DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
747 * If child is NULL, this means that an optional argument
748 * was omitted. We must create a placeholder with a special
749 * opcode (DEFAULT_ARG) so that the code generator will know
750 * that it must emit the correct default for this argument
754 Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
757 /* Link first child to parent */
762 Op->Asl.Child = Child;
765 /* Point all children to parent */
767 Child->Asl.Parent = Op;
769 /* Link children in a peer list */
773 PrevChild->Asl.Next = Child;
777 * This child might be a list, point all nodes in the list
780 while (Child->Asl.Next)
782 Child = Child->Asl.Next;
783 Child->Asl.Parent = Op;
789 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
794 /*******************************************************************************
796 * FUNCTION: TrLinkPeerNode
798 * PARAMETERS: Op1 - First peer
801 * RETURN: Op1 or the non-null node.
803 * DESCRIPTION: Link two nodes as peers. Handles cases where one peer is null.
805 ******************************************************************************/
809 ACPI_PARSE_OBJECT *Op1,
810 ACPI_PARSE_OBJECT *Op2)
812 ACPI_PARSE_OBJECT *Next;
815 DbgPrint (ASL_PARSE_OUTPUT,
816 "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n",
817 Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL,
818 Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL);
821 if ((!Op1) && (!Op2))
823 DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n");
827 /* If one of the nodes is null, just return the non-null node */
841 DbgPrint (ASL_DEBUG_OUTPUT,
842 "\n\n************* Internal error, linking node to itself %p\n\n\n",
844 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1,
845 "Linking node to itself");
849 Op1->Asl.Parent = Op2->Asl.Parent;
852 * Op 1 may already have a peer list (such as an IF/ELSE pair),
853 * so we must walk to the end of the list and attach the new
857 while (Next->Asl.Next)
859 Next = Next->Asl.Next;
862 Next->Asl.Next = Op2;
867 /*******************************************************************************
869 * FUNCTION: TrLinkPeerNodes
871 * PARAMETERS: NumPeers - The number of nodes in the list to follow
872 * ... - A list of nodes to link together as peers
874 * RETURN: The first node in the list (head of the peer list)
876 * DESCRIPTION: Link together an arbitrary number of peer nodes.
878 ******************************************************************************/
885 ACPI_PARSE_OBJECT *This;
886 ACPI_PARSE_OBJECT *Next;
889 ACPI_PARSE_OBJECT *Start;
892 DbgPrint (ASL_PARSE_OUTPUT,
893 "\nLinkPeerNodes: (%u) ", NumPeers);
895 va_start (ap, NumPeers);
896 This = va_arg (ap, ACPI_PARSE_OBJECT *);
902 for (i = 0; i < (NumPeers -1); i++)
904 DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This);
906 while (This->Asl.Next)
908 This = This->Asl.Next;
911 /* Get another peer node */
913 Next = va_arg (ap, ACPI_PARSE_OBJECT *);
916 Next = TrAllocateNode (PARSEOP_DEFAULT_ARG);
919 /* link new node to the current node */
921 This->Asl.Next = Next;
926 DbgPrint (ASL_PARSE_OUTPUT,"\n\n");
931 /*******************************************************************************
933 * FUNCTION: TrLinkChildNode
935 * PARAMETERS: Op1 - Parent node
936 * Op2 - Op to become a child
938 * RETURN: The parent node
940 * DESCRIPTION: Link two nodes together as a parent and child
942 ******************************************************************************/
946 ACPI_PARSE_OBJECT *Op1,
947 ACPI_PARSE_OBJECT *Op2)
949 ACPI_PARSE_OBJECT *Next;
952 DbgPrint (ASL_PARSE_OUTPUT,
953 "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n",
954 Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL,
955 Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL);
962 Op1->Asl.Child = Op2;
964 /* Set the child and all peers of the child to point to the parent */
969 Next->Asl.Parent = Op1;
970 Next = Next->Asl.Next;
977 /*******************************************************************************
979 * FUNCTION: TrWalkParseTree
981 * PARAMETERS: Visitation - Type of walk
982 * DescendingCallback - Called during tree descent
983 * AscendingCallback - Called during tree ascent
984 * Context - To be passed to the callbacks
986 * RETURN: Status from callback(s)
988 * DESCRIPTION: Walk the entire parse tree.
990 ******************************************************************************/
994 ACPI_PARSE_OBJECT *Op,
996 ASL_WALK_CALLBACK DescendingCallback,
997 ASL_WALK_CALLBACK AscendingCallback,
1001 BOOLEAN NodePreviouslyVisited;
1002 ACPI_PARSE_OBJECT *StartOp = Op;
1012 NodePreviouslyVisited = FALSE;
1016 case ASL_WALK_VISIT_DOWNWARD:
1020 if (!NodePreviouslyVisited)
1022 /* Let the callback process the node. */
1024 Status = DescendingCallback (Op, Level, Context);
1025 if (ACPI_SUCCESS (Status))
1027 /* Visit children first, once */
1036 else if (Status != AE_CTRL_DEPTH)
1038 /* Exit immediately on any error */
1044 /* Terminate walk at start op */
1051 /* No more children, visit peers */
1056 NodePreviouslyVisited = FALSE;
1060 /* No children or peers, re-visit parent */
1066 Op = Op->Asl.Parent;
1067 NodePreviouslyVisited = TRUE;
1073 case ASL_WALK_VISIT_UPWARD:
1077 /* Visit leaf node (no children) or parent node on return trip */
1079 if ((!Op->Asl.Child) ||
1080 (NodePreviouslyVisited))
1082 /* Let the callback process the node. */
1084 Status = AscendingCallback (Op, Level, Context);
1085 if (ACPI_FAILURE (Status))
1092 /* Visit children first, once */
1099 /* Terminate walk at start op */
1106 /* No more children, visit peers */
1111 NodePreviouslyVisited = FALSE;
1115 /* No children or peers, re-visit parent */
1121 Op = Op->Asl.Parent;
1122 NodePreviouslyVisited = TRUE;
1128 case ASL_WALK_VISIT_TWICE:
1132 if (NodePreviouslyVisited)
1134 Status = AscendingCallback (Op, Level, Context);
1135 if (ACPI_FAILURE (Status))
1142 /* Let the callback process the node. */
1144 Status = DescendingCallback (Op, Level, Context);
1145 if (ACPI_SUCCESS (Status))
1147 /* Visit children first, once */
1156 else if (Status != AE_CTRL_DEPTH)
1158 /* Exit immediately on any error */
1164 /* Terminate walk at start op */
1171 /* No more children, visit peers */
1176 NodePreviouslyVisited = FALSE;
1180 /* No children or peers, re-visit parent */
1186 Op = Op->Asl.Parent;
1187 NodePreviouslyVisited = TRUE;
1193 /* No other types supported */
1197 /* If we get here, the walk completed with no errors */