]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/acpi/parser/psloop.c
/home/lenb/src/to-akpm branch 'acpi-2.6.12'
[linux-2.6-omap-h63xx.git] / drivers / acpi / parser / psloop.c
1 /******************************************************************************
2  *
3  * Module Name: psloop - Main AML parse loop
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 /*
46  * Parse the AML and build an operation tree as most interpreters,
47  * like Perl, do.  Parsing is done by hand rather than with a YACC
48  * generated parser to tightly constrain stack and dynamic memory
49  * usage.  At the same time, parsing is kept flexible and the code
50  * fairly compact by parsing based on a list of AML opcode
51  * templates in aml_op_info[]
52  */
53
54 #include <acpi/acpi.h>
55 #include <acpi/acparser.h>
56 #include <acpi/acdispat.h>
57 #include <acpi/amlcode.h>
58
59 #define _COMPONENT          ACPI_PARSER
60          ACPI_MODULE_NAME    ("psloop")
61
62 static u32                          acpi_gbl_depth = 0;
63
64
65 /*******************************************************************************
66  *
67  * FUNCTION:    acpi_ps_parse_loop
68  *
69  * PARAMETERS:  walk_state          - Current state
70  *
71  * RETURN:      Status
72  *
73  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
74  *              a tree of ops.
75  *
76  ******************************************************************************/
77
78 acpi_status
79 acpi_ps_parse_loop (
80         struct acpi_walk_state          *walk_state)
81 {
82         acpi_status                     status = AE_OK;
83         acpi_status                     status2;
84         union acpi_parse_object         *op = NULL;     /* current op */
85         union acpi_parse_object         *arg = NULL;
86         union acpi_parse_object         *pre_op = NULL;
87         struct acpi_parse_state         *parser_state;
88         u8                              *aml_op_start = NULL;
89
90
91         ACPI_FUNCTION_TRACE_PTR ("ps_parse_loop", walk_state);
92
93         if (walk_state->descending_callback == NULL) {
94                 return_ACPI_STATUS (AE_BAD_PARAMETER);
95         }
96
97         parser_state = &walk_state->parser_state;
98         walk_state->arg_types = 0;
99
100 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
101
102         if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
103                 /* We are restarting a preempted control method */
104
105                 if (acpi_ps_has_completed_scope (parser_state)) {
106                         /*
107                          * We must check if a predicate to an IF or WHILE statement
108                          * was just completed
109                          */
110                         if ((parser_state->scope->parse_scope.op) &&
111                            ((parser_state->scope->parse_scope.op->common.aml_opcode == AML_IF_OP) ||
112                                 (parser_state->scope->parse_scope.op->common.aml_opcode == AML_WHILE_OP)) &&
113                                 (walk_state->control_state) &&
114                                 (walk_state->control_state->common.state ==
115                                         ACPI_CONTROL_PREDICATE_EXECUTING)) {
116                                 /*
117                                  * A predicate was just completed, get the value of the
118                                  * predicate and branch based on that value
119                                  */
120                                 walk_state->op = NULL;
121                                 status = acpi_ds_get_predicate_value (walk_state, ACPI_TO_POINTER (TRUE));
122                                 if (ACPI_FAILURE (status) &&
123                                         ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
124                                         if (status == AE_AML_NO_RETURN_VALUE) {
125                                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
126                                                         "Invoked method did not return a value, %s\n",
127                                                         acpi_format_exception (status)));
128
129                                         }
130                                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
131                                                 "get_predicate Failed, %s\n",
132                                                 acpi_format_exception (status)));
133                                         return_ACPI_STATUS (status);
134                                 }
135
136                                 status = acpi_ps_next_parse_state (walk_state, op, status);
137                         }
138
139                         acpi_ps_pop_scope (parser_state, &op,
140                                 &walk_state->arg_types, &walk_state->arg_count);
141                         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
142                 }
143                 else if (walk_state->prev_op) {
144                         /* We were in the middle of an op */
145
146                         op = walk_state->prev_op;
147                         walk_state->arg_types = walk_state->prev_arg_types;
148                 }
149         }
150 #endif
151
152         /* Iterative parsing loop, while there is more AML to process: */
153
154         while ((parser_state->aml < parser_state->aml_end) || (op)) {
155                 aml_op_start = parser_state->aml;
156                 if (!op) {
157                         /* Get the next opcode from the AML stream */
158
159                         walk_state->aml_offset = (u32) ACPI_PTR_DIFF (parser_state->aml,
160                                           parser_state->aml_start);
161                         walk_state->opcode   = acpi_ps_peek_opcode (parser_state);
162
163                         /*
164                          * First cut to determine what we have found:
165                          * 1) A valid AML opcode
166                          * 2) A name string
167                          * 3) An unknown/invalid opcode
168                          */
169                         walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
170                         switch (walk_state->op_info->class) {
171                         case AML_CLASS_ASCII:
172                         case AML_CLASS_PREFIX:
173                                 /*
174                                  * Starts with a valid prefix or ASCII char, this is a name
175                                  * string.  Convert the bare name string to a namepath.
176                                  */
177                                 walk_state->opcode = AML_INT_NAMEPATH_OP;
178                                 walk_state->arg_types = ARGP_NAMESTRING;
179                                 break;
180
181                         case AML_CLASS_UNKNOWN:
182
183                                 /* The opcode is unrecognized.  Just skip unknown opcodes */
184
185                                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
186                                         "Found unknown opcode %X at AML address %p offset %X, ignoring\n",
187                                         walk_state->opcode, parser_state->aml, walk_state->aml_offset));
188
189                                 ACPI_DUMP_BUFFER (parser_state->aml, 128);
190
191                                 /* Assume one-byte bad opcode */
192
193                                 parser_state->aml++;
194                                 continue;
195
196                         default:
197
198                                 /* Found opcode info, this is a normal opcode */
199
200                                 parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
201                                 walk_state->arg_types = walk_state->op_info->parse_args;
202                                 break;
203                         }
204
205                         /* Create Op structure and append to parent's argument list */
206
207                         if (walk_state->op_info->flags & AML_NAMED) {
208                                 /* Allocate a new pre_op if necessary */
209
210                                 if (!pre_op) {
211                                         pre_op = acpi_ps_alloc_op (walk_state->opcode);
212                                         if (!pre_op) {
213                                                 status = AE_NO_MEMORY;
214                                                 goto close_this_op;
215                                         }
216                                 }
217
218                                 pre_op->common.value.arg = NULL;
219                                 pre_op->common.aml_opcode = walk_state->opcode;
220
221                                 /*
222                                  * Get and append arguments until we find the node that contains
223                                  * the name (the type ARGP_NAME).
224                                  */
225                                 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
226                                           (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME)) {
227                                         status = acpi_ps_get_next_arg (walk_state, parser_state,
228                                                          GET_CURRENT_ARG_TYPE (walk_state->arg_types), &arg);
229                                         if (ACPI_FAILURE (status)) {
230                                                 goto close_this_op;
231                                         }
232
233                                         acpi_ps_append_arg (pre_op, arg);
234                                         INCREMENT_ARG_LIST (walk_state->arg_types);
235                                 }
236
237                                 /*
238                                  * Make sure that we found a NAME and didn't run out of
239                                  * arguments
240                                  */
241                                 if (!GET_CURRENT_ARG_TYPE (walk_state->arg_types)) {
242                                         status = AE_AML_NO_OPERAND;
243                                         goto close_this_op;
244                                 }
245
246                                 /* We know that this arg is a name, move to next arg */
247
248                                 INCREMENT_ARG_LIST (walk_state->arg_types);
249
250                                 /*
251                                  * Find the object.  This will either insert the object into
252                                  * the namespace or simply look it up
253                                  */
254                                 walk_state->op = NULL;
255
256                                 status = walk_state->descending_callback (walk_state, &op);
257                                 if (ACPI_FAILURE (status)) {
258                                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
259                                                 "During name lookup/catalog, %s\n",
260                                                 acpi_format_exception (status)));
261                                         goto close_this_op;
262                                 }
263
264                                 if (!op) {
265                                         continue;
266                                 }
267
268                                 status = acpi_ps_next_parse_state (walk_state, op, status);
269                                 if (status == AE_CTRL_PENDING) {
270                                         status = AE_OK;
271                                         goto close_this_op;
272                                 }
273
274                                 if (ACPI_FAILURE (status)) {
275                                         goto close_this_op;
276                                 }
277
278                                 acpi_ps_append_arg (op, pre_op->common.value.arg);
279                                 acpi_gbl_depth++;
280
281                                 if (op->common.aml_opcode == AML_REGION_OP) {
282                                         /*
283                                          * Defer final parsing of an operation_region body,
284                                          * because we don't have enough info in the first pass
285                                          * to parse it correctly (i.e., there may be method
286                                          * calls within the term_arg elements of the body.)
287                                          *
288                                          * However, we must continue parsing because
289                                          * the opregion is not a standalone package --
290                                          * we don't know where the end is at this point.
291                                          *
292                                          * (Length is unknown until parse of the body complete)
293                                          */
294                                         op->named.data    = aml_op_start;
295                                         op->named.length  = 0;
296                                 }
297                         }
298                         else {
299                                 /* Not a named opcode, just allocate Op and append to parent */
300
301                                 walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
302                                 op = acpi_ps_alloc_op (walk_state->opcode);
303                                 if (!op) {
304                                         status = AE_NO_MEMORY;
305                                         goto close_this_op;
306                                 }
307
308                                 if (walk_state->op_info->flags & AML_CREATE) {
309                                         /*
310                                          * Backup to beginning of create_xXXfield declaration
311                                          * body_length is unknown until we parse the body
312                                          */
313                                         op->named.data    = aml_op_start;
314                                         op->named.length  = 0;
315                                 }
316
317                                 acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
318
319                                 if ((walk_state->descending_callback != NULL)) {
320                                         /*
321                                          * Find the object. This will either insert the object into
322                                          * the namespace or simply look it up
323                                          */
324                                         walk_state->op = op;
325
326                                         status = walk_state->descending_callback (walk_state, &op);
327                                         status = acpi_ps_next_parse_state (walk_state, op, status);
328                                         if (status == AE_CTRL_PENDING) {
329                                                 status = AE_OK;
330                                                 goto close_this_op;
331                                         }
332
333                                         if (ACPI_FAILURE (status)) {
334                                                 goto close_this_op;
335                                         }
336                                 }
337                         }
338
339                         op->common.aml_offset = walk_state->aml_offset;
340
341                         if (walk_state->op_info) {
342                                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
343                                         "Opcode %4.4X [%s] Op %p Aml %p aml_offset %5.5X\n",
344                                          (u32) op->common.aml_opcode, walk_state->op_info->name,
345                                          op, parser_state->aml, op->common.aml_offset));
346                         }
347                 }
348
349
350                 /*
351                  * Start arg_count at zero because we don't know if there are
352                  * any args yet
353                  */
354                 walk_state->arg_count = 0;
355
356                 /* Are there any arguments that must be processed? */
357
358                 if (walk_state->arg_types) {
359                         /* Get arguments */
360
361                         switch (op->common.aml_opcode) {
362                         case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
363                         case AML_WORD_OP:       /* AML_WORDDATA_ARG */
364                         case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
365                         case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
366                         case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
367
368                                 /* Fill in constant or string argument directly */
369
370                                 acpi_ps_get_next_simple_arg (parser_state,
371                                         GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
372                                 break;
373
374                         case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
375
376                                 status = acpi_ps_get_next_namepath (walk_state, parser_state, op, 1);
377                                 if (ACPI_FAILURE (status)) {
378                                         goto close_this_op;
379                                 }
380
381                                 walk_state->arg_types = 0;
382                                 break;
383
384                         default:
385                                 /*
386                                  * Op is not a constant or string, append each argument
387                                  * to the Op
388                                  */
389                                 while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) &&
390                                                 !walk_state->arg_count) {
391                                         walk_state->aml_offset = (u32)
392                                                 ACPI_PTR_DIFF (parser_state->aml, parser_state->aml_start);
393
394                                         status = acpi_ps_get_next_arg (walk_state, parser_state,
395                                                          GET_CURRENT_ARG_TYPE (walk_state->arg_types),
396                                                          &arg);
397                                         if (ACPI_FAILURE (status)) {
398                                                 goto close_this_op;
399                                         }
400
401                                         if (arg) {
402                                                 arg->common.aml_offset = walk_state->aml_offset;
403                                                 acpi_ps_append_arg (op, arg);
404                                         }
405                                         INCREMENT_ARG_LIST (walk_state->arg_types);
406                                 }
407
408
409                                 /* Special processing for certain opcodes */
410
411         /* TBD (remove): Temporary mechanism to disable this code if needed */
412
413 #ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
414
415                          if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
416                                    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
417                                         /*
418                                          * We want to skip If/Else/While constructs during Pass1
419                                          * because we want to actually conditionally execute the
420                                          * code during Pass2.
421                                          *
422                                          * Except for disassembly, where we always want to
423                                          * walk the If/Else/While packages
424                                          */
425                                         switch (op->common.aml_opcode) {
426                                         case AML_IF_OP:
427                                         case AML_ELSE_OP:
428                                         case AML_WHILE_OP:
429
430                                                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
431                                                         "Pass1: Skipping an If/Else/While body\n"));
432
433                                                 /* Skip body of if/else/while in pass 1 */
434
435                                                 parser_state->aml   = parser_state->pkg_end;
436                                                 walk_state->arg_count = 0;
437                                                 break;
438
439                                         default:
440                                                 break;
441                                         }
442                                 }
443 #endif
444                                 switch (op->common.aml_opcode) {
445                                 case AML_METHOD_OP:
446
447                                         /*
448                                          * Skip parsing of control method
449                                          * because we don't have enough info in the first pass
450                                          * to parse it correctly.
451                                          *
452                                          * Save the length and address of the body
453                                          */
454                                         op->named.data   = parser_state->aml;
455                                         op->named.length = (u32) (parser_state->pkg_end -
456                                                            parser_state->aml);
457
458                                         /* Skip body of method */
459
460                                         parser_state->aml   = parser_state->pkg_end;
461                                         walk_state->arg_count = 0;
462                                         break;
463
464                                 case AML_BUFFER_OP:
465                                 case AML_PACKAGE_OP:
466                                 case AML_VAR_PACKAGE_OP:
467
468                                         if ((op->common.parent) &&
469                                                 (op->common.parent->common.aml_opcode == AML_NAME_OP) &&
470                                                 (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) {
471                                                 /*
472                                                  * Skip parsing of Buffers and Packages
473                                                  * because we don't have enough info in the first pass
474                                                  * to parse them correctly.
475                                                  */
476                                                 op->named.data   = aml_op_start;
477                                                 op->named.length = (u32) (parser_state->pkg_end -
478                                                                    aml_op_start);
479
480                                                 /* Skip body */
481
482                                                 parser_state->aml   = parser_state->pkg_end;
483                                                 walk_state->arg_count = 0;
484                                         }
485                                         break;
486
487                                 case AML_WHILE_OP:
488
489                                         if (walk_state->control_state) {
490                                                 walk_state->control_state->control.package_end =
491                                                         parser_state->pkg_end;
492                                         }
493                                         break;
494
495                                 default:
496
497                                         /* No action for all other opcodes */
498                                         break;
499                                 }
500                                 break;
501                         }
502                 }
503
504                 /* Check for arguments that need to be processed */
505
506                 if (walk_state->arg_count) {
507                         /*
508                          * There are arguments (complex ones), push Op and
509                          * prepare for argument
510                          */
511                         status = acpi_ps_push_scope (parser_state, op,
512                                          walk_state->arg_types, walk_state->arg_count);
513                         if (ACPI_FAILURE (status)) {
514                                 goto close_this_op;
515                         }
516                         op = NULL;
517                         continue;
518                 }
519
520                 /*
521                  * All arguments have been processed -- Op is complete,
522                  * prepare for next
523                  */
524                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
525                 if (walk_state->op_info->flags & AML_NAMED) {
526                         if (acpi_gbl_depth) {
527                                 acpi_gbl_depth--;
528                         }
529
530                         if (op->common.aml_opcode == AML_REGION_OP) {
531                                 /*
532                                  * Skip parsing of control method or opregion body,
533                                  * because we don't have enough info in the first pass
534                                  * to parse them correctly.
535                                  *
536                                  * Completed parsing an op_region declaration, we now
537                                  * know the length.
538                                  */
539                                 op->named.length = (u32) (parser_state->aml - op->named.data);
540                         }
541                 }
542
543                 if (walk_state->op_info->flags & AML_CREATE) {
544                         /*
545                          * Backup to beginning of create_xXXfield declaration (1 for
546                          * Opcode)
547                          *
548                          * body_length is unknown until we parse the body
549                          */
550                         op->named.length = (u32) (parser_state->aml - op->named.data);
551                 }
552
553                 /* This op complete, notify the dispatcher */
554
555                 if (walk_state->ascending_callback != NULL) {
556                         walk_state->op    = op;
557                         walk_state->opcode = op->common.aml_opcode;
558
559                         status = walk_state->ascending_callback (walk_state);
560                         status = acpi_ps_next_parse_state (walk_state, op, status);
561                         if (status == AE_CTRL_PENDING) {
562                                 status = AE_OK;
563                                 goto close_this_op;
564                         }
565                 }
566
567
568 close_this_op:
569                 /*
570                  * Finished one argument of the containing scope
571                  */
572                 parser_state->scope->parse_scope.arg_count--;
573
574                 /* Finished with pre_op */
575
576                 if (pre_op) {
577                         acpi_ps_free_op (pre_op);
578                         pre_op = NULL;
579                 }
580
581                 /* Close this Op (will result in parse subtree deletion) */
582
583                 status2 = acpi_ps_complete_this_op (walk_state, op);
584                 if (ACPI_FAILURE (status2)) {
585                         return_ACPI_STATUS (status2);
586                 }
587                 op = NULL;
588
589                 switch (status) {
590                 case AE_OK:
591                         break;
592
593
594                 case AE_CTRL_TRANSFER:
595
596                         /* We are about to transfer to a called method. */
597
598                         walk_state->prev_op = op;
599                         walk_state->prev_arg_types = walk_state->arg_types;
600                         return_ACPI_STATUS (status);
601
602
603                 case AE_CTRL_END:
604
605                         acpi_ps_pop_scope (parser_state, &op,
606                                 &walk_state->arg_types, &walk_state->arg_count);
607
608                         if (op) {
609                                 walk_state->op    = op;
610                                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
611                                 walk_state->opcode = op->common.aml_opcode;
612
613                                 status = walk_state->ascending_callback (walk_state);
614                                 status = acpi_ps_next_parse_state (walk_state, op, status);
615
616                                 status2 = acpi_ps_complete_this_op (walk_state, op);
617                                 if (ACPI_FAILURE (status2)) {
618                                         return_ACPI_STATUS (status2);
619                                 }
620                                 op = NULL;
621                         }
622                         status = AE_OK;
623                         break;
624
625
626                 case AE_CTRL_BREAK:
627                 case AE_CTRL_CONTINUE:
628
629                         /* Pop off scopes until we find the While */
630
631                         while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
632                                 acpi_ps_pop_scope (parser_state, &op,
633                                         &walk_state->arg_types, &walk_state->arg_count);
634                         }
635
636                         /* Close this iteration of the While loop */
637
638                         walk_state->op    = op;
639                         walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
640                         walk_state->opcode = op->common.aml_opcode;
641
642                         status = walk_state->ascending_callback (walk_state);
643                         status = acpi_ps_next_parse_state (walk_state, op, status);
644
645                         status2 = acpi_ps_complete_this_op (walk_state, op);
646                         if (ACPI_FAILURE (status2)) {
647                                 return_ACPI_STATUS (status2);
648                         }
649                         op = NULL;
650
651                         status = AE_OK;
652                         break;
653
654
655                 case AE_CTRL_TERMINATE:
656
657                         status = AE_OK;
658
659                         /* Clean up */
660                         do {
661                                 if (op) {
662                                         status2 = acpi_ps_complete_this_op (walk_state, op);
663                                         if (ACPI_FAILURE (status2)) {
664                                                 return_ACPI_STATUS (status2);
665                                         }
666                                 }
667                                 acpi_ps_pop_scope (parser_state, &op,
668                                         &walk_state->arg_types, &walk_state->arg_count);
669
670                         } while (op);
671
672                         return_ACPI_STATUS (status);
673
674
675                 default:  /* All other non-AE_OK status */
676
677                         do {
678                                 if (op) {
679                                         status2 = acpi_ps_complete_this_op (walk_state, op);
680                                         if (ACPI_FAILURE (status2)) {
681                                                 return_ACPI_STATUS (status2);
682                                         }
683                                 }
684                                 acpi_ps_pop_scope (parser_state, &op,
685                                         &walk_state->arg_types, &walk_state->arg_count);
686
687                         } while (op);
688
689
690                         /*
691                          * TBD: Cleanup parse ops on error
692                          */
693 #if 0
694                         if (op == NULL) {
695                                 acpi_ps_pop_scope (parser_state, &op,
696                                         &walk_state->arg_types, &walk_state->arg_count);
697                         }
698 #endif
699                         walk_state->prev_op = op;
700                         walk_state->prev_arg_types = walk_state->arg_types;
701                         return_ACPI_STATUS (status);
702                 }
703
704                 /* This scope complete? */
705
706                 if (acpi_ps_has_completed_scope (parser_state)) {
707                         acpi_ps_pop_scope (parser_state, &op,
708                                 &walk_state->arg_types, &walk_state->arg_count);
709                         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
710                 }
711                 else {
712                         op = NULL;
713                 }
714
715         } /* while parser_state->Aml */
716
717
718         /*
719          * Complete the last Op (if not completed), and clear the scope stack.
720          * It is easily possible to end an AML "package" with an unbounded number
721          * of open scopes (such as when several ASL blocks are closed with
722          * sequential closing braces).  We want to terminate each one cleanly.
723          */
724         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
725         do {
726                 if (op) {
727                         if (walk_state->ascending_callback != NULL) {
728                                 walk_state->op    = op;
729                                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
730                                 walk_state->opcode = op->common.aml_opcode;
731
732                                 status = walk_state->ascending_callback (walk_state);
733                                 status = acpi_ps_next_parse_state (walk_state, op, status);
734                                 if (status == AE_CTRL_PENDING) {
735                                         status = AE_OK;
736                                         goto close_this_op;
737                                 }
738
739                                 if (status == AE_CTRL_TERMINATE) {
740                                         status = AE_OK;
741
742                                         /* Clean up */
743                                         do {
744                                                 if (op) {
745                                                         status2 = acpi_ps_complete_this_op (walk_state, op);
746                                                         if (ACPI_FAILURE (status2)) {
747                                                                 return_ACPI_STATUS (status2);
748                                                         }
749                                                 }
750
751                                                 acpi_ps_pop_scope (parser_state, &op,
752                                                         &walk_state->arg_types, &walk_state->arg_count);
753
754                                         } while (op);
755
756                                         return_ACPI_STATUS (status);
757                                 }
758
759                                 else if (ACPI_FAILURE (status)) {
760                                         /* First error is most important */
761
762                                         (void) acpi_ps_complete_this_op (walk_state, op);
763                                         return_ACPI_STATUS (status);
764                                 }
765                         }
766
767                         status2 = acpi_ps_complete_this_op (walk_state, op);
768                         if (ACPI_FAILURE (status2)) {
769                                 return_ACPI_STATUS (status2);
770                         }
771                 }
772
773                 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
774                         &walk_state->arg_count);
775
776         } while (op);
777
778         return_ACPI_STATUS (status);
779 }
780
781