Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: psobject - Support for parse objects
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "amlcode.h"
0014 #include "acconvert.h"
0015 #include "acnamesp.h"
0016 
0017 #define _COMPONENT          ACPI_PARSER
0018 ACPI_MODULE_NAME("psobject")
0019 
0020 /* Local prototypes */
0021 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
0022 
0023 /*******************************************************************************
0024  *
0025  * FUNCTION:    acpi_ps_get_aml_opcode
0026  *
0027  * PARAMETERS:  walk_state          - Current state
0028  *
0029  * RETURN:      Status
0030  *
0031  * DESCRIPTION: Extract the next AML opcode from the input stream.
0032  *
0033  ******************************************************************************/
0034 
0035 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
0036 {
0037     ACPI_ERROR_ONLY(u32 aml_offset);
0038 
0039     ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
0040 
0041     walk_state->aml = walk_state->parser_state.aml;
0042     walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
0043 
0044     /*
0045      * First cut to determine what we have found:
0046      * 1) A valid AML opcode
0047      * 2) A name string
0048      * 3) An unknown/invalid opcode
0049      */
0050     walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
0051 
0052     switch (walk_state->op_info->class) {
0053     case AML_CLASS_ASCII:
0054     case AML_CLASS_PREFIX:
0055         /*
0056          * Starts with a valid prefix or ASCII char, this is a name
0057          * string. Convert the bare name string to a namepath.
0058          */
0059         walk_state->opcode = AML_INT_NAMEPATH_OP;
0060         walk_state->arg_types = ARGP_NAMESTRING;
0061         break;
0062 
0063     case AML_CLASS_UNKNOWN:
0064 
0065         /* The opcode is unrecognized. Complain and skip unknown opcodes */
0066 
0067         if (walk_state->pass_number == 2) {
0068             ACPI_ERROR_ONLY(aml_offset =
0069                     (u32)ACPI_PTR_DIFF(walk_state->aml,
0070                                walk_state->
0071                                parser_state.
0072                                aml_start));
0073 
0074             ACPI_ERROR((AE_INFO,
0075                     "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
0076                     walk_state->opcode,
0077                     (u32)(aml_offset +
0078                       sizeof(struct acpi_table_header))));
0079 
0080             ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
0081                      48);
0082 
0083 #ifdef ACPI_ASL_COMPILER
0084             /*
0085              * This is executed for the disassembler only. Output goes
0086              * to the disassembled ASL output file.
0087              */
0088             acpi_os_printf
0089                 ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
0090                  walk_state->opcode,
0091                  (u32)(aml_offset +
0092                    sizeof(struct acpi_table_header)));
0093 
0094             ACPI_ERROR((AE_INFO,
0095                     "Aborting disassembly, AML byte code is corrupt"));
0096 
0097             /* Dump the context surrounding the invalid opcode */
0098 
0099             acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
0100                          aml - 16), 48, DB_BYTE_DISPLAY,
0101                         (aml_offset +
0102                          sizeof(struct acpi_table_header) -
0103                          16));
0104             acpi_os_printf(" */\n");
0105 
0106             /*
0107              * Just abort the disassembly, cannot continue because the
0108              * parser is essentially lost. The disassembler can then
0109              * randomly fail because an ill-constructed parse tree
0110              * can result.
0111              */
0112             return_ACPI_STATUS(AE_AML_BAD_OPCODE);
0113 #endif
0114         }
0115 
0116         /* Increment past one-byte or two-byte opcode */
0117 
0118         walk_state->parser_state.aml++;
0119         if (walk_state->opcode > 0xFF) {    /* Can only happen if first byte is 0x5B */
0120             walk_state->parser_state.aml++;
0121         }
0122 
0123         return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0124 
0125     default:
0126 
0127         /* Found opcode info, this is a normal opcode */
0128 
0129         walk_state->parser_state.aml +=
0130             acpi_ps_get_opcode_size(walk_state->opcode);
0131         walk_state->arg_types = walk_state->op_info->parse_args;
0132         break;
0133     }
0134 
0135     return_ACPI_STATUS(AE_OK);
0136 }
0137 
0138 /*******************************************************************************
0139  *
0140  * FUNCTION:    acpi_ps_build_named_op
0141  *
0142  * PARAMETERS:  walk_state          - Current state
0143  *              aml_op_start        - Begin of named Op in AML
0144  *              unnamed_op          - Early Op (not a named Op)
0145  *              op                  - Returned Op
0146  *
0147  * RETURN:      Status
0148  *
0149  * DESCRIPTION: Parse a named Op
0150  *
0151  ******************************************************************************/
0152 
0153 acpi_status
0154 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
0155                u8 *aml_op_start,
0156                union acpi_parse_object *unnamed_op,
0157                union acpi_parse_object **op)
0158 {
0159     acpi_status status = AE_OK;
0160     union acpi_parse_object *arg = NULL;
0161 
0162     ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
0163 
0164     unnamed_op->common.value.arg = NULL;
0165     unnamed_op->common.arg_list_length = 0;
0166     unnamed_op->common.aml_opcode = walk_state->opcode;
0167 
0168     /*
0169      * Get and append arguments until we find the node that contains
0170      * the name (the type ARGP_NAME).
0171      */
0172     while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
0173            (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
0174         ASL_CV_CAPTURE_COMMENTS(walk_state);
0175         status =
0176             acpi_ps_get_next_arg(walk_state,
0177                      &(walk_state->parser_state),
0178                      GET_CURRENT_ARG_TYPE(walk_state->
0179                                   arg_types), &arg);
0180         if (ACPI_FAILURE(status)) {
0181             return_ACPI_STATUS(status);
0182         }
0183 
0184         acpi_ps_append_arg(unnamed_op, arg);
0185         INCREMENT_ARG_LIST(walk_state->arg_types);
0186     }
0187 
0188     /* are there any inline comments associated with the name_seg?? If so, save this. */
0189 
0190     ASL_CV_CAPTURE_COMMENTS(walk_state);
0191 
0192 #ifdef ACPI_ASL_COMPILER
0193     if (acpi_gbl_current_inline_comment != NULL) {
0194         unnamed_op->common.name_comment =
0195             acpi_gbl_current_inline_comment;
0196         acpi_gbl_current_inline_comment = NULL;
0197     }
0198 #endif
0199 
0200     /*
0201      * Make sure that we found a NAME and didn't run out of arguments
0202      */
0203     if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
0204         return_ACPI_STATUS(AE_AML_NO_OPERAND);
0205     }
0206 
0207     /* We know that this arg is a name, move to next arg */
0208 
0209     INCREMENT_ARG_LIST(walk_state->arg_types);
0210 
0211     /*
0212      * Find the object. This will either insert the object into
0213      * the namespace or simply look it up
0214      */
0215     walk_state->op = NULL;
0216 
0217     status = walk_state->descending_callback(walk_state, op);
0218     if (ACPI_FAILURE(status)) {
0219         if (status != AE_CTRL_TERMINATE) {
0220             ACPI_EXCEPTION((AE_INFO, status,
0221                     "During name lookup/catalog"));
0222         }
0223         return_ACPI_STATUS(status);
0224     }
0225 
0226     if (!*op) {
0227         return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0228     }
0229 
0230     status = acpi_ps_next_parse_state(walk_state, *op, status);
0231     if (ACPI_FAILURE(status)) {
0232         if (status == AE_CTRL_PENDING) {
0233             status = AE_CTRL_PARSE_PENDING;
0234         }
0235         return_ACPI_STATUS(status);
0236     }
0237 
0238     acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
0239 
0240 #ifdef ACPI_ASL_COMPILER
0241 
0242     /* save any comments that might be associated with unnamed_op. */
0243 
0244     (*op)->common.inline_comment = unnamed_op->common.inline_comment;
0245     (*op)->common.end_node_comment = unnamed_op->common.end_node_comment;
0246     (*op)->common.close_brace_comment =
0247         unnamed_op->common.close_brace_comment;
0248     (*op)->common.name_comment = unnamed_op->common.name_comment;
0249     (*op)->common.comment_list = unnamed_op->common.comment_list;
0250     (*op)->common.end_blk_comment = unnamed_op->common.end_blk_comment;
0251     (*op)->common.cv_filename = unnamed_op->common.cv_filename;
0252     (*op)->common.cv_parent_filename =
0253         unnamed_op->common.cv_parent_filename;
0254     (*op)->named.aml = unnamed_op->common.aml;
0255 
0256     unnamed_op->common.inline_comment = NULL;
0257     unnamed_op->common.end_node_comment = NULL;
0258     unnamed_op->common.close_brace_comment = NULL;
0259     unnamed_op->common.name_comment = NULL;
0260     unnamed_op->common.comment_list = NULL;
0261     unnamed_op->common.end_blk_comment = NULL;
0262 #endif
0263 
0264     if ((*op)->common.aml_opcode == AML_REGION_OP ||
0265         (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
0266         /*
0267          * Defer final parsing of an operation_region body, because we don't
0268          * have enough info in the first pass to parse it correctly (i.e.,
0269          * there may be method calls within the term_arg elements of the body.)
0270          *
0271          * However, we must continue parsing because the opregion is not a
0272          * standalone package -- we don't know where the end is at this point.
0273          *
0274          * (Length is unknown until parse of the body complete)
0275          */
0276         (*op)->named.data = aml_op_start;
0277         (*op)->named.length = 0;
0278     }
0279 
0280     return_ACPI_STATUS(AE_OK);
0281 }
0282 
0283 /*******************************************************************************
0284  *
0285  * FUNCTION:    acpi_ps_create_op
0286  *
0287  * PARAMETERS:  walk_state          - Current state
0288  *              aml_op_start        - Op start in AML
0289  *              new_op              - Returned Op
0290  *
0291  * RETURN:      Status
0292  *
0293  * DESCRIPTION: Get Op from AML
0294  *
0295  ******************************************************************************/
0296 
0297 acpi_status
0298 acpi_ps_create_op(struct acpi_walk_state *walk_state,
0299           u8 *aml_op_start, union acpi_parse_object **new_op)
0300 {
0301     acpi_status status = AE_OK;
0302     union acpi_parse_object *op;
0303     union acpi_parse_object *named_op = NULL;
0304     union acpi_parse_object *parent_scope;
0305     u8 argument_count;
0306     const struct acpi_opcode_info *op_info;
0307 
0308     ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
0309 
0310     status = acpi_ps_get_aml_opcode(walk_state);
0311     if (status == AE_CTRL_PARSE_CONTINUE) {
0312         return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0313     }
0314     if (ACPI_FAILURE(status)) {
0315         return_ACPI_STATUS(status);
0316     }
0317 
0318     /* Create Op structure and append to parent's argument list */
0319 
0320     walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
0321     op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
0322     if (!op) {
0323         return_ACPI_STATUS(AE_NO_MEMORY);
0324     }
0325 
0326     if (walk_state->op_info->flags & AML_NAMED) {
0327         status =
0328             acpi_ps_build_named_op(walk_state, aml_op_start, op,
0329                        &named_op);
0330         acpi_ps_free_op(op);
0331 
0332 #ifdef ACPI_ASL_COMPILER
0333         if (acpi_gbl_disasm_flag
0334             && walk_state->opcode == AML_EXTERNAL_OP
0335             && status == AE_NOT_FOUND) {
0336             /*
0337              * If parsing of AML_EXTERNAL_OP's name path fails, then skip
0338              * past this opcode and keep parsing. This is a much better
0339              * alternative than to abort the entire disassembler. At this
0340              * point, the parser_state is at the end of the namepath of the
0341              * external declaration opcode. Setting walk_state->Aml to
0342              * walk_state->parser_state.Aml + 2 moves increments the
0343              * walk_state->Aml past the object type and the paramcount of the
0344              * external opcode.
0345              */
0346             walk_state->aml = walk_state->parser_state.aml + 2;
0347             walk_state->parser_state.aml = walk_state->aml;
0348             return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
0349         }
0350 #endif
0351         if (ACPI_FAILURE(status)) {
0352             return_ACPI_STATUS(status);
0353         }
0354 
0355         *new_op = named_op;
0356         return_ACPI_STATUS(AE_OK);
0357     }
0358 
0359     /* Not a named opcode, just allocate Op and append to parent */
0360 
0361     if (walk_state->op_info->flags & AML_CREATE) {
0362         /*
0363          * Backup to beginning of create_XXXfield declaration
0364          * body_length is unknown until we parse the body
0365          */
0366         op->named.data = aml_op_start;
0367         op->named.length = 0;
0368     }
0369 
0370     if (walk_state->opcode == AML_BANK_FIELD_OP) {
0371         /*
0372          * Backup to beginning of bank_field declaration
0373          * body_length is unknown until we parse the body
0374          */
0375         op->named.data = aml_op_start;
0376         op->named.length = 0;
0377     }
0378 
0379     parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
0380     acpi_ps_append_arg(parent_scope, op);
0381 
0382     if (parent_scope) {
0383         op_info =
0384             acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
0385         if (op_info->flags & AML_HAS_TARGET) {
0386             argument_count =
0387                 acpi_ps_get_argument_count(op_info->type);
0388             if (parent_scope->common.arg_list_length >
0389                 argument_count) {
0390                 op->common.flags |= ACPI_PARSEOP_TARGET;
0391             }
0392         }
0393 
0394         /*
0395          * Special case for both Increment() and Decrement(), where
0396          * the lone argument is both a source and a target.
0397          */
0398         else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
0399              || (parent_scope->common.aml_opcode ==
0400                  AML_DECREMENT_OP)) {
0401             op->common.flags |= ACPI_PARSEOP_TARGET;
0402         }
0403     }
0404 
0405     if (walk_state->descending_callback != NULL) {
0406         /*
0407          * Find the object. This will either insert the object into
0408          * the namespace or simply look it up
0409          */
0410         walk_state->op = *new_op = op;
0411 
0412         status = walk_state->descending_callback(walk_state, &op);
0413         status = acpi_ps_next_parse_state(walk_state, op, status);
0414         if (status == AE_CTRL_PENDING) {
0415             status = AE_CTRL_PARSE_PENDING;
0416         }
0417     }
0418 
0419     return_ACPI_STATUS(status);
0420 }
0421 
0422 /*******************************************************************************
0423  *
0424  * FUNCTION:    acpi_ps_complete_op
0425  *
0426  * PARAMETERS:  walk_state          - Current state
0427  *              op                  - Returned Op
0428  *              status              - Parse status before complete Op
0429  *
0430  * RETURN:      Status
0431  *
0432  * DESCRIPTION: Complete Op
0433  *
0434  ******************************************************************************/
0435 
0436 acpi_status
0437 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
0438             union acpi_parse_object **op, acpi_status status)
0439 {
0440     acpi_status status2;
0441 
0442     ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
0443 
0444     /*
0445      * Finished one argument of the containing scope
0446      */
0447     walk_state->parser_state.scope->parse_scope.arg_count--;
0448 
0449     /* Close this Op (will result in parse subtree deletion) */
0450 
0451     status2 = acpi_ps_complete_this_op(walk_state, *op);
0452     if (ACPI_FAILURE(status2)) {
0453         return_ACPI_STATUS(status2);
0454     }
0455 
0456     *op = NULL;
0457 
0458     switch (status) {
0459     case AE_OK:
0460 
0461         break;
0462 
0463     case AE_CTRL_TRANSFER:
0464 
0465         /* We are about to transfer to a called method */
0466 
0467         walk_state->prev_op = NULL;
0468         walk_state->prev_arg_types = walk_state->arg_types;
0469         return_ACPI_STATUS(status);
0470 
0471     case AE_CTRL_END:
0472 
0473         acpi_ps_pop_scope(&(walk_state->parser_state), op,
0474                   &walk_state->arg_types,
0475                   &walk_state->arg_count);
0476 
0477         if (*op) {
0478             walk_state->op = *op;
0479             walk_state->op_info =
0480                 acpi_ps_get_opcode_info((*op)->common.aml_opcode);
0481             walk_state->opcode = (*op)->common.aml_opcode;
0482 
0483             status = walk_state->ascending_callback(walk_state);
0484             (void)acpi_ps_next_parse_state(walk_state, *op, status);
0485 
0486             status2 = acpi_ps_complete_this_op(walk_state, *op);
0487             if (ACPI_FAILURE(status2)) {
0488                 return_ACPI_STATUS(status2);
0489             }
0490         }
0491 
0492         break;
0493 
0494     case AE_CTRL_BREAK:
0495     case AE_CTRL_CONTINUE:
0496 
0497         /* Pop off scopes until we find the While */
0498 
0499         while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
0500             acpi_ps_pop_scope(&(walk_state->parser_state), op,
0501                       &walk_state->arg_types,
0502                       &walk_state->arg_count);
0503         }
0504 
0505         /* Close this iteration of the While loop */
0506 
0507         walk_state->op = *op;
0508         walk_state->op_info =
0509             acpi_ps_get_opcode_info((*op)->common.aml_opcode);
0510         walk_state->opcode = (*op)->common.aml_opcode;
0511 
0512         status = walk_state->ascending_callback(walk_state);
0513         (void)acpi_ps_next_parse_state(walk_state, *op, status);
0514 
0515         status2 = acpi_ps_complete_this_op(walk_state, *op);
0516         if (ACPI_FAILURE(status2)) {
0517             return_ACPI_STATUS(status2);
0518         }
0519 
0520         break;
0521 
0522     case AE_CTRL_TERMINATE:
0523 
0524         /* Clean up */
0525         do {
0526             if (*op) {
0527                 status2 =
0528                     acpi_ps_complete_this_op(walk_state, *op);
0529                 if (ACPI_FAILURE(status2)) {
0530                     return_ACPI_STATUS(status2);
0531                 }
0532 
0533                 acpi_ut_delete_generic_state
0534                     (acpi_ut_pop_generic_state
0535                      (&walk_state->control_state));
0536             }
0537 
0538             acpi_ps_pop_scope(&(walk_state->parser_state), op,
0539                       &walk_state->arg_types,
0540                       &walk_state->arg_count);
0541 
0542         } while (*op);
0543 
0544         return_ACPI_STATUS(AE_OK);
0545 
0546     default:        /* All other non-AE_OK status */
0547 
0548         do {
0549             if (*op) {
0550                 /*
0551                  * These Opcodes need to be removed from the namespace because they
0552                  * get created even if these opcodes cannot be created due to
0553                  * errors.
0554                  */
0555                 if (((*op)->common.aml_opcode == AML_REGION_OP)
0556                     || ((*op)->common.aml_opcode ==
0557                     AML_DATA_REGION_OP)) {
0558                     acpi_ns_delete_children((*op)->common.
0559                                 node);
0560                     acpi_ns_remove_node((*op)->common.node);
0561                     (*op)->common.node = NULL;
0562                     acpi_ps_delete_parse_tree(*op);
0563                 }
0564 
0565                 status2 =
0566                     acpi_ps_complete_this_op(walk_state, *op);
0567                 if (ACPI_FAILURE(status2)) {
0568                     return_ACPI_STATUS(status2);
0569                 }
0570             }
0571 
0572             acpi_ps_pop_scope(&(walk_state->parser_state), op,
0573                       &walk_state->arg_types,
0574                       &walk_state->arg_count);
0575 
0576         } while (*op);
0577 
0578 #if 0
0579         /*
0580          * TBD: Cleanup parse ops on error
0581          */
0582         if (*op == NULL) {
0583             acpi_ps_pop_scope(parser_state, op,
0584                       &walk_state->arg_types,
0585                       &walk_state->arg_count);
0586         }
0587 #endif
0588         walk_state->prev_op = NULL;
0589         walk_state->prev_arg_types = walk_state->arg_types;
0590 
0591         if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
0592             /*
0593              * There was something that went wrong while executing code at the
0594              * module-level. We need to skip parsing whatever caused the
0595              * error and keep going. One runtime error during the table load
0596              * should not cause the entire table to not be loaded. This is
0597              * because there could be correct AML beyond the parts that caused
0598              * the runtime error.
0599              */
0600             ACPI_INFO(("Ignoring error and continuing table load"));
0601             return_ACPI_STATUS(AE_OK);
0602         }
0603         return_ACPI_STATUS(status);
0604     }
0605 
0606     /* This scope complete? */
0607 
0608     if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
0609         acpi_ps_pop_scope(&(walk_state->parser_state), op,
0610                   &walk_state->arg_types,
0611                   &walk_state->arg_count);
0612         ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
0613     } else {
0614         *op = NULL;
0615     }
0616 
0617     return_ACPI_STATUS(AE_OK);
0618 }
0619 
0620 /*******************************************************************************
0621  *
0622  * FUNCTION:    acpi_ps_complete_final_op
0623  *
0624  * PARAMETERS:  walk_state          - Current state
0625  *              op                  - Current Op
0626  *              status              - Current parse status before complete last
0627  *                                    Op
0628  *
0629  * RETURN:      Status
0630  *
0631  * DESCRIPTION: Complete last Op.
0632  *
0633  ******************************************************************************/
0634 
0635 acpi_status
0636 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
0637               union acpi_parse_object *op, acpi_status status)
0638 {
0639     acpi_status status2;
0640 
0641     ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
0642 
0643     /*
0644      * Complete the last Op (if not completed), and clear the scope stack.
0645      * It is easily possible to end an AML "package" with an unbounded number
0646      * of open scopes (such as when several ASL blocks are closed with
0647      * sequential closing braces). We want to terminate each one cleanly.
0648      */
0649     ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
0650               op));
0651     do {
0652         if (op) {
0653             if (walk_state->ascending_callback != NULL) {
0654                 walk_state->op = op;
0655                 walk_state->op_info =
0656                     acpi_ps_get_opcode_info(op->common.
0657                                 aml_opcode);
0658                 walk_state->opcode = op->common.aml_opcode;
0659 
0660                 status =
0661                     walk_state->ascending_callback(walk_state);
0662                 status =
0663                     acpi_ps_next_parse_state(walk_state, op,
0664                                  status);
0665                 if (status == AE_CTRL_PENDING) {
0666                     status =
0667                         acpi_ps_complete_op(walk_state, &op,
0668                                 AE_OK);
0669                     if (ACPI_FAILURE(status)) {
0670                         return_ACPI_STATUS(status);
0671                     }
0672                 }
0673 
0674                 if (status == AE_CTRL_TERMINATE) {
0675                     status = AE_OK;
0676 
0677                     /* Clean up */
0678                     do {
0679                         if (op) {
0680                             status2 =
0681                                 acpi_ps_complete_this_op
0682                                 (walk_state, op);
0683                             if (ACPI_FAILURE
0684                                 (status2)) {
0685                                 return_ACPI_STATUS
0686                                     (status2);
0687                             }
0688                         }
0689 
0690                         acpi_ps_pop_scope(&
0691                                   (walk_state->
0692                                    parser_state),
0693                                   &op,
0694                                   &walk_state->
0695                                   arg_types,
0696                                   &walk_state->
0697                                   arg_count);
0698 
0699                     } while (op);
0700 
0701                     return_ACPI_STATUS(status);
0702                 }
0703 
0704                 else if (ACPI_FAILURE(status)) {
0705 
0706                     /* First error is most important */
0707 
0708                     (void)
0709                         acpi_ps_complete_this_op(walk_state,
0710                                      op);
0711                     return_ACPI_STATUS(status);
0712                 }
0713             }
0714 
0715             status2 = acpi_ps_complete_this_op(walk_state, op);
0716             if (ACPI_FAILURE(status2)) {
0717                 return_ACPI_STATUS(status2);
0718             }
0719         }
0720 
0721         acpi_ps_pop_scope(&(walk_state->parser_state), &op,
0722                   &walk_state->arg_types,
0723                   &walk_state->arg_count);
0724 
0725     } while (op);
0726 
0727     return_ACPI_STATUS(status);
0728 }