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