Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: psloop - Main AML parse loop
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /*
  8.  * Copyright (C) 2000 - 2015, Intel Corp.
  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.  * Parse the AML and build an operation tree as most interpreters, (such as
  46.  * Perl) do. Parsing is done by hand rather than with a YACC generated parser
  47.  * to tightly constrain stack and dynamic memory usage. Parsing is kept
  48.  * flexible and the code fairly compact by parsing based on a list of AML
  49.  * opcode templates in aml_op_info[].
  50.  */
  51.  
  52. #include <acpi/acpi.h>
  53. #include "accommon.h"
  54. #include "acinterp.h"
  55. #include "acparser.h"
  56. #include "acdispat.h"
  57. #include "amlcode.h"
  58.  
  59. #define _COMPONENT          ACPI_PARSER
  60. ACPI_MODULE_NAME("psloop")
  61.  
  62. /* Local prototypes */
  63. static acpi_status
  64. acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
  65.                       u8 * aml_op_start, union acpi_parse_object *op);
  66.  
  67. static void
  68. acpi_ps_link_module_code(union acpi_parse_object *parent_op,
  69.                          u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
  70.  
  71. /*******************************************************************************
  72.  *
  73.  * FUNCTION:    acpi_ps_get_arguments
  74.  *
  75.  * PARAMETERS:  walk_state          - Current state
  76.  *              aml_op_start        - Op start in AML
  77.  *              op                  - Current Op
  78.  *
  79.  * RETURN:      Status
  80.  *
  81.  * DESCRIPTION: Get arguments for passed Op.
  82.  *
  83.  ******************************************************************************/
  84.  
  85. static acpi_status
  86. acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
  87.                       u8 * aml_op_start, union acpi_parse_object *op)
  88. {
  89.         acpi_status status = AE_OK;
  90.         union acpi_parse_object *arg = NULL;
  91.         const struct acpi_opcode_info *op_info;
  92.  
  93.         ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state);
  94.  
  95.         switch (op->common.aml_opcode) {
  96.         case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
  97.         case AML_WORD_OP:       /* AML_WORDDATA_ARG */
  98.         case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
  99.         case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
  100.         case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
  101.  
  102.                 /* Fill in constant or string argument directly */
  103.  
  104.                 acpi_ps_get_next_simple_arg(&(walk_state->parser_state),
  105.                                             GET_CURRENT_ARG_TYPE(walk_state->
  106.                                                                  arg_types),
  107.                                             op);
  108.                 break;
  109.  
  110.         case AML_INT_NAMEPATH_OP:       /* AML_NAMESTRING_ARG */
  111.  
  112.                 status =
  113.                     acpi_ps_get_next_namepath(walk_state,
  114.                                               &(walk_state->parser_state), op,
  115.                                               1);
  116.                 if (ACPI_FAILURE(status)) {
  117.                         return_ACPI_STATUS(status);
  118.                 }
  119.  
  120.                 walk_state->arg_types = 0;
  121.                 break;
  122.  
  123.         default:
  124.                 /*
  125.                  * Op is not a constant or string, append each argument to the Op
  126.                  */
  127.                 while (GET_CURRENT_ARG_TYPE(walk_state->arg_types)
  128.                        && !walk_state->arg_count) {
  129.                         walk_state->aml = walk_state->parser_state.aml;
  130.  
  131.                         status =
  132.                             acpi_ps_get_next_arg(walk_state,
  133.                                                  &(walk_state->parser_state),
  134.                                                  GET_CURRENT_ARG_TYPE
  135.                                                  (walk_state->arg_types), &arg);
  136.                         if (ACPI_FAILURE(status)) {
  137.                                 return_ACPI_STATUS(status);
  138.                         }
  139.  
  140.                         if (arg) {
  141.                                 acpi_ps_append_arg(op, arg);
  142.                         }
  143.  
  144.                         INCREMENT_ARG_LIST(walk_state->arg_types);
  145.                 }
  146.  
  147.                 /*
  148.                  * Handle executable code at "module-level". This refers to
  149.                  * executable opcodes that appear outside of any control method.
  150.                  */
  151.                 if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) &&
  152.                     ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) {
  153.                         /*
  154.                          * We want to skip If/Else/While constructs during Pass1 because we
  155.                          * want to actually conditionally execute the code during Pass2.
  156.                          *
  157.                          * Except for disassembly, where we always want to walk the
  158.                          * If/Else/While packages
  159.                          */
  160.                         switch (op->common.aml_opcode) {
  161.                         case AML_IF_OP:
  162.                         case AML_ELSE_OP:
  163.                         case AML_WHILE_OP:
  164.                                 /*
  165.                                  * Currently supported module-level opcodes are:
  166.                                  * IF/ELSE/WHILE. These appear to be the most common,
  167.                                  * and easiest to support since they open an AML
  168.                                  * package.
  169.                                  */
  170.                                 if (walk_state->pass_number ==
  171.                                     ACPI_IMODE_LOAD_PASS1) {
  172.                                         acpi_ps_link_module_code(op->common.
  173.                                                                  parent,
  174.                                                                  aml_op_start,
  175.                                                                  (u32)
  176.                                                                  (walk_state->
  177.                                                                  parser_state.
  178.                                                                  pkg_end -
  179.                                                                  aml_op_start),
  180.                                                                  walk_state->
  181.                                                                  owner_id);
  182.                                 }
  183.  
  184.                                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  185.                                                   "Pass1: Skipping an If/Else/While body\n"));
  186.  
  187.                                 /* Skip body of if/else/while in pass 1 */
  188.  
  189.                                 walk_state->parser_state.aml =
  190.                                     walk_state->parser_state.pkg_end;
  191.                                 walk_state->arg_count = 0;
  192.                                 break;
  193.  
  194.                         default:
  195.                                 /*
  196.                                  * Check for an unsupported executable opcode at module
  197.                                  * level. We must be in PASS1, the parent must be a SCOPE,
  198.                                  * The opcode class must be EXECUTE, and the opcode must
  199.                                  * not be an argument to another opcode.
  200.                                  */
  201.                                 if ((walk_state->pass_number ==
  202.                                      ACPI_IMODE_LOAD_PASS1)
  203.                                     && (op->common.parent->common.aml_opcode ==
  204.                                         AML_SCOPE_OP)) {
  205.                                         op_info =
  206.                                             acpi_ps_get_opcode_info(op->common.
  207.                                                                     aml_opcode);
  208.                                         if ((op_info->class ==
  209.                                              AML_CLASS_EXECUTE) && (!arg)) {
  210.                                                 ACPI_WARNING((AE_INFO,
  211.                                                               "Unsupported module-level executable opcode "
  212.                                                               "0x%.2X at table offset 0x%.4X",
  213.                                                               op->common.
  214.                                                               aml_opcode,
  215.                                                               (u32)
  216.                                                               (ACPI_PTR_DIFF
  217.                                                                (aml_op_start,
  218.                                                                 walk_state->
  219.                                                                 parser_state.
  220.                                                                 aml_start) +
  221.                                                                sizeof(struct
  222.                                                                       acpi_table_header))));
  223.                                         }
  224.                                 }
  225.                                 break;
  226.                         }
  227.                 }
  228.  
  229.                 /* Special processing for certain opcodes */
  230.  
  231.                 switch (op->common.aml_opcode) {
  232.                 case AML_METHOD_OP:
  233.                         /*
  234.                          * Skip parsing of control method because we don't have enough
  235.                          * info in the first pass to parse it correctly.
  236.                          *
  237.                          * Save the length and address of the body
  238.                          */
  239.                         op->named.data = walk_state->parser_state.aml;
  240.                         op->named.length = (u32)
  241.                             (walk_state->parser_state.pkg_end -
  242.                              walk_state->parser_state.aml);
  243.  
  244.                         /* Skip body of method */
  245.  
  246.                         walk_state->parser_state.aml =
  247.                             walk_state->parser_state.pkg_end;
  248.                         walk_state->arg_count = 0;
  249.                         break;
  250.  
  251.                 case AML_BUFFER_OP:
  252.                 case AML_PACKAGE_OP:
  253.                 case AML_VAR_PACKAGE_OP:
  254.  
  255.                         if ((op->common.parent) &&
  256.                             (op->common.parent->common.aml_opcode ==
  257.                              AML_NAME_OP)
  258.                             && (walk_state->pass_number <=
  259.                                 ACPI_IMODE_LOAD_PASS2)) {
  260.                                 /*
  261.                                  * Skip parsing of Buffers and Packages because we don't have
  262.                                  * enough info in the first pass to parse them correctly.
  263.                                  */
  264.                                 op->named.data = aml_op_start;
  265.                                 op->named.length = (u32)
  266.                                     (walk_state->parser_state.pkg_end -
  267.                                      aml_op_start);
  268.  
  269.                                 /* Skip body */
  270.  
  271.                                 walk_state->parser_state.aml =
  272.                                     walk_state->parser_state.pkg_end;
  273.                                 walk_state->arg_count = 0;
  274.                         }
  275.                         break;
  276.  
  277.                 case AML_WHILE_OP:
  278.  
  279.                         if (walk_state->control_state) {
  280.                                 walk_state->control_state->control.package_end =
  281.                                     walk_state->parser_state.pkg_end;
  282.                         }
  283.                         break;
  284.  
  285.                 default:
  286.  
  287.                         /* No action for all other opcodes */
  288.  
  289.                         break;
  290.                 }
  291.  
  292.                 break;
  293.         }
  294.  
  295.         return_ACPI_STATUS(AE_OK);
  296. }
  297.  
  298. /*******************************************************************************
  299.  *
  300.  * FUNCTION:    acpi_ps_link_module_code
  301.  *
  302.  * PARAMETERS:  parent_op           - Parent parser op
  303.  *              aml_start           - Pointer to the AML
  304.  *              aml_length          - Length of executable AML
  305.  *              owner_id            - owner_id of module level code
  306.  *
  307.  * RETURN:      None.
  308.  *
  309.  * DESCRIPTION: Wrap the module-level code with a method object and link the
  310.  *              object to the global list. Note, the mutex field of the method
  311.  *              object is used to link multiple module-level code objects.
  312.  *
  313.  ******************************************************************************/
  314.  
  315. static void
  316. acpi_ps_link_module_code(union acpi_parse_object *parent_op,
  317.                          u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
  318. {
  319.         union acpi_operand_object *prev;
  320.         union acpi_operand_object *next;
  321.         union acpi_operand_object *method_obj;
  322.         struct acpi_namespace_node *parent_node;
  323.  
  324.         ACPI_FUNCTION_TRACE(ps_link_module_code);
  325.  
  326.         /* Get the tail of the list */
  327.  
  328.         prev = next = acpi_gbl_module_code_list;
  329.         while (next) {
  330.                 prev = next;
  331.                 next = next->method.mutex;
  332.         }
  333.  
  334.         /*
  335.          * Insert the module level code into the list. Merge it if it is
  336.          * adjacent to the previous element.
  337.          */
  338.         if (!prev ||
  339.             ((prev->method.aml_start + prev->method.aml_length) != aml_start)) {
  340.  
  341.                 /* Create, initialize, and link a new temporary method object */
  342.  
  343.                 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
  344.                 if (!method_obj) {
  345.                         return_VOID;
  346.                 }
  347.  
  348.                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  349.                                   "Create/Link new code block: %p\n",
  350.                                   method_obj));
  351.  
  352.                 if (parent_op->common.node) {
  353.                         parent_node = parent_op->common.node;
  354.                 } else {
  355.                         parent_node = acpi_gbl_root_node;
  356.                 }
  357.  
  358.                 method_obj->method.aml_start = aml_start;
  359.                 method_obj->method.aml_length = aml_length;
  360.                 method_obj->method.owner_id = owner_id;
  361.                 method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
  362.  
  363.                 /*
  364.                  * Save the parent node in next_object. This is cheating, but we
  365.                  * don't want to expand the method object.
  366.                  */
  367.                 method_obj->method.next_object =
  368.                     ACPI_CAST_PTR(union acpi_operand_object, parent_node);
  369.  
  370.                 if (!prev) {
  371.                         acpi_gbl_module_code_list = method_obj;
  372.                 } else {
  373.                         prev->method.mutex = method_obj;
  374.                 }
  375.         } else {
  376.                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  377.                                   "Appending to existing code block: %p\n",
  378.                                   prev));
  379.  
  380.                 prev->method.aml_length += aml_length;
  381.         }
  382.  
  383.         return_VOID;
  384. }
  385.  
  386. /*******************************************************************************
  387.  *
  388.  * FUNCTION:    acpi_ps_parse_loop
  389.  *
  390.  * PARAMETERS:  walk_state          - Current state
  391.  *
  392.  * RETURN:      Status
  393.  *
  394.  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
  395.  *              a tree of ops.
  396.  *
  397.  ******************************************************************************/
  398.  
  399. acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
  400. {
  401.         acpi_status status = AE_OK;
  402.         union acpi_parse_object *op = NULL;     /* current op */
  403.         struct acpi_parse_state *parser_state;
  404.         u8 *aml_op_start = NULL;
  405.  
  406.         ACPI_FUNCTION_TRACE_PTR(ps_parse_loop, walk_state);
  407.  
  408.         if (walk_state->descending_callback == NULL) {
  409.                 return_ACPI_STATUS(AE_BAD_PARAMETER);
  410.         }
  411.  
  412.         parser_state = &walk_state->parser_state;
  413.         walk_state->arg_types = 0;
  414.  
  415. #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
  416.  
  417.         if (walk_state->walk_type & ACPI_WALK_METHOD_RESTART) {
  418.  
  419.                 /* We are restarting a preempted control method */
  420.  
  421.                 if (acpi_ps_has_completed_scope(parser_state)) {
  422.                         /*
  423.                          * We must check if a predicate to an IF or WHILE statement
  424.                          * was just completed
  425.                          */
  426.                         if ((parser_state->scope->parse_scope.op) &&
  427.                             ((parser_state->scope->parse_scope.op->common.
  428.                               aml_opcode == AML_IF_OP)
  429.                              || (parser_state->scope->parse_scope.op->common.
  430.                                  aml_opcode == AML_WHILE_OP))
  431.                             && (walk_state->control_state)
  432.                             && (walk_state->control_state->common.state ==
  433.                                 ACPI_CONTROL_PREDICATE_EXECUTING)) {
  434.                                 /*
  435.                                  * A predicate was just completed, get the value of the
  436.                                  * predicate and branch based on that value
  437.                                  */
  438.                                 walk_state->op = NULL;
  439.                                 status =
  440.                                     acpi_ds_get_predicate_value(walk_state,
  441.                                                                 ACPI_TO_POINTER
  442.                                                                 (TRUE));
  443.                                 if (ACPI_FAILURE(status)
  444.                                     && ((status & AE_CODE_MASK) !=
  445.                                         AE_CODE_CONTROL)) {
  446.                                         if (status == AE_AML_NO_RETURN_VALUE) {
  447.                                                 ACPI_EXCEPTION((AE_INFO, status,
  448.                                                                 "Invoked method did not return a value"));
  449.                                         }
  450.  
  451.                                         ACPI_EXCEPTION((AE_INFO, status,
  452.                                                         "GetPredicate Failed"));
  453.                                         return_ACPI_STATUS(status);
  454.                                 }
  455.  
  456.                                 status =
  457.                                     acpi_ps_next_parse_state(walk_state, op,
  458.                                                              status);
  459.                         }
  460.  
  461.                         acpi_ps_pop_scope(parser_state, &op,
  462.                                           &walk_state->arg_types,
  463.                                           &walk_state->arg_count);
  464.                         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
  465.                                           "Popped scope, Op=%p\n", op));
  466.                 } else if (walk_state->prev_op) {
  467.  
  468.                         /* We were in the middle of an op */
  469.  
  470.                         op = walk_state->prev_op;
  471.                         walk_state->arg_types = walk_state->prev_arg_types;
  472.                 }
  473.         }
  474. #endif
  475.  
  476.         /* Iterative parsing loop, while there is more AML to process: */
  477.  
  478.         while ((parser_state->aml < parser_state->aml_end) || (op)) {
  479.                 aml_op_start = parser_state->aml;
  480.                 if (!op) {
  481.                         status =
  482.                             acpi_ps_create_op(walk_state, aml_op_start, &op);
  483.                         if (ACPI_FAILURE(status)) {
  484.                                 if (status == AE_CTRL_PARSE_CONTINUE) {
  485.                                         continue;
  486.                                 }
  487.  
  488.                                 if (status == AE_CTRL_PARSE_PENDING) {
  489.                                         status = AE_OK;
  490.                                 }
  491.  
  492.                                 if (status == AE_CTRL_TERMINATE) {
  493.                                         return_ACPI_STATUS(status);
  494.                                 }
  495.  
  496.                                 status =
  497.                                     acpi_ps_complete_op(walk_state, &op,
  498.                                                         status);
  499.                                 if (ACPI_FAILURE(status)) {
  500.                                         return_ACPI_STATUS(status);
  501.                                 }
  502.  
  503.                                 continue;
  504.                         }
  505.  
  506.                         acpi_ex_start_trace_opcode(op, walk_state);
  507.                 }
  508.  
  509.                 /*
  510.                  * Start arg_count at zero because we don't know if there are
  511.                  * any args yet
  512.                  */
  513.                 walk_state->arg_count = 0;
  514.  
  515.                 /* Are there any arguments that must be processed? */
  516.  
  517.                 if (walk_state->arg_types) {
  518.  
  519.                         /* Get arguments */
  520.  
  521.                         status =
  522.                             acpi_ps_get_arguments(walk_state, aml_op_start, op);
  523.                         if (ACPI_FAILURE(status)) {
  524.                                 status =
  525.                                     acpi_ps_complete_op(walk_state, &op,
  526.                                                         status);
  527.                                 if (ACPI_FAILURE(status)) {
  528.                                         return_ACPI_STATUS(status);
  529.                                 }
  530.  
  531.                                 continue;
  532.                         }
  533.                 }
  534.  
  535.                 /* Check for arguments that need to be processed */
  536.  
  537.                 if (walk_state->arg_count) {
  538.                         /*
  539.                          * There are arguments (complex ones), push Op and
  540.                          * prepare for argument
  541.                          */
  542.                         status = acpi_ps_push_scope(parser_state, op,
  543.                                                     walk_state->arg_types,
  544.                                                     walk_state->arg_count);
  545.                         if (ACPI_FAILURE(status)) {
  546.                                 status =
  547.                                     acpi_ps_complete_op(walk_state, &op,
  548.                                                         status);
  549.                                 if (ACPI_FAILURE(status)) {
  550.                                         return_ACPI_STATUS(status);
  551.                                 }
  552.  
  553.                                 continue;
  554.                         }
  555.  
  556.                         op = NULL;
  557.                         continue;
  558.                 }
  559.  
  560.                 /*
  561.                  * All arguments have been processed -- Op is complete,
  562.                  * prepare for next
  563.                  */
  564.                 walk_state->op_info =
  565.                     acpi_ps_get_opcode_info(op->common.aml_opcode);
  566.                 if (walk_state->op_info->flags & AML_NAMED) {
  567.                         if (op->common.aml_opcode == AML_REGION_OP ||
  568.                             op->common.aml_opcode == AML_DATA_REGION_OP) {
  569.                                 /*
  570.                                  * Skip parsing of control method or opregion body,
  571.                                  * because we don't have enough info in the first pass
  572.                                  * to parse them correctly.
  573.                                  *
  574.                                  * Completed parsing an op_region declaration, we now
  575.                                  * know the length.
  576.                                  */
  577.                                 op->named.length =
  578.                                     (u32) (parser_state->aml - op->named.data);
  579.                         }
  580.                 }
  581.  
  582.                 if (walk_state->op_info->flags & AML_CREATE) {
  583.                         /*
  584.                          * Backup to beginning of create_XXXfield declaration (1 for
  585.                          * Opcode)
  586.                          *
  587.                          * body_length is unknown until we parse the body
  588.                          */
  589.                         op->named.length =
  590.                             (u32) (parser_state->aml - op->named.data);
  591.                 }
  592.  
  593.                 if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
  594.                         /*
  595.                          * Backup to beginning of bank_field declaration
  596.                          *
  597.                          * body_length is unknown until we parse the body
  598.                          */
  599.                         op->named.length =
  600.                             (u32) (parser_state->aml - op->named.data);
  601.                 }
  602.  
  603.                 /* This op complete, notify the dispatcher */
  604.  
  605.                 if (walk_state->ascending_callback != NULL) {
  606.                         walk_state->op = op;
  607.                         walk_state->opcode = op->common.aml_opcode;
  608.  
  609.                         status = walk_state->ascending_callback(walk_state);
  610.                         status =
  611.                             acpi_ps_next_parse_state(walk_state, op, status);
  612.                         if (status == AE_CTRL_PENDING) {
  613.                                 status = AE_OK;
  614.                         }
  615.                 }
  616.  
  617.                 status = acpi_ps_complete_op(walk_state, &op, status);
  618.                 if (ACPI_FAILURE(status)) {
  619.                         return_ACPI_STATUS(status);
  620.                 }
  621.  
  622.         }                       /* while parser_state->Aml */
  623.  
  624.         status = acpi_ps_complete_final_op(walk_state, op, status);
  625.         return_ACPI_STATUS(status);
  626. }
  627.