aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/parser/psloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/parser/psloop.c')
-rw-r--r--drivers/acpi/parser/psloop.c781
1 files changed, 781 insertions, 0 deletions
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
new file mode 100644
index 000000000000..551d54bdbec3
--- /dev/null
+++ b/drivers/acpi/parser/psloop.c
@@ -0,0 +1,781 @@
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
62static 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
78acpi_status
79acpi_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
568close_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