checkdirs() was being passed the wrong mount point, resulting in a panic
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050309 / interpreter / parser / psparse.c
1 /******************************************************************************
2  *
3  * Module Name: psparse - Parser top level AML parse routines
4  *              $Revision: 148 $
5  *
6  *****************************************************************************/
7
8 /******************************************************************************
9  *
10  * 1. Copyright Notice
11  *
12  * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
13  * All rights reserved.
14  *
15  * 2. License
16  *
17  * 2.1. This is your license from Intel Corp. under its intellectual property
18  * rights.  You may have additional license terms from the party that provided
19  * you this software, covering your right to use that party's intellectual
20  * property rights.
21  *
22  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23  * copy of the source code appearing in this file ("Covered Code") an
24  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25  * base code distributed originally by Intel ("Original Intel Code") to copy,
26  * make derivatives, distribute, use and display any portion of the Covered
27  * Code in any form, with the right to sublicense such rights; and
28  *
29  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30  * license (with the right to sublicense), under only those claims of Intel
31  * patents that are infringed by the Original Intel Code, to make, use, sell,
32  * offer to sell, and import the Covered Code and derivative works thereof
33  * solely to the minimum extent necessary to exercise the above copyright
34  * license, and in no event shall the patent license extend to any additions
35  * to or modifications of the Original Intel Code.  No other license or right
36  * is granted directly or by implication, estoppel or otherwise;
37  *
38  * The above copyright and patent license is granted only if the following
39  * conditions are met:
40  *
41  * 3. Conditions
42  *
43  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44  * Redistribution of source code of any substantial portion of the Covered
45  * Code or modification with rights to further distribute source must include
46  * the above Copyright Notice, the above License, this list of Conditions,
47  * and the following Disclaimer and Export Compliance provision.  In addition,
48  * Licensee must cause all Covered Code to which Licensee contributes to
49  * contain a file documenting the changes Licensee made to create that Covered
50  * Code and the date of any change.  Licensee must include in that file the
51  * documentation of any changes made by any predecessor Licensee.  Licensee
52  * must include a prominent statement that the modification is derived,
53  * directly or indirectly, from Original Intel Code.
54  *
55  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56  * Redistribution of source code of any substantial portion of the Covered
57  * Code or modification without rights to further distribute source must
58  * include the following Disclaimer and Export Compliance provision in the
59  * documentation and/or other materials provided with distribution.  In
60  * addition, Licensee may not authorize further sublicense of source of any
61  * portion of the Covered Code, and must include terms to the effect that the
62  * license from Licensee to its licensee is limited to the intellectual
63  * property embodied in the software Licensee provides to its licensee, and
64  * not to intellectual property embodied in modifications its licensee may
65  * make.
66  *
67  * 3.3. Redistribution of Executable. Redistribution in executable form of any
68  * substantial portion of the Covered Code or modification must reproduce the
69  * above Copyright Notice, and the following Disclaimer and Export Compliance
70  * provision in the documentation and/or other materials provided with the
71  * distribution.
72  *
73  * 3.4. Intel retains all right, title, and interest in and to the Original
74  * Intel Code.
75  *
76  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77  * Intel shall be used in advertising or otherwise to promote the sale, use or
78  * other dealings in products derived from or relating to the Covered Code
79  * without prior written authorization from Intel.
80  *
81  * 4. Disclaimer and Export Compliance
82  *
83  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89  * PARTICULAR PURPOSE.
90  *
91  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98  * LIMITED REMEDY.
99  *
100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
101  * software or system incorporating such software without first obtaining any
102  * required license or other approval from the U. S. Department of Commerce or
103  * any other agency or department of the United States Government.  In the
104  * event Licensee exports any such software from the United States or
105  * re-exports any such software from a foreign destination, Licensee shall
106  * ensure that the distribution and export/re-export of the software is in
107  * compliance with all laws, regulations, orders, or other restrictions of the
108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109  * any of its subsidiaries will export/re-export any technical data, process,
110  * software, or service, directly or indirectly, to any country for which the
111  * United States government or any agency thereof requires an export license,
112  * other governmental approval, or letter of assurance, without first obtaining
113  * such license, approval or letter.
114  *
115  *****************************************************************************/
116
117
118 /*
119  * Parse the AML and build an operation tree as most interpreters,
120  * like Perl, do.  Parsing is done by hand rather than with a YACC
121  * generated parser to tightly constrain stack and dynamic memory
122  * usage.  At the same time, parsing is kept flexible and the code
123  * fairly compact by parsing based on a list of AML opcode
124  * templates in AmlOpInfo[]
125  */
126
127 #include "acpi.h"
128 #include "acparser.h"
129 #include "acdispat.h"
130 #include "amlcode.h"
131 #include "acnamesp.h"
132 #include "acinterp.h"
133
134 #define _COMPONENT          ACPI_PARSER
135         ACPI_MODULE_NAME    ("psparse")
136
137
138 static UINT32               AcpiGbl_Depth = 0;
139
140
141 /*******************************************************************************
142  *
143  * FUNCTION:    AcpiPsGetOpcodeSize
144  *
145  * PARAMETERS:  Opcode          - An AML opcode
146  *
147  * RETURN:      Size of the opcode, in bytes (1 or 2)
148  *
149  * DESCRIPTION: Get the size of the current opcode.
150  *
151  ******************************************************************************/
152
153 UINT32
154 AcpiPsGetOpcodeSize (
155     UINT32                  Opcode)
156 {
157
158     /* Extended (2-byte) opcode if > 255 */
159
160     if (Opcode > 0x00FF)
161     {
162         return (2);
163     }
164
165     /* Otherwise, just a single byte opcode */
166
167     return (1);
168 }
169
170
171 /*******************************************************************************
172  *
173  * FUNCTION:    AcpiPsPeekOpcode
174  *
175  * PARAMETERS:  ParserState         - A parser state object
176  *
177  * RETURN:      Status
178  *
179  * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
180  *
181  ******************************************************************************/
182
183 UINT16
184 AcpiPsPeekOpcode (
185     ACPI_PARSE_STATE        *ParserState)
186 {
187     UINT8                   *Aml;
188     UINT16                  Opcode;
189
190
191     Aml = ParserState->Aml;
192     Opcode = (UINT16) ACPI_GET8 (Aml);
193
194
195     if (Opcode == AML_EXTOP)
196     {
197         /* Extended opcode */
198
199         Aml++;
200         Opcode = (UINT16) ((Opcode << 8) | ACPI_GET8 (Aml));
201     }
202
203     return (Opcode);
204 }
205
206
207 /*******************************************************************************
208  *
209  * FUNCTION:    AcpiPsCompleteThisOp
210  *
211  * PARAMETERS:  WalkState       - Current State
212  *              Op              - Op to complete
213  *
214  * RETURN:      None.
215  *
216  * DESCRIPTION: Perform any cleanup at the completion of an Op.
217  *
218  ******************************************************************************/
219
220 void
221 AcpiPsCompleteThisOp (
222     ACPI_WALK_STATE         *WalkState,
223     ACPI_PARSE_OBJECT       *Op)
224 {
225     ACPI_PARSE_OBJECT       *Prev;
226     ACPI_PARSE_OBJECT       *Next;
227     const ACPI_OPCODE_INFO  *ParentInfo;
228     ACPI_PARSE_OBJECT       *ReplacementOp = NULL;
229
230
231     ACPI_FUNCTION_TRACE_PTR ("PsCompleteThisOp", Op);
232
233
234     /* Check for null Op, can happen if AML code is corrupt */
235
236     if (!Op)
237     {
238         return_VOID;
239     }
240
241     /* Delete this op and the subtree below it if asked to */
242
243     if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
244          (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT))
245     {
246         return_VOID;
247     }
248
249     /* Make sure that we only delete this subtree */
250
251     if (Op->Common.Parent)
252     {
253         /*
254          * Check if we need to replace the operator and its subtree
255          * with a return value op (placeholder op)
256          */
257         ParentInfo  = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
258
259         switch (ParentInfo->Class)
260         {
261         case AML_CLASS_CONTROL:
262             break;
263
264         case AML_CLASS_CREATE:
265
266             /*
267              * These opcodes contain TermArg operands.  The current
268              * op must be replaced by a placeholder return op
269              */
270             ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
271             if (!ReplacementOp)
272             {
273                 goto Cleanup;
274             }
275             break;
276
277         case AML_CLASS_NAMED_OBJECT:
278
279             /*
280              * These opcodes contain TermArg operands.  The current
281              * op must be replaced by a placeholder return op
282              */
283             if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP)       ||
284                 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP)  ||
285                 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP)       ||
286                 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP)      ||
287                 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
288             {
289                 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
290                 if (!ReplacementOp)
291                 {
292                     goto Cleanup;
293                 }
294             }
295
296             if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
297                 (WalkState->DescendingCallback != AcpiDsExecBeginOp))
298
299             {
300                 if ((Op->Common.AmlOpcode == AML_BUFFER_OP) ||
301                     (Op->Common.AmlOpcode == AML_PACKAGE_OP) ||
302                     (Op->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
303                 {
304                     ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode);
305                     if (!ReplacementOp)
306                     {
307                         goto Cleanup;
308                     }
309
310                     ReplacementOp->Named.Data = Op->Named.Data;
311                     ReplacementOp->Named.Length = Op->Named.Length;
312                 }
313             }
314             break;
315
316         default:
317             ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
318             if (!ReplacementOp)
319             {
320                 goto Cleanup;
321             }
322         }
323
324         /* We must unlink this op from the parent tree */
325
326         Prev = Op->Common.Parent->Common.Value.Arg;
327         if (Prev == Op)
328         {
329             /* This op is the first in the list */
330
331             if (ReplacementOp)
332             {
333                 ReplacementOp->Common.Parent        = Op->Common.Parent;
334                 ReplacementOp->Common.Value.Arg     = NULL;
335                 ReplacementOp->Common.Node          = Op->Common.Node;
336                 Op->Common.Parent->Common.Value.Arg = ReplacementOp;
337                 ReplacementOp->Common.Next          = Op->Common.Next;
338             }
339             else
340             {
341                 Op->Common.Parent->Common.Value.Arg = Op->Common.Next;
342             }
343         }
344
345         /* Search the parent list */
346
347         else while (Prev)
348         {
349             /* Traverse all siblings in the parent's argument list */
350
351             Next = Prev->Common.Next;
352             if (Next == Op)
353             {
354                 if (ReplacementOp)
355                 {
356                     ReplacementOp->Common.Parent    = Op->Common.Parent;
357                     ReplacementOp->Common.Value.Arg = NULL;
358                     ReplacementOp->Common.Node      = Op->Common.Node;
359                     Prev->Common.Next               = ReplacementOp;
360                     ReplacementOp->Common.Next      = Op->Common.Next;
361                     Next = NULL;
362                 }
363                 else
364                 {
365                     Prev->Common.Next = Op->Common.Next;
366                     Next = NULL;
367                 }
368             }
369
370             Prev = Next;
371         }
372     }
373
374
375 Cleanup:
376
377     /* Now we can actually delete the subtree rooted at op */
378
379     AcpiPsDeleteParseTree (Op);
380     return_VOID;
381 }
382
383
384 /*******************************************************************************
385  *
386  * FUNCTION:    AcpiPsNextParseState
387  *
388  * PARAMETERS:  ParserState         - Current parser state object
389  *
390  * RETURN:      Status
391  *
392  * DESCRIPTION: Update the parser state based upon the return exception from
393  *              the parser callback.
394  *
395  ******************************************************************************/
396
397 ACPI_STATUS
398 AcpiPsNextParseState (
399     ACPI_WALK_STATE         *WalkState,
400     ACPI_PARSE_OBJECT       *Op,
401     ACPI_STATUS             CallbackStatus)
402 {
403     ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
404     ACPI_STATUS             Status = AE_CTRL_PENDING;
405
406
407     ACPI_FUNCTION_TRACE_PTR ("PsNextParseState", Op);
408
409
410     switch (CallbackStatus)
411     {
412     case AE_CTRL_TERMINATE:
413
414         /*
415          * A control method was terminated via a RETURN statement.
416          * The walk of this method is complete.
417          */
418         ParserState->Aml = ParserState->AmlEnd;
419         Status = AE_CTRL_TERMINATE;
420         break;
421
422
423     case AE_CTRL_BREAK:
424
425         ParserState->Aml = WalkState->AmlLastWhile;
426         WalkState->ControlState->Common.Value = FALSE;
427         Status = AE_CTRL_BREAK;
428         break;
429
430     case AE_CTRL_CONTINUE:
431
432
433         ParserState->Aml = WalkState->AmlLastWhile;
434         Status = AE_CTRL_CONTINUE;
435         break;
436
437     case AE_CTRL_PENDING:
438
439         ParserState->Aml = WalkState->AmlLastWhile;
440         break;
441
442 #if 0
443     case AE_CTRL_SKIP:
444
445         ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
446         Status = AE_OK;
447         break;
448 #endif
449
450     case AE_CTRL_TRUE:
451
452         /*
453          * Predicate of an IF was true, and we are at the matching ELSE.
454          * Just close out this package
455          */
456         ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);
457         break;
458
459
460     case AE_CTRL_FALSE:
461
462         /*
463          * Either an IF/WHILE Predicate was false or we encountered a BREAK
464          * opcode.  In both cases, we do not execute the rest of the
465          * package;  We simply close out the parent (finishing the walk of
466          * this branch of the tree) and continue execution at the parent
467          * level.
468          */
469         ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
470
471         /* In the case of a BREAK, just force a predicate (if any) to FALSE */
472
473         WalkState->ControlState->Common.Value = FALSE;
474         Status = AE_CTRL_END;
475         break;
476
477
478     case AE_CTRL_TRANSFER:
479
480         /*
481          * A method call (invocation) -- transfer control
482          */
483         Status = AE_CTRL_TRANSFER;
484         WalkState->PrevOp = Op;
485         WalkState->MethodCallOp = Op;
486         WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;
487
488         /* Will return value (if any) be used by the caller? */
489
490         WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
491         break;
492
493
494     default:
495         Status = CallbackStatus;
496         if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
497         {
498             Status = AE_OK;
499         }
500         break;
501     }
502
503     return_ACPI_STATUS (Status);
504 }
505
506
507 /*******************************************************************************
508  *
509  * FUNCTION:    AcpiPsParseLoop
510  *
511  * PARAMETERS:  ParserState         - Current parser state object
512  *
513  * RETURN:      Status
514  *
515  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
516  *              a tree of ops.
517  *
518  ******************************************************************************/
519
520 ACPI_STATUS
521 AcpiPsParseLoop (
522     ACPI_WALK_STATE         *WalkState)
523 {
524     ACPI_STATUS             Status = AE_OK;
525     ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
526     ACPI_PARSE_OBJECT       *Arg = NULL;
527     ACPI_PARSE_OBJECT       *PreOp = NULL;
528     ACPI_PARSE_STATE        *ParserState;
529     UINT8                   *AmlOpStart = NULL;
530
531
532     ACPI_FUNCTION_TRACE_PTR ("PsParseLoop", WalkState);
533
534     if (WalkState->DescendingCallback == NULL)
535     {
536         return_ACPI_STATUS (AE_BAD_PARAMETER);
537     }
538
539     ParserState = &WalkState->ParserState;
540     WalkState->ArgTypes = 0;
541
542 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
543     if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
544     {
545         /* We are restarting a preempted control method */
546
547         if (AcpiPsHasCompletedScope (ParserState))
548         {
549             /*
550              * We must check if a predicate to an IF or WHILE statement
551              * was just completed
552              */
553             if ((ParserState->Scope->ParseScope.Op) &&
554                ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
555                 (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
556                 (WalkState->ControlState) &&
557                 (WalkState->ControlState->Common.State ==
558                     ACPI_CONTROL_PREDICATE_EXECUTING))
559             {
560                 /*
561                  * A predicate was just completed, get the value of the
562                  * predicate and branch based on that value
563                  */
564                 WalkState->Op = NULL;
565                 Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
566                 if (ACPI_FAILURE (Status) &&
567                     ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
568                 {
569                     if (Status == AE_AML_NO_RETURN_VALUE)
570                     {
571                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
572                             "Invoked method did not return a value, %s\n",
573                             AcpiFormatException (Status)));
574
575                     }
576                     ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n",
577                         AcpiFormatException (Status)));
578                     return_ACPI_STATUS (Status);
579                 }
580
581                 Status = AcpiPsNextParseState (WalkState, Op, Status);
582             }
583
584             AcpiPsPopScope (ParserState, &Op,
585                 &WalkState->ArgTypes, &WalkState->ArgCount);
586             ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
587         }
588         else if (WalkState->PrevOp)
589         {
590             /* We were in the middle of an op */
591
592             Op = WalkState->PrevOp;
593             WalkState->ArgTypes = WalkState->PrevArgTypes;
594         }
595     }
596 #endif
597
598     /*
599      * Iterative parsing loop, while there is more aml to process:
600      */
601     while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
602     {
603         AmlOpStart = ParserState->Aml;
604         if (!Op)
605         {
606             /* Get the next opcode from the AML stream */
607
608             WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (ParserState->Aml,
609                                                            ParserState->AmlStart);
610             WalkState->Opcode    = AcpiPsPeekOpcode (ParserState);
611
612             /*
613              * First cut to determine what we have found:
614              * 1) A valid AML opcode
615              * 2) A name string
616              * 3) An unknown/invalid opcode
617              */
618             WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
619             switch (WalkState->OpInfo->Class)
620             {
621             case AML_CLASS_ASCII:
622             case AML_CLASS_PREFIX:
623                 /*
624                  * Starts with a valid prefix or ASCII char, this is a name
625                  * string.  Convert the bare name string to a namepath.
626                  */
627                 WalkState->Opcode = AML_INT_NAMEPATH_OP;
628                 WalkState->ArgTypes = ARGP_NAMESTRING;
629                 break;
630
631             case AML_CLASS_UNKNOWN:
632
633                 /* The opcode is unrecognized.  Just skip unknown opcodes */
634
635                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
636                     "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
637                     WalkState->Opcode, ParserState->Aml, WalkState->AmlOffset));
638
639                 ACPI_DUMP_BUFFER (ParserState->Aml, 128);
640
641                 /* Assume one-byte bad opcode */
642
643                 ParserState->Aml++;
644                 continue;
645
646             default:
647
648                 /* Found opcode info, this is a normal opcode */
649
650                 ParserState->Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
651                 WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
652                 break;
653             }
654
655             /* Create Op structure and append to parent's argument list */
656
657             if (WalkState->OpInfo->Flags & AML_NAMED)
658             {
659                 /* Allocate a new PreOp if necessary */
660
661                 if (!PreOp)
662                 {
663                     PreOp = AcpiPsAllocOp (WalkState->Opcode);
664                     if (!PreOp)
665                     {
666                         Status = AE_NO_MEMORY;
667                         goto CloseThisOp;
668                     }
669                 }
670
671                 PreOp->Common.Value.Arg = NULL;
672                 PreOp->Common.AmlOpcode = WalkState->Opcode;
673
674                 /*
675                  * Get and append arguments until we find the node that contains
676                  * the name (the type ARGP_NAME).
677                  */
678                 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
679                       (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
680                 {
681                     Status = AcpiPsGetNextArg (WalkState, ParserState,
682                                 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
683                     if (ACPI_FAILURE (Status))
684                     {
685                         goto CloseThisOp;
686                     }
687
688                     AcpiPsAppendArg (PreOp, Arg);
689                     INCREMENT_ARG_LIST (WalkState->ArgTypes);
690                 }
691
692                 /* Make sure that we found a NAME and didn't run out of arguments */
693
694                 if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
695                 {
696                     Status = AE_AML_NO_OPERAND;
697                     goto CloseThisOp;
698                 }
699
700                 /* We know that this arg is a name, move to next arg */
701
702                 INCREMENT_ARG_LIST (WalkState->ArgTypes);
703
704                 /*
705                  * Find the object.  This will either insert the object into
706                  * the namespace or simply look it up
707                  */
708                 WalkState->Op = NULL;
709
710                 Status = WalkState->DescendingCallback (WalkState, &Op);
711                 if (ACPI_FAILURE (Status))
712                 {
713                     ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n",
714                             AcpiFormatException (Status)));
715                     goto CloseThisOp;
716                 }
717
718                 if (Op == NULL)
719                 {
720                     continue;
721                 }
722
723                 Status = AcpiPsNextParseState (WalkState, Op, Status);
724                 if (Status == AE_CTRL_PENDING)
725                 {
726                     Status = AE_OK;
727                     goto CloseThisOp;
728                 }
729
730                 if (ACPI_FAILURE (Status))
731                 {
732                     goto CloseThisOp;
733                 }
734
735                 AcpiPsAppendArg (Op, PreOp->Common.Value.Arg);
736                 AcpiGbl_Depth++;
737
738                 if (Op->Common.AmlOpcode == AML_REGION_OP)
739                 {
740                     /*
741                      * Defer final parsing of an OperationRegion body,
742                      * because we don't have enough info in the first pass
743                      * to parse it correctly (i.e., there may be method
744                      * calls within the TermArg elements of the body.)
745                      *
746                      * However, we must continue parsing because
747                      * the opregion is not a standalone package --
748                      * we don't know where the end is at this point.
749                      *
750                      * (Length is unknown until parse of the body complete)
751                      */
752                     Op->Named.Data    = AmlOpStart;
753                     Op->Named.Length  = 0;
754                 }
755             }
756             else
757             {
758                 /* Not a named opcode, just allocate Op and append to parent */
759
760                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
761                 Op = AcpiPsAllocOp (WalkState->Opcode);
762                 if (!Op)
763                 {
764                     Status = AE_NO_MEMORY;
765                     goto CloseThisOp;
766                 }
767
768                 if (WalkState->OpInfo->Flags & AML_CREATE)
769                 {
770                     /*
771                      * Backup to beginning of CreateXXXfield declaration
772                      * BodyLength is unknown until we parse the body
773                      */
774                     Op->Named.Data    = AmlOpStart;
775                     Op->Named.Length  = 0;
776                 }
777
778                 AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op);
779
780                 if ((WalkState->DescendingCallback != NULL))
781                 {
782                     /*
783                      * Find the object.  This will either insert the object into
784                      * the namespace or simply look it up
785                      */
786                     WalkState->Op = Op;
787
788                     Status = WalkState->DescendingCallback (WalkState, &Op);
789                     Status = AcpiPsNextParseState (WalkState, Op, Status);
790                     if (Status == AE_CTRL_PENDING)
791                     {
792                         Status = AE_OK;
793                         goto CloseThisOp;
794                     }
795
796                     if (ACPI_FAILURE (Status))
797                     {
798                         goto CloseThisOp;
799                     }
800                 }
801             }
802
803             Op->Common.AmlOffset = WalkState->AmlOffset;
804
805             if (WalkState->OpInfo)
806             {
807                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
808                     "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
809                      (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name,
810                      Op, ParserState->Aml, Op->Common.AmlOffset));
811             }
812         }
813
814
815         /* Start ArgCount at zero because we don't know if there are any args yet */
816
817         WalkState->ArgCount  = 0;
818
819         if (WalkState->ArgTypes)   /* Are there any arguments that must be processed? */
820         {
821             /* Get arguments */
822
823             switch (Op->Common.AmlOpcode)
824             {
825             case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
826             case AML_WORD_OP:       /* AML_WORDDATA_ARG */
827             case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
828             case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
829             case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
830
831                 /* Fill in constant or string argument directly */
832
833                 AcpiPsGetNextSimpleArg (ParserState,
834                     GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
835                 break;
836
837             case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
838
839                 Status = AcpiPsGetNextNamepath (WalkState, ParserState, Op, 1);
840                 if (ACPI_FAILURE (Status))
841                 {
842                     goto CloseThisOp;
843                 }
844
845                 WalkState->ArgTypes = 0;
846                 break;
847
848             default:
849
850                 /* Op is not a constant or string, append each argument to the Op */
851
852                 while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
853                         !WalkState->ArgCount)
854                 {
855                     WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (ParserState->Aml,
856                                                                    ParserState->AmlStart);
857                     Status = AcpiPsGetNextArg (WalkState, ParserState,
858                                 GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
859                     if (ACPI_FAILURE (Status))
860                     {
861                         goto CloseThisOp;
862                     }
863
864                     if (Arg)
865                     {
866                         Arg->Common.AmlOffset = WalkState->AmlOffset;
867                         AcpiPsAppendArg (Op, Arg);
868                     }
869                     INCREMENT_ARG_LIST (WalkState->ArgTypes);
870                 }
871
872                 /* Special processing for certain opcodes */
873
874                 switch (Op->Common.AmlOpcode)
875                 {
876                 case AML_METHOD_OP:
877
878                     /*
879                      * Skip parsing of control method
880                      * because we don't have enough info in the first pass
881                      * to parse it correctly.
882                      *
883                      * Save the length and address of the body
884                      */
885                     Op->Named.Data   = ParserState->Aml;
886                     Op->Named.Length = (UINT32) (ParserState->PkgEnd - ParserState->Aml);
887
888                     /* Skip body of method */
889
890                     ParserState->Aml    = ParserState->PkgEnd;
891                     WalkState->ArgCount = 0;
892                     break;
893
894                 case AML_BUFFER_OP:
895                 case AML_PACKAGE_OP:
896                 case AML_VAR_PACKAGE_OP:
897
898                     if ((Op->Common.Parent) &&
899                         (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
900                         (WalkState->DescendingCallback != AcpiDsExecBeginOp))
901                     {
902                         /*
903                          * Skip parsing of Buffers and Packages
904                          * because we don't have enough info in the first pass
905                          * to parse them correctly.
906                          */
907                         Op->Named.Data   = AmlOpStart;
908                         Op->Named.Length = (UINT32) (ParserState->PkgEnd - AmlOpStart);
909
910                         /* Skip body */
911
912                         ParserState->Aml    = ParserState->PkgEnd;
913                         WalkState->ArgCount = 0;
914                     }
915                     break;
916
917                 case AML_WHILE_OP:
918
919                     if (WalkState->ControlState)
920                     {
921                         WalkState->ControlState->Control.PackageEnd = ParserState->PkgEnd;
922                     }
923                     break;
924
925                 default:
926
927                     /* No action for all other opcodes */
928                     break;
929                 }
930                 break;
931             }
932         }
933
934         /* Check for arguments that need to be processed */
935
936         if (WalkState->ArgCount)
937         {
938             /* There are arguments (complex ones), push Op and prepare for argument */
939
940             Status = AcpiPsPushScope (ParserState, Op,
941                         WalkState->ArgTypes, WalkState->ArgCount);
942             if (ACPI_FAILURE (Status))
943             {
944                 goto CloseThisOp;
945             }
946             Op = NULL;
947             continue;
948         }
949
950         /* All arguments have been processed -- Op is complete, prepare for next */
951
952         WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
953         if (WalkState->OpInfo->Flags & AML_NAMED)
954         {
955             if (AcpiGbl_Depth)
956             {
957                 AcpiGbl_Depth--;
958             }
959
960             if (Op->Common.AmlOpcode == AML_REGION_OP)
961             {
962                 /*
963                  * Skip parsing of control method or opregion body,
964                  * because we don't have enough info in the first pass
965                  * to parse them correctly.
966                  *
967                  * Completed parsing an OpRegion declaration, we now
968                  * know the length.
969                  */
970                 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
971             }
972         }
973
974         if (WalkState->OpInfo->Flags & AML_CREATE)
975         {
976             /*
977              * Backup to beginning of CreateXXXfield declaration (1 for
978              * Opcode)
979              *
980              * BodyLength is unknown until we parse the body
981              */
982             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
983         }
984
985         /* This op complete, notify the dispatcher */
986
987         if (WalkState->AscendingCallback != NULL)
988         {
989             WalkState->Op     = Op;
990             WalkState->Opcode = Op->Common.AmlOpcode;
991
992             Status = WalkState->AscendingCallback (WalkState);
993             Status = AcpiPsNextParseState (WalkState, Op, Status);
994             if (Status == AE_CTRL_PENDING)
995             {
996                 Status = AE_OK;
997                 goto CloseThisOp;
998             }
999         }
1000
1001
1002 CloseThisOp:
1003         /*
1004          * Finished one argument of the containing scope
1005          */
1006         ParserState->Scope->ParseScope.ArgCount--;
1007
1008         /* Close this Op (will result in parse subtree deletion) */
1009
1010         AcpiPsCompleteThisOp (WalkState, Op);
1011         Op = NULL;
1012         if (PreOp)
1013         {
1014             AcpiPsFreeOp (PreOp);
1015             PreOp = NULL;
1016         }
1017
1018         switch (Status)
1019         {
1020         case AE_OK:
1021             break;
1022
1023
1024         case AE_CTRL_TRANSFER:
1025
1026             /*
1027              * We are about to transfer to a called method.
1028              */
1029             WalkState->PrevOp = Op;
1030             WalkState->PrevArgTypes = WalkState->ArgTypes;
1031             return_ACPI_STATUS (Status);
1032
1033
1034         case AE_CTRL_END:
1035
1036             AcpiPsPopScope (ParserState, &Op,
1037                 &WalkState->ArgTypes, &WalkState->ArgCount);
1038
1039             if (Op)
1040             {
1041                 WalkState->Op     = Op;
1042                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1043                 WalkState->Opcode = Op->Common.AmlOpcode;
1044
1045                 Status = WalkState->AscendingCallback (WalkState);
1046                 Status = AcpiPsNextParseState (WalkState, Op, Status);
1047
1048                 AcpiPsCompleteThisOp (WalkState, Op);
1049                 Op = NULL;
1050             }
1051             Status = AE_OK;
1052             break;
1053
1054
1055         case AE_CTRL_BREAK:
1056         case AE_CTRL_CONTINUE:
1057
1058             /* Pop off scopes until we find the While */
1059
1060             while (!Op || (Op->Common.AmlOpcode != AML_WHILE_OP))
1061             {
1062                 AcpiPsPopScope (ParserState, &Op,
1063                     &WalkState->ArgTypes, &WalkState->ArgCount);
1064             }
1065
1066             /* Close this iteration of the While loop */
1067
1068             WalkState->Op     = Op;
1069             WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1070             WalkState->Opcode = Op->Common.AmlOpcode;
1071
1072             Status = WalkState->AscendingCallback (WalkState);
1073             Status = AcpiPsNextParseState (WalkState, Op, Status);
1074
1075             AcpiPsCompleteThisOp (WalkState, Op);
1076             Op = NULL;
1077
1078             Status = AE_OK;
1079             break;
1080
1081
1082         case AE_CTRL_TERMINATE:
1083
1084             Status = AE_OK;
1085
1086             /* Clean up */
1087             do
1088             {
1089                 if (Op)
1090                 {
1091                     AcpiPsCompleteThisOp (WalkState, Op);
1092                 }
1093                 AcpiPsPopScope (ParserState, &Op,
1094                     &WalkState->ArgTypes, &WalkState->ArgCount);
1095
1096             } while (Op);
1097
1098             return_ACPI_STATUS (Status);
1099
1100
1101         default:  /* All other non-AE_OK status */
1102
1103             do
1104             {
1105                 if (Op)
1106                 {
1107                     AcpiPsCompleteThisOp (WalkState, Op);
1108                 }
1109                 AcpiPsPopScope (ParserState, &Op,
1110                     &WalkState->ArgTypes, &WalkState->ArgCount);
1111
1112             } while (Op);
1113
1114
1115             /*
1116              * TBD: Cleanup parse ops on error
1117              */
1118 #if 0
1119             if (Op == NULL)
1120             {
1121                 AcpiPsPopScope (ParserState, &Op,
1122                     &WalkState->ArgTypes, &WalkState->ArgCount);
1123             }
1124 #endif
1125             WalkState->PrevOp = Op;
1126             WalkState->PrevArgTypes = WalkState->ArgTypes;
1127             return_ACPI_STATUS (Status);
1128         }
1129
1130         /* This scope complete? */
1131
1132         if (AcpiPsHasCompletedScope (ParserState))
1133         {
1134             AcpiPsPopScope (ParserState, &Op,
1135                 &WalkState->ArgTypes, &WalkState->ArgCount);
1136             ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
1137         }
1138         else
1139         {
1140             Op = NULL;
1141         }
1142
1143     } /* while ParserState->Aml */
1144
1145
1146     /*
1147      * Complete the last Op (if not completed), and clear the scope stack.
1148      * It is easily possible to end an AML "package" with an unbounded number
1149      * of open scopes (such as when several ASL blocks are closed with
1150      * sequential closing braces).  We want to terminate each one cleanly.
1151      */
1152     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
1153     do
1154     {
1155         if (Op)
1156         {
1157             if (WalkState->AscendingCallback != NULL)
1158             {
1159                 WalkState->Op     = Op;
1160                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1161                 WalkState->Opcode = Op->Common.AmlOpcode;
1162
1163                 Status = WalkState->AscendingCallback (WalkState);
1164                 Status = AcpiPsNextParseState (WalkState, Op, Status);
1165                 if (Status == AE_CTRL_PENDING)
1166                 {
1167                     Status = AE_OK;
1168                     goto CloseThisOp;
1169                 }
1170
1171                 if (Status == AE_CTRL_TERMINATE)
1172                 {
1173                     Status = AE_OK;
1174
1175                     /* Clean up */
1176                     do
1177                     {
1178                         if (Op)
1179                         {
1180                             AcpiPsCompleteThisOp (WalkState, Op);
1181                         }
1182
1183                         AcpiPsPopScope (ParserState, &Op,
1184                             &WalkState->ArgTypes, &WalkState->ArgCount);
1185
1186                     } while (Op);
1187
1188                     return_ACPI_STATUS (Status);
1189                 }
1190
1191                 else if (ACPI_FAILURE (Status))
1192                 {
1193                     AcpiPsCompleteThisOp (WalkState, Op);
1194                     return_ACPI_STATUS (Status);
1195                 }
1196             }
1197
1198             AcpiPsCompleteThisOp (WalkState, Op);
1199         }
1200
1201         AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes,
1202             &WalkState->ArgCount);
1203
1204     } while (Op);
1205
1206     return_ACPI_STATUS (Status);
1207 }
1208
1209
1210 /*******************************************************************************
1211  *
1212  * FUNCTION:    AcpiPsParseAml
1213  *
1214  * PARAMETERS:  StartScope      - The starting point of the parse.  Becomes the
1215  *                                root of the parsed op tree.
1216  *              Aml             - Pointer to the raw AML code to parse
1217  *              AmlSize         - Length of the AML to parse
1218  *
1219  *
1220  * RETURN:      Status
1221  *
1222  * DESCRIPTION: Parse raw AML and return a tree of ops
1223  *
1224  ******************************************************************************/
1225
1226 ACPI_STATUS
1227 AcpiPsParseAml (
1228     ACPI_WALK_STATE         *WalkState)
1229 {
1230     ACPI_STATUS             Status;
1231     ACPI_STATUS             TerminateStatus;
1232     ACPI_THREAD_STATE       *Thread;
1233     ACPI_THREAD_STATE       *PrevWalkList = AcpiGbl_CurrentWalkList;
1234     ACPI_WALK_STATE         *PreviousWalkState;
1235
1236
1237     ACPI_FUNCTION_TRACE ("PsParseAml");
1238
1239     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with WalkState=%p Aml=%p size=%X\n",
1240         WalkState, WalkState->ParserState.Aml, WalkState->ParserState.AmlSize));
1241
1242
1243     /* Create and initialize a new thread state */
1244
1245     Thread = AcpiUtCreateThreadState ();
1246     if (!Thread)
1247     {
1248         return_ACPI_STATUS (AE_NO_MEMORY);
1249     }
1250
1251     WalkState->Thread = Thread;
1252     AcpiDsPushWalkState (WalkState, Thread);
1253
1254     /*
1255      * This global allows the AML debugger to get a handle to the currently
1256      * executing control method.
1257      */
1258     AcpiGbl_CurrentWalkList = Thread;
1259
1260     /*
1261      * Execute the walk loop as long as there is a valid Walk State.  This
1262      * handles nested control method invocations without recursion.
1263      */
1264     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", WalkState));
1265
1266     Status = AE_OK;
1267     while (WalkState)
1268     {
1269         if (ACPI_SUCCESS (Status))
1270         {
1271             /*
1272              * The ParseLoop executes AML until the method terminates
1273              * or calls another method.
1274              */
1275             Status = AcpiPsParseLoop (WalkState);
1276         }
1277
1278         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1279             "Completed one call to walk loop, %s State=%p\n",
1280             AcpiFormatException (Status), WalkState));
1281
1282         if (Status == AE_CTRL_TRANSFER)
1283         {
1284             /*
1285              * A method call was detected.
1286              * Transfer control to the called control method
1287              */
1288             Status = AcpiDsCallControlMethod (Thread, WalkState, NULL);
1289
1290             /*
1291              * If the transfer to the new method method call worked, a new walk
1292              * state was created -- get it
1293              */
1294             WalkState = AcpiDsGetCurrentWalkState (Thread);
1295             continue;
1296         }
1297         else if (Status == AE_CTRL_TERMINATE)
1298         {
1299             Status = AE_OK;
1300         }
1301         else if ((Status != AE_OK) && (WalkState->MethodDesc))
1302         {
1303             ACPI_REPORT_METHOD_ERROR ("Method execution failed",
1304                 WalkState->MethodNode, NULL, Status);
1305
1306             /* Check for possible multi-thread reentrancy problem */
1307
1308             if ((Status == AE_ALREADY_EXISTS) &&
1309                 (!WalkState->MethodDesc->Method.Semaphore))
1310             {
1311                 /*
1312                  * This method is marked NotSerialized, but it tried to create a named
1313                  * object, causing the second thread entrance to fail.  We will workaround
1314                  * this by marking the method permanently as Serialized.
1315                  */
1316                 WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED;
1317                 WalkState->MethodDesc->Method.Concurrency = 1;
1318             }
1319         }
1320
1321         if (WalkState->MethodDesc)
1322         {
1323             /* Decrement the thread count on the method parse tree */
1324
1325             if (WalkState->MethodDesc->Method.ThreadCount)
1326             {
1327                 WalkState->MethodDesc->Method.ThreadCount--;
1328             }
1329         }
1330
1331         /* We are done with this walk, move on to the parent if any */
1332
1333         WalkState = AcpiDsPopWalkState (Thread);
1334
1335         /* Reset the current scope to the beginning of scope stack */
1336
1337         AcpiDsScopeStackClear (WalkState);
1338
1339         /*
1340          * If we just returned from the execution of a control method,
1341          * there's lots of cleanup to do
1342          */
1343         if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE)
1344         {
1345             TerminateStatus = AcpiDsTerminateControlMethod (WalkState);
1346             if (ACPI_FAILURE (TerminateStatus))
1347             {
1348                 ACPI_REPORT_ERROR ((
1349                     "Could not terminate control method properly\n"));
1350
1351                 /* Ignore error and continue */
1352             }
1353         }
1354
1355         /* Delete this walk state and all linked control states */
1356
1357         AcpiPsCleanupScope (&WalkState->ParserState);
1358
1359         PreviousWalkState = WalkState;
1360
1361         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "ReturnValue=%p, ImplicitValue=%p State=%p\n",
1362             WalkState->ReturnDesc, WalkState->ImplicitReturnObj, WalkState));
1363
1364         /* Check if we have restarted a preempted walk */
1365
1366         WalkState = AcpiDsGetCurrentWalkState (Thread);
1367         if (WalkState)
1368         {
1369             if (ACPI_SUCCESS (Status))
1370             {
1371                 /*
1372                  * There is another walk state, restart it.
1373                  * If the method return value is not used by the parent,
1374                  * The object is deleted
1375                  */
1376                 if (!PreviousWalkState->ReturnDesc)
1377                 {
1378                     Status = AcpiDsRestartControlMethod (WalkState,
1379                                 PreviousWalkState->ImplicitReturnObj);
1380                 }
1381                 else
1382                 {
1383                     /*
1384                      * We have a valid return value, delete any implicit
1385                      * return value.
1386                      */
1387                     AcpiDsClearImplicitReturn (PreviousWalkState);
1388
1389                     Status = AcpiDsRestartControlMethod (WalkState,
1390                                 PreviousWalkState->ReturnDesc);
1391                 }
1392                 if (ACPI_SUCCESS (Status))
1393                 {
1394                     WalkState->WalkType |= ACPI_WALK_METHOD_RESTART;
1395                 }
1396             }
1397             else
1398             {
1399                 /* On error, delete any return object */
1400
1401                 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
1402             }
1403         }
1404
1405         /*
1406          * Just completed a 1st-level method, save the final internal return
1407          * value (if any)
1408          */
1409         else if (PreviousWalkState->CallerReturnDesc)
1410         {
1411             if (PreviousWalkState->ImplicitReturnObj)
1412             {
1413                 *(PreviousWalkState->CallerReturnDesc) = PreviousWalkState->ImplicitReturnObj;
1414             }
1415             else
1416             {
1417                  /* NULL if no return value */
1418
1419                 *(PreviousWalkState->CallerReturnDesc) = PreviousWalkState->ReturnDesc;
1420             }
1421         }
1422         else
1423         {
1424             if (PreviousWalkState->ReturnDesc)
1425             {
1426                 /* Caller doesn't want it, must delete it */
1427
1428                 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
1429             }
1430             if (PreviousWalkState->ImplicitReturnObj)
1431             {
1432                 /* Caller doesn't want it, must delete it */
1433
1434                 AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);
1435             }
1436         }
1437
1438         AcpiDsDeleteWalkState (PreviousWalkState);
1439     }
1440
1441     /* Normal exit */
1442
1443     AcpiExReleaseAllMutexes (Thread);
1444     AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));
1445     AcpiGbl_CurrentWalkList = PrevWalkList;
1446     return_ACPI_STATUS (Status);
1447 }
1448
1449