root/drivers/acpi/acpica/psobject.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ps_build_named_op
  3. acpi_ps_create_op
  4. acpi_ps_complete_op
  5. acpi_ps_complete_final_op

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: psobject - Support for parse objects
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acparser.h"
  13 #include "amlcode.h"
  14 #include "acconvert.h"
  15 #include "acnamesp.h"
  16 
  17 #define _COMPONENT          ACPI_PARSER
  18 ACPI_MODULE_NAME("psobject")
  19 
  20 /* Local prototypes */
  21 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state);
  22 
  23 /*******************************************************************************
  24  *
  25  * FUNCTION:    acpi_ps_get_aml_opcode
  26  *
  27  * PARAMETERS:  walk_state          - Current state
  28  *
  29  * RETURN:      Status
  30  *
  31  * DESCRIPTION: Extract the next AML opcode from the input stream.
  32  *
  33  ******************************************************************************/
  34 
  35 static acpi_status acpi_ps_get_aml_opcode(struct acpi_walk_state *walk_state)
  36 {
  37         ACPI_ERROR_ONLY(u32 aml_offset);
  38 
  39         ACPI_FUNCTION_TRACE_PTR(ps_get_aml_opcode, walk_state);
  40 
  41         walk_state->aml = walk_state->parser_state.aml;
  42         walk_state->opcode = acpi_ps_peek_opcode(&(walk_state->parser_state));
  43 
  44         /*
  45          * First cut to determine what we have found:
  46          * 1) A valid AML opcode
  47          * 2) A name string
  48          * 3) An unknown/invalid opcode
  49          */
  50         walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
  51 
  52         switch (walk_state->op_info->class) {
  53         case AML_CLASS_ASCII:
  54         case AML_CLASS_PREFIX:
  55                 /*
  56                  * Starts with a valid prefix or ASCII char, this is a name
  57                  * string. Convert the bare name string to a namepath.
  58                  */
  59                 walk_state->opcode = AML_INT_NAMEPATH_OP;
  60                 walk_state->arg_types = ARGP_NAMESTRING;
  61                 break;
  62 
  63         case AML_CLASS_UNKNOWN:
  64 
  65                 /* The opcode is unrecognized. Complain and skip unknown opcodes */
  66 
  67                 if (walk_state->pass_number == 2) {
  68                         ACPI_ERROR_ONLY(aml_offset =
  69                                         (u32)ACPI_PTR_DIFF(walk_state->aml,
  70                                                            walk_state->
  71                                                            parser_state.
  72                                                            aml_start));
  73 
  74                         ACPI_ERROR((AE_INFO,
  75                                     "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
  76                                     walk_state->opcode,
  77                                     (u32)(aml_offset +
  78                                           sizeof(struct acpi_table_header))));
  79 
  80                         ACPI_DUMP_BUFFER((walk_state->parser_state.aml - 16),
  81                                          48);
  82 
  83 #ifdef ACPI_ASL_COMPILER
  84                         /*
  85                          * This is executed for the disassembler only. Output goes
  86                          * to the disassembled ASL output file.
  87                          */
  88                         acpi_os_printf
  89                             ("/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
  90                              walk_state->opcode,
  91                              (u32)(aml_offset +
  92                                    sizeof(struct acpi_table_header)));
  93 
  94                         ACPI_ERROR((AE_INFO,
  95                                     "Aborting disassembly, AML byte code is corrupt"));
  96 
  97                         /* Dump the context surrounding the invalid opcode */
  98 
  99                         acpi_ut_dump_buffer(((u8 *)walk_state->parser_state.
 100                                              aml - 16), 48, DB_BYTE_DISPLAY,
 101                                             (aml_offset +
 102                                              sizeof(struct acpi_table_header) -
 103                                              16));
 104                         acpi_os_printf(" */\n");
 105 
 106                         /*
 107                          * Just abort the disassembly, cannot continue because the
 108                          * parser is essentially lost. The disassembler can then
 109                          * randomly fail because an ill-constructed parse tree
 110                          * can result.
 111                          */
 112                         return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 113 #endif
 114                 }
 115 
 116                 /* Increment past one-byte or two-byte opcode */
 117 
 118                 walk_state->parser_state.aml++;
 119                 if (walk_state->opcode > 0xFF) {        /* Can only happen if first byte is 0x5B */
 120                         walk_state->parser_state.aml++;
 121                 }
 122 
 123                 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 124 
 125         default:
 126 
 127                 /* Found opcode info, this is a normal opcode */
 128 
 129                 walk_state->parser_state.aml +=
 130                     acpi_ps_get_opcode_size(walk_state->opcode);
 131                 walk_state->arg_types = walk_state->op_info->parse_args;
 132                 break;
 133         }
 134 
 135         return_ACPI_STATUS(AE_OK);
 136 }
 137 
 138 /*******************************************************************************
 139  *
 140  * FUNCTION:    acpi_ps_build_named_op
 141  *
 142  * PARAMETERS:  walk_state          - Current state
 143  *              aml_op_start        - Begin of named Op in AML
 144  *              unnamed_op          - Early Op (not a named Op)
 145  *              op                  - Returned Op
 146  *
 147  * RETURN:      Status
 148  *
 149  * DESCRIPTION: Parse a named Op
 150  *
 151  ******************************************************************************/
 152 
 153 acpi_status
 154 acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
 155                        u8 *aml_op_start,
 156                        union acpi_parse_object *unnamed_op,
 157                        union acpi_parse_object **op)
 158 {
 159         acpi_status status = AE_OK;
 160         union acpi_parse_object *arg = NULL;
 161 
 162         ACPI_FUNCTION_TRACE_PTR(ps_build_named_op, walk_state);
 163 
 164         unnamed_op->common.value.arg = NULL;
 165         unnamed_op->common.arg_list_length = 0;
 166         unnamed_op->common.aml_opcode = walk_state->opcode;
 167 
 168         /*
 169          * Get and append arguments until we find the node that contains
 170          * the name (the type ARGP_NAME).
 171          */
 172         while (GET_CURRENT_ARG_TYPE(walk_state->arg_types) &&
 173                (GET_CURRENT_ARG_TYPE(walk_state->arg_types) != ARGP_NAME)) {
 174                 ASL_CV_CAPTURE_COMMENTS(walk_state);
 175                 status =
 176                     acpi_ps_get_next_arg(walk_state,
 177                                          &(walk_state->parser_state),
 178                                          GET_CURRENT_ARG_TYPE(walk_state->
 179                                                               arg_types), &arg);
 180                 if (ACPI_FAILURE(status)) {
 181                         return_ACPI_STATUS(status);
 182                 }
 183 
 184                 acpi_ps_append_arg(unnamed_op, arg);
 185                 INCREMENT_ARG_LIST(walk_state->arg_types);
 186         }
 187 
 188         /* are there any inline comments associated with the name_seg?? If so, save this. */
 189 
 190         ASL_CV_CAPTURE_COMMENTS(walk_state);
 191 
 192 #ifdef ACPI_ASL_COMPILER
 193         if (acpi_gbl_current_inline_comment != NULL) {
 194                 unnamed_op->common.name_comment =
 195                     acpi_gbl_current_inline_comment;
 196                 acpi_gbl_current_inline_comment = NULL;
 197         }
 198 #endif
 199 
 200         /*
 201          * Make sure that we found a NAME and didn't run out of arguments
 202          */
 203         if (!GET_CURRENT_ARG_TYPE(walk_state->arg_types)) {
 204                 return_ACPI_STATUS(AE_AML_NO_OPERAND);
 205         }
 206 
 207         /* We know that this arg is a name, move to next arg */
 208 
 209         INCREMENT_ARG_LIST(walk_state->arg_types);
 210 
 211         /*
 212          * Find the object. This will either insert the object into
 213          * the namespace or simply look it up
 214          */
 215         walk_state->op = NULL;
 216 
 217         status = walk_state->descending_callback(walk_state, op);
 218         if (ACPI_FAILURE(status)) {
 219                 if (status != AE_CTRL_TERMINATE) {
 220                         ACPI_EXCEPTION((AE_INFO, status,
 221                                         "During name lookup/catalog"));
 222                 }
 223                 return_ACPI_STATUS(status);
 224         }
 225 
 226         if (!*op) {
 227                 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 228         }
 229 
 230         status = acpi_ps_next_parse_state(walk_state, *op, status);
 231         if (ACPI_FAILURE(status)) {
 232                 if (status == AE_CTRL_PENDING) {
 233                         status = AE_CTRL_PARSE_PENDING;
 234                 }
 235                 return_ACPI_STATUS(status);
 236         }
 237 
 238         acpi_ps_append_arg(*op, unnamed_op->common.value.arg);
 239 
 240 #ifdef ACPI_ASL_COMPILER
 241 
 242         /* save any comments that might be associated with unnamed_op. */
 243 
 244         (*op)->common.inline_comment = unnamed_op->common.inline_comment;
 245         (*op)->common.end_node_comment = unnamed_op->common.end_node_comment;
 246         (*op)->common.close_brace_comment =
 247             unnamed_op->common.close_brace_comment;
 248         (*op)->common.name_comment = unnamed_op->common.name_comment;
 249         (*op)->common.comment_list = unnamed_op->common.comment_list;
 250         (*op)->common.end_blk_comment = unnamed_op->common.end_blk_comment;
 251         (*op)->common.cv_filename = unnamed_op->common.cv_filename;
 252         (*op)->common.cv_parent_filename =
 253             unnamed_op->common.cv_parent_filename;
 254         (*op)->named.aml = unnamed_op->common.aml;
 255 
 256         unnamed_op->common.inline_comment = NULL;
 257         unnamed_op->common.end_node_comment = NULL;
 258         unnamed_op->common.close_brace_comment = NULL;
 259         unnamed_op->common.name_comment = NULL;
 260         unnamed_op->common.comment_list = NULL;
 261         unnamed_op->common.end_blk_comment = NULL;
 262 #endif
 263 
 264         if ((*op)->common.aml_opcode == AML_REGION_OP ||
 265             (*op)->common.aml_opcode == AML_DATA_REGION_OP) {
 266                 /*
 267                  * Defer final parsing of an operation_region body, because we don't
 268                  * have enough info in the first pass to parse it correctly (i.e.,
 269                  * there may be method calls within the term_arg elements of the body.)
 270                  *
 271                  * However, we must continue parsing because the opregion is not a
 272                  * standalone package -- we don't know where the end is at this point.
 273                  *
 274                  * (Length is unknown until parse of the body complete)
 275                  */
 276                 (*op)->named.data = aml_op_start;
 277                 (*op)->named.length = 0;
 278         }
 279 
 280         return_ACPI_STATUS(AE_OK);
 281 }
 282 
 283 /*******************************************************************************
 284  *
 285  * FUNCTION:    acpi_ps_create_op
 286  *
 287  * PARAMETERS:  walk_state          - Current state
 288  *              aml_op_start        - Op start in AML
 289  *              new_op              - Returned Op
 290  *
 291  * RETURN:      Status
 292  *
 293  * DESCRIPTION: Get Op from AML
 294  *
 295  ******************************************************************************/
 296 
 297 acpi_status
 298 acpi_ps_create_op(struct acpi_walk_state *walk_state,
 299                   u8 *aml_op_start, union acpi_parse_object **new_op)
 300 {
 301         acpi_status status = AE_OK;
 302         union acpi_parse_object *op;
 303         union acpi_parse_object *named_op = NULL;
 304         union acpi_parse_object *parent_scope;
 305         u8 argument_count;
 306         const struct acpi_opcode_info *op_info;
 307 
 308         ACPI_FUNCTION_TRACE_PTR(ps_create_op, walk_state);
 309 
 310         status = acpi_ps_get_aml_opcode(walk_state);
 311         if (status == AE_CTRL_PARSE_CONTINUE) {
 312                 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 313         }
 314         if (ACPI_FAILURE(status)) {
 315                 return_ACPI_STATUS(status);
 316         }
 317 
 318         /* Create Op structure and append to parent's argument list */
 319 
 320         walk_state->op_info = acpi_ps_get_opcode_info(walk_state->opcode);
 321         op = acpi_ps_alloc_op(walk_state->opcode, aml_op_start);
 322         if (!op) {
 323                 return_ACPI_STATUS(AE_NO_MEMORY);
 324         }
 325 
 326         if (walk_state->op_info->flags & AML_NAMED) {
 327                 status =
 328                     acpi_ps_build_named_op(walk_state, aml_op_start, op,
 329                                            &named_op);
 330                 acpi_ps_free_op(op);
 331 
 332 #ifdef ACPI_ASL_COMPILER
 333                 if (acpi_gbl_disasm_flag
 334                     && walk_state->opcode == AML_EXTERNAL_OP
 335                     && status == AE_NOT_FOUND) {
 336                         /*
 337                          * If parsing of AML_EXTERNAL_OP's name path fails, then skip
 338                          * past this opcode and keep parsing. This is a much better
 339                          * alternative than to abort the entire disassembler. At this
 340                          * point, the parser_state is at the end of the namepath of the
 341                          * external declaration opcode. Setting walk_state->Aml to
 342                          * walk_state->parser_state.Aml + 2 moves increments the
 343                          * walk_state->Aml past the object type and the paramcount of the
 344                          * external opcode.
 345                          */
 346                         walk_state->aml = walk_state->parser_state.aml + 2;
 347                         walk_state->parser_state.aml = walk_state->aml;
 348                         return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
 349                 }
 350 #endif
 351                 if (ACPI_FAILURE(status)) {
 352                         return_ACPI_STATUS(status);
 353                 }
 354 
 355                 *new_op = named_op;
 356                 return_ACPI_STATUS(AE_OK);
 357         }
 358 
 359         /* Not a named opcode, just allocate Op and append to parent */
 360 
 361         if (walk_state->op_info->flags & AML_CREATE) {
 362                 /*
 363                  * Backup to beginning of create_XXXfield declaration
 364                  * body_length is unknown until we parse the body
 365                  */
 366                 op->named.data = aml_op_start;
 367                 op->named.length = 0;
 368         }
 369 
 370         if (walk_state->opcode == AML_BANK_FIELD_OP) {
 371                 /*
 372                  * Backup to beginning of bank_field declaration
 373                  * body_length is unknown until we parse the body
 374                  */
 375                 op->named.data = aml_op_start;
 376                 op->named.length = 0;
 377         }
 378 
 379         parent_scope = acpi_ps_get_parent_scope(&(walk_state->parser_state));
 380         acpi_ps_append_arg(parent_scope, op);
 381 
 382         if (parent_scope) {
 383                 op_info =
 384                     acpi_ps_get_opcode_info(parent_scope->common.aml_opcode);
 385                 if (op_info->flags & AML_HAS_TARGET) {
 386                         argument_count =
 387                             acpi_ps_get_argument_count(op_info->type);
 388                         if (parent_scope->common.arg_list_length >
 389                             argument_count) {
 390                                 op->common.flags |= ACPI_PARSEOP_TARGET;
 391                         }
 392                 }
 393 
 394                 /*
 395                  * Special case for both Increment() and Decrement(), where
 396                  * the lone argument is both a source and a target.
 397                  */
 398                 else if ((parent_scope->common.aml_opcode == AML_INCREMENT_OP)
 399                          || (parent_scope->common.aml_opcode ==
 400                              AML_DECREMENT_OP)) {
 401                         op->common.flags |= ACPI_PARSEOP_TARGET;
 402                 }
 403         }
 404 
 405         if (walk_state->descending_callback != NULL) {
 406                 /*
 407                  * Find the object. This will either insert the object into
 408                  * the namespace or simply look it up
 409                  */
 410                 walk_state->op = *new_op = op;
 411 
 412                 status = walk_state->descending_callback(walk_state, &op);
 413                 status = acpi_ps_next_parse_state(walk_state, op, status);
 414                 if (status == AE_CTRL_PENDING) {
 415                         status = AE_CTRL_PARSE_PENDING;
 416                 }
 417         }
 418 
 419         return_ACPI_STATUS(status);
 420 }
 421 
 422 /*******************************************************************************
 423  *
 424  * FUNCTION:    acpi_ps_complete_op
 425  *
 426  * PARAMETERS:  walk_state          - Current state
 427  *              op                  - Returned Op
 428  *              status              - Parse status before complete Op
 429  *
 430  * RETURN:      Status
 431  *
 432  * DESCRIPTION: Complete Op
 433  *
 434  ******************************************************************************/
 435 
 436 acpi_status
 437 acpi_ps_complete_op(struct acpi_walk_state *walk_state,
 438                     union acpi_parse_object **op, acpi_status status)
 439 {
 440         acpi_status status2;
 441 
 442         ACPI_FUNCTION_TRACE_PTR(ps_complete_op, walk_state);
 443 
 444         /*
 445          * Finished one argument of the containing scope
 446          */
 447         walk_state->parser_state.scope->parse_scope.arg_count--;
 448 
 449         /* Close this Op (will result in parse subtree deletion) */
 450 
 451         status2 = acpi_ps_complete_this_op(walk_state, *op);
 452         if (ACPI_FAILURE(status2)) {
 453                 return_ACPI_STATUS(status2);
 454         }
 455 
 456         *op = NULL;
 457 
 458         switch (status) {
 459         case AE_OK:
 460 
 461                 break;
 462 
 463         case AE_CTRL_TRANSFER:
 464 
 465                 /* We are about to transfer to a called method */
 466 
 467                 walk_state->prev_op = NULL;
 468                 walk_state->prev_arg_types = walk_state->arg_types;
 469                 return_ACPI_STATUS(status);
 470 
 471         case AE_CTRL_END:
 472 
 473                 acpi_ps_pop_scope(&(walk_state->parser_state), op,
 474                                   &walk_state->arg_types,
 475                                   &walk_state->arg_count);
 476 
 477                 if (*op) {
 478                         walk_state->op = *op;
 479                         walk_state->op_info =
 480                             acpi_ps_get_opcode_info((*op)->common.aml_opcode);
 481                         walk_state->opcode = (*op)->common.aml_opcode;
 482 
 483                         status = walk_state->ascending_callback(walk_state);
 484                         status =
 485                             acpi_ps_next_parse_state(walk_state, *op, status);
 486 
 487                         status2 = acpi_ps_complete_this_op(walk_state, *op);
 488                         if (ACPI_FAILURE(status2)) {
 489                                 return_ACPI_STATUS(status2);
 490                         }
 491                 }
 492 
 493                 status = AE_OK;
 494                 break;
 495 
 496         case AE_CTRL_BREAK:
 497         case AE_CTRL_CONTINUE:
 498 
 499                 /* Pop off scopes until we find the While */
 500 
 501                 while (!(*op) || ((*op)->common.aml_opcode != AML_WHILE_OP)) {
 502                         acpi_ps_pop_scope(&(walk_state->parser_state), op,
 503                                           &walk_state->arg_types,
 504                                           &walk_state->arg_count);
 505                 }
 506 
 507                 /* Close this iteration of the While loop */
 508 
 509                 walk_state->op = *op;
 510                 walk_state->op_info =
 511                     acpi_ps_get_opcode_info((*op)->common.aml_opcode);
 512                 walk_state->opcode = (*op)->common.aml_opcode;
 513 
 514                 status = walk_state->ascending_callback(walk_state);
 515                 status = acpi_ps_next_parse_state(walk_state, *op, status);
 516 
 517                 status2 = acpi_ps_complete_this_op(walk_state, *op);
 518                 if (ACPI_FAILURE(status2)) {
 519                         return_ACPI_STATUS(status2);
 520                 }
 521 
 522                 status = AE_OK;
 523                 break;
 524 
 525         case AE_CTRL_TERMINATE:
 526 
 527                 /* Clean up */
 528                 do {
 529                         if (*op) {
 530                                 status2 =
 531                                     acpi_ps_complete_this_op(walk_state, *op);
 532                                 if (ACPI_FAILURE(status2)) {
 533                                         return_ACPI_STATUS(status2);
 534                                 }
 535 
 536                                 acpi_ut_delete_generic_state
 537                                     (acpi_ut_pop_generic_state
 538                                      (&walk_state->control_state));
 539                         }
 540 
 541                         acpi_ps_pop_scope(&(walk_state->parser_state), op,
 542                                           &walk_state->arg_types,
 543                                           &walk_state->arg_count);
 544 
 545                 } while (*op);
 546 
 547                 return_ACPI_STATUS(AE_OK);
 548 
 549         default:                /* All other non-AE_OK status */
 550 
 551                 do {
 552                         if (*op) {
 553                                 /*
 554                                  * These Opcodes need to be removed from the namespace because they
 555                                  * get created even if these opcodes cannot be created due to
 556                                  * errors.
 557                                  */
 558                                 if (((*op)->common.aml_opcode == AML_REGION_OP)
 559                                     || ((*op)->common.aml_opcode ==
 560                                         AML_DATA_REGION_OP)) {
 561                                         acpi_ns_delete_children((*op)->common.
 562                                                                 node);
 563                                         acpi_ns_remove_node((*op)->common.node);
 564                                         (*op)->common.node = NULL;
 565                                         acpi_ps_delete_parse_tree(*op);
 566                                 }
 567 
 568                                 status2 =
 569                                     acpi_ps_complete_this_op(walk_state, *op);
 570                                 if (ACPI_FAILURE(status2)) {
 571                                         return_ACPI_STATUS(status2);
 572                                 }
 573                         }
 574 
 575                         acpi_ps_pop_scope(&(walk_state->parser_state), op,
 576                                           &walk_state->arg_types,
 577                                           &walk_state->arg_count);
 578 
 579                 } while (*op);
 580 
 581 #if 0
 582                 /*
 583                  * TBD: Cleanup parse ops on error
 584                  */
 585                 if (*op == NULL) {
 586                         acpi_ps_pop_scope(parser_state, op,
 587                                           &walk_state->arg_types,
 588                                           &walk_state->arg_count);
 589                 }
 590 #endif
 591                 walk_state->prev_op = NULL;
 592                 walk_state->prev_arg_types = walk_state->arg_types;
 593 
 594                 if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
 595                         /*
 596                          * There was something that went wrong while executing code at the
 597                          * module-level. We need to skip parsing whatever caused the
 598                          * error and keep going. One runtime error during the table load
 599                          * should not cause the entire table to not be loaded. This is
 600                          * because there could be correct AML beyond the parts that caused
 601                          * the runtime error.
 602                          */
 603                         ACPI_INFO(("Ignoring error and continuing table load"));
 604                         return_ACPI_STATUS(AE_OK);
 605                 }
 606                 return_ACPI_STATUS(status);
 607         }
 608 
 609         /* This scope complete? */
 610 
 611         if (acpi_ps_has_completed_scope(&(walk_state->parser_state))) {
 612                 acpi_ps_pop_scope(&(walk_state->parser_state), op,
 613                                   &walk_state->arg_types,
 614                                   &walk_state->arg_count);
 615                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *op));
 616         } else {
 617                 *op = NULL;
 618         }
 619 
 620         return_ACPI_STATUS(AE_OK);
 621 }
 622 
 623 /*******************************************************************************
 624  *
 625  * FUNCTION:    acpi_ps_complete_final_op
 626  *
 627  * PARAMETERS:  walk_state          - Current state
 628  *              op                  - Current Op
 629  *              status              - Current parse status before complete last
 630  *                                    Op
 631  *
 632  * RETURN:      Status
 633  *
 634  * DESCRIPTION: Complete last Op.
 635  *
 636  ******************************************************************************/
 637 
 638 acpi_status
 639 acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
 640                           union acpi_parse_object *op, acpi_status status)
 641 {
 642         acpi_status status2;
 643 
 644         ACPI_FUNCTION_TRACE_PTR(ps_complete_final_op, walk_state);
 645 
 646         /*
 647          * Complete the last Op (if not completed), and clear the scope stack.
 648          * It is easily possible to end an AML "package" with an unbounded number
 649          * of open scopes (such as when several ASL blocks are closed with
 650          * sequential closing braces). We want to terminate each one cleanly.
 651          */
 652         ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "AML package complete at Op %p\n",
 653                           op));
 654         do {
 655                 if (op) {
 656                         if (walk_state->ascending_callback != NULL) {
 657                                 walk_state->op = op;
 658                                 walk_state->op_info =
 659                                     acpi_ps_get_opcode_info(op->common.
 660                                                             aml_opcode);
 661                                 walk_state->opcode = op->common.aml_opcode;
 662 
 663                                 status =
 664                                     walk_state->ascending_callback(walk_state);
 665                                 status =
 666                                     acpi_ps_next_parse_state(walk_state, op,
 667                                                              status);
 668                                 if (status == AE_CTRL_PENDING) {
 669                                         status =
 670                                             acpi_ps_complete_op(walk_state, &op,
 671                                                                 AE_OK);
 672                                         if (ACPI_FAILURE(status)) {
 673                                                 return_ACPI_STATUS(status);
 674                                         }
 675                                 }
 676 
 677                                 if (status == AE_CTRL_TERMINATE) {
 678                                         status = AE_OK;
 679 
 680                                         /* Clean up */
 681                                         do {
 682                                                 if (op) {
 683                                                         status2 =
 684                                                             acpi_ps_complete_this_op
 685                                                             (walk_state, op);
 686                                                         if (ACPI_FAILURE
 687                                                             (status2)) {
 688                                                                 return_ACPI_STATUS
 689                                                                     (status2);
 690                                                         }
 691                                                 }
 692 
 693                                                 acpi_ps_pop_scope(&
 694                                                                   (walk_state->
 695                                                                    parser_state),
 696                                                                   &op,
 697                                                                   &walk_state->
 698                                                                   arg_types,
 699                                                                   &walk_state->
 700                                                                   arg_count);
 701 
 702                                         } while (op);
 703 
 704                                         return_ACPI_STATUS(status);
 705                                 }
 706 
 707                                 else if (ACPI_FAILURE(status)) {
 708 
 709                                         /* First error is most important */
 710 
 711                                         (void)
 712                                             acpi_ps_complete_this_op(walk_state,
 713                                                                      op);
 714                                         return_ACPI_STATUS(status);
 715                                 }
 716                         }
 717 
 718                         status2 = acpi_ps_complete_this_op(walk_state, op);
 719                         if (ACPI_FAILURE(status2)) {
 720                                 return_ACPI_STATUS(status2);
 721                         }
 722                 }
 723 
 724                 acpi_ps_pop_scope(&(walk_state->parser_state), &op,
 725                                   &walk_state->arg_types,
 726                                   &walk_state->arg_count);
 727 
 728         } while (op);
 729 
 730         return_ACPI_STATUS(status);
 731 }

/* [<][>][^][v][top][bottom][index][help] */