]> err.no Git - linux-2.6/blob - drivers/acpi/parser/psloop.c
ACPICA 20050617-0624 from Bob Moore <robert.moore@intel.com>
[linux-2.6] / 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                                 /* Special processing for certain opcodes */
411
412                                 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) &&
413                                    ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
414                                         /*
415                                          * We want to skip If/Else/While constructs during Pass1
416                                          * because we want to actually conditionally execute the
417                                          * code during Pass2.
418                                          *
419                                          * Except for disassembly, where we always want to
420                                          * walk the If/Else/While packages
421                                          */
422                                         switch (op->common.aml_opcode) {
423                                         case AML_IF_OP:
424                                         case AML_ELSE_OP:
425                                         case AML_WHILE_OP:
426
427                                                 /* Skip body of if/else/while in pass 1 */
428
429                                                 parser_state->aml   = parser_state->pkg_end;
430                                                 walk_state->arg_count = 0;
431                                                 break;
432
433                                         default:
434                                                 break;
435                                         }
436                                 }
437
438                                 switch (op->common.aml_opcode) {
439                                 case AML_METHOD_OP:
440
441                                         /*
442                                          * Skip parsing of control method
443                                          * because we don't have enough info in the first pass
444                                          * to parse it correctly.
445                                          *
446                                          * Save the length and address of the body
447                                          */
448                                         op->named.data   = parser_state->aml;
449                                         op->named.length = (u32) (parser_state->pkg_end -
450                                                            parser_state->aml);
451
452                                         /* Skip body of method */
453
454                                         parser_state->aml   = parser_state->pkg_end;
455                                         walk_state->arg_count = 0;
456                                         break;
457
458                                 case AML_BUFFER_OP:
459                                 case AML_PACKAGE_OP:
460                                 case AML_VAR_PACKAGE_OP:
461
462                                         if ((op->common.parent) &&
463                                                 (op->common.parent->common.aml_opcode == AML_NAME_OP) &&
464                                                 (walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2)) {
465                                                 /*
466                                                  * Skip parsing of Buffers and Packages
467                                                  * because we don't have enough info in the first pass
468                                                  * to parse them correctly.
469                                                  */
470                                                 op->named.data   = aml_op_start;
471                                                 op->named.length = (u32) (parser_state->pkg_end -
472                                                                    aml_op_start);
473
474                                                 /* Skip body */
475
476                                                 parser_state->aml   = parser_state->pkg_end;
477                                                 walk_state->arg_count = 0;
478                                         }
479                                         break;
480
481                                 case AML_WHILE_OP:
482
483                                         if (walk_state->control_state) {
484                                                 walk_state->control_state->control.package_end =
485                                                         parser_state->pkg_end;
486                                         }
487                                         break;
488
489                                 default:
490
491                                         /* No action for all other opcodes */
492                                         break;
493                                 }
494                                 break;
495                         }
496                 }
497
498                 /* Check for arguments that need to be processed */
499
500                 if (walk_state->arg_count) {
501                         /*
502                          * There are arguments (complex ones), push Op and
503                          * prepare for argument
504                          */
505                         status = acpi_ps_push_scope (parser_state, op,
506                                          walk_state->arg_types, walk_state->arg_count);
507                         if (ACPI_FAILURE (status)) {
508                                 goto close_this_op;
509                         }
510                         op = NULL;
511                         continue;
512                 }
513
514                 /*
515                  * All arguments have been processed -- Op is complete,
516                  * prepare for next
517                  */
518                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
519                 if (walk_state->op_info->flags & AML_NAMED) {
520                         if (acpi_gbl_depth) {
521                                 acpi_gbl_depth--;
522                         }
523
524                         if (op->common.aml_opcode == AML_REGION_OP) {
525                                 /*
526                                  * Skip parsing of control method or opregion body,
527                                  * because we don't have enough info in the first pass
528                                  * to parse them correctly.
529                                  *
530                                  * Completed parsing an op_region declaration, we now
531                                  * know the length.
532                                  */
533                                 op->named.length = (u32) (parser_state->aml - op->named.data);
534                         }
535                 }
536
537                 if (walk_state->op_info->flags & AML_CREATE) {
538                         /*
539                          * Backup to beginning of create_xXXfield declaration (1 for
540                          * Opcode)
541                          *
542                          * body_length is unknown until we parse the body
543                          */
544                         op->named.length = (u32) (parser_state->aml - op->named.data);
545                 }
546
547                 /* This op complete, notify the dispatcher */
548
549                 if (walk_state->ascending_callback != NULL) {
550                         walk_state->op    = op;
551                         walk_state->opcode = op->common.aml_opcode;
552
553                         status = walk_state->ascending_callback (walk_state);
554                         status = acpi_ps_next_parse_state (walk_state, op, status);
555                         if (status == AE_CTRL_PENDING) {
556                                 status = AE_OK;
557                                 goto close_this_op;
558                         }
559                 }
560
561
562 close_this_op:
563                 /*
564                  * Finished one argument of the containing scope
565                  */
566                 parser_state->scope->parse_scope.arg_count--;
567
568                 /* Finished with pre_op */
569
570                 if (pre_op) {
571                         acpi_ps_free_op (pre_op);
572                         pre_op = NULL;
573                 }
574
575                 /* Close this Op (will result in parse subtree deletion) */
576
577                 status2 = acpi_ps_complete_this_op (walk_state, op);
578                 if (ACPI_FAILURE (status2)) {
579                         return_ACPI_STATUS (status2);
580                 }
581                 op = NULL;
582
583                 switch (status) {
584                 case AE_OK:
585                         break;
586
587
588                 case AE_CTRL_TRANSFER:
589
590                         /* We are about to transfer to a called method. */
591
592                         walk_state->prev_op = op;
593                         walk_state->prev_arg_types = walk_state->arg_types;
594                         return_ACPI_STATUS (status);
595
596
597                 case AE_CTRL_END:
598
599                         acpi_ps_pop_scope (parser_state, &op,
600                                 &walk_state->arg_types, &walk_state->arg_count);
601
602                         if (op) {
603                                 walk_state->op    = op;
604                                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
605                                 walk_state->opcode = op->common.aml_opcode;
606
607                                 status = walk_state->ascending_callback (walk_state);
608                                 status = acpi_ps_next_parse_state (walk_state, op, status);
609
610                                 status2 = acpi_ps_complete_this_op (walk_state, op);
611                                 if (ACPI_FAILURE (status2)) {
612                                         return_ACPI_STATUS (status2);
613                                 }
614                                 op = NULL;
615                         }
616                         status = AE_OK;
617                         break;
618
619
620                 case AE_CTRL_BREAK:
621                 case AE_CTRL_CONTINUE:
622
623                         /* Pop off scopes until we find the While */
624
625                         while (!op || (op->common.aml_opcode != AML_WHILE_OP)) {
626                                 acpi_ps_pop_scope (parser_state, &op,
627                                         &walk_state->arg_types, &walk_state->arg_count);
628                         }
629
630                         /* Close this iteration of the While loop */
631
632                         walk_state->op    = op;
633                         walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
634                         walk_state->opcode = op->common.aml_opcode;
635
636                         status = walk_state->ascending_callback (walk_state);
637                         status = acpi_ps_next_parse_state (walk_state, op, status);
638
639                         status2 = acpi_ps_complete_this_op (walk_state, op);
640                         if (ACPI_FAILURE (status2)) {
641                                 return_ACPI_STATUS (status2);
642                         }
643                         op = NULL;
644
645                         status = AE_OK;
646                         break;
647
648
649                 case AE_CTRL_TERMINATE:
650
651                         status = AE_OK;
652
653                         /* Clean up */
654                         do {
655                                 if (op) {
656                                         status2 = acpi_ps_complete_this_op (walk_state, op);
657                                         if (ACPI_FAILURE (status2)) {
658                                                 return_ACPI_STATUS (status2);
659                                         }
660                                 }
661                                 acpi_ps_pop_scope (parser_state, &op,
662                                         &walk_state->arg_types, &walk_state->arg_count);
663
664                         } while (op);
665
666                         return_ACPI_STATUS (status);
667
668
669                 default:  /* All other non-AE_OK status */
670
671                         do {
672                                 if (op) {
673                                         status2 = acpi_ps_complete_this_op (walk_state, op);
674                                         if (ACPI_FAILURE (status2)) {
675                                                 return_ACPI_STATUS (status2);
676                                         }
677                                 }
678                                 acpi_ps_pop_scope (parser_state, &op,
679                                         &walk_state->arg_types, &walk_state->arg_count);
680
681                         } while (op);
682
683
684                         /*
685                          * TBD: Cleanup parse ops on error
686                          */
687 #if 0
688                         if (op == NULL) {
689                                 acpi_ps_pop_scope (parser_state, &op,
690                                         &walk_state->arg_types, &walk_state->arg_count);
691                         }
692 #endif
693                         walk_state->prev_op = op;
694                         walk_state->prev_arg_types = walk_state->arg_types;
695                         return_ACPI_STATUS (status);
696                 }
697
698                 /* This scope complete? */
699
700                 if (acpi_ps_has_completed_scope (parser_state)) {
701                         acpi_ps_pop_scope (parser_state, &op,
702                                 &walk_state->arg_types, &walk_state->arg_count);
703                         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", op));
704                 }
705                 else {
706                         op = NULL;
707                 }
708
709         } /* while parser_state->Aml */
710
711
712         /*
713          * Complete the last Op (if not completed), and clear the scope stack.
714          * It is easily possible to end an AML "package" with an unbounded number
715          * of open scopes (such as when several ASL blocks are closed with
716          * sequential closing braces).  We want to terminate each one cleanly.
717          */
718         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", op));
719         do {
720                 if (op) {
721                         if (walk_state->ascending_callback != NULL) {
722                                 walk_state->op    = op;
723                                 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
724                                 walk_state->opcode = op->common.aml_opcode;
725
726                                 status = walk_state->ascending_callback (walk_state);
727                                 status = acpi_ps_next_parse_state (walk_state, op, status);
728                                 if (status == AE_CTRL_PENDING) {
729                                         status = AE_OK;
730                                         goto close_this_op;
731                                 }
732
733                                 if (status == AE_CTRL_TERMINATE) {
734                                         status = AE_OK;
735
736                                         /* Clean up */
737                                         do {
738                                                 if (op) {
739                                                         status2 = acpi_ps_complete_this_op (walk_state, op);
740                                                         if (ACPI_FAILURE (status2)) {
741                                                                 return_ACPI_STATUS (status2);
742                                                         }
743                                                 }
744
745                                                 acpi_ps_pop_scope (parser_state, &op,
746                                                         &walk_state->arg_types, &walk_state->arg_count);
747
748                                         } while (op);
749
750                                         return_ACPI_STATUS (status);
751                                 }
752
753                                 else if (ACPI_FAILURE (status)) {
754                                         /* First error is most important */
755
756                                         (void) acpi_ps_complete_this_op (walk_state, op);
757                                         return_ACPI_STATUS (status);
758                                 }
759                         }
760
761                         status2 = acpi_ps_complete_this_op (walk_state, op);
762                         if (ACPI_FAILURE (status2)) {
763                                 return_ACPI_STATUS (status2);
764                         }
765                 }
766
767                 acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types,
768                         &walk_state->arg_count);
769
770         } while (op);
771
772         return_ACPI_STATUS (status);
773 }
774
775