1 /******************************************************************************
   2  *
   3  * Module Name: psobject - Support for parse objects
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2013, 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 #include "acpi.h"
  46 #include "accommon.h"
  47 #include "acparser.h"
  48 #include "amlcode.h"
  49 
  50 #define _COMPONENT          ACPI_PARSER
  51         ACPI_MODULE_NAME    ("psobject")
  52 
  53 
  54 /* Local prototypes */
  55 
  56 static ACPI_STATUS
  57 AcpiPsGetAmlOpcode (
  58     ACPI_WALK_STATE         *WalkState);
  59 
  60 
  61 /*******************************************************************************
  62  *
  63  * FUNCTION:    AcpiPsGetAmlOpcode
  64  *
  65  * PARAMETERS:  WalkState           - Current state
  66  *
  67  * RETURN:      Status
  68  *
  69  * DESCRIPTION: Extract the next AML opcode from the input stream.
  70  *
  71  ******************************************************************************/
  72 
  73 static ACPI_STATUS
  74 AcpiPsGetAmlOpcode (
  75     ACPI_WALK_STATE         *WalkState)
  76 {
  77 
  78     ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
  79 
  80 
  81     WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
  82                                 WalkState->ParserState.AmlStart);
  83     WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
  84 
  85     /*
  86      * First cut to determine what we have found:
  87      * 1) A valid AML opcode
  88      * 2) A name string
  89      * 3) An unknown/invalid opcode
  90      */
  91     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
  92 
  93     switch (WalkState->OpInfo->Class)
  94     {
  95     case AML_CLASS_ASCII:
  96     case AML_CLASS_PREFIX:
  97         /*
  98          * Starts with a valid prefix or ASCII char, this is a name
  99          * string. Convert the bare name string to a namepath.
 100          */
 101         WalkState->Opcode = AML_INT_NAMEPATH_OP;
 102         WalkState->ArgTypes = ARGP_NAMESTRING;
 103         break;
 104 
 105     case AML_CLASS_UNKNOWN:
 106 
 107         /* The opcode is unrecognized. Complain and skip unknown opcodes */
 108 
 109         if (WalkState->PassNumber == 2)
 110         {
 111             ACPI_ERROR ((AE_INFO,
 112                 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
 113                 WalkState->Opcode,
 114                 (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER))));
 115 
 116             ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48);
 117 
 118 #ifdef ACPI_ASL_COMPILER
 119             /*
 120              * This is executed for the disassembler only. Output goes
 121              * to the disassembled ASL output file.
 122              */
 123             AcpiOsPrintf (
 124                 "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
 125                 WalkState->Opcode,
 126                 (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER)));
 127 
 128             /* Dump the context surrounding the invalid opcode */
 129 
 130             AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
 131                 48, DB_BYTE_DISPLAY,
 132                 (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16));
 133             AcpiOsPrintf (" */\n");
 134 #endif
 135         }
 136 
 137         /* Increment past one-byte or two-byte opcode */
 138 
 139         WalkState->ParserState.Aml++;
 140         if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
 141         {
 142             WalkState->ParserState.Aml++;
 143         }
 144 
 145         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
 146 
 147     default:
 148 
 149         /* Found opcode info, this is a normal opcode */
 150 
 151         WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
 152         WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
 153         break;
 154     }
 155 
 156     return_ACPI_STATUS (AE_OK);
 157 }
 158 
 159 
 160 /*******************************************************************************
 161  *
 162  * FUNCTION:    AcpiPsBuildNamedOp
 163  *
 164  * PARAMETERS:  WalkState           - Current state
 165  *              AmlOpStart          - Begin of named Op in AML
 166  *              UnnamedOp           - Early Op (not a named Op)
 167  *              Op                  - Returned Op
 168  *
 169  * RETURN:      Status
 170  *
 171  * DESCRIPTION: Parse a named Op
 172  *
 173  ******************************************************************************/
 174 
 175 ACPI_STATUS
 176 AcpiPsBuildNamedOp (
 177     ACPI_WALK_STATE         *WalkState,
 178     UINT8                   *AmlOpStart,
 179     ACPI_PARSE_OBJECT       *UnnamedOp,
 180     ACPI_PARSE_OBJECT       **Op)
 181 {
 182     ACPI_STATUS             Status = AE_OK;
 183     ACPI_PARSE_OBJECT       *Arg = NULL;
 184 
 185 
 186     ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
 187 
 188 
 189     UnnamedOp->Common.Value.Arg = NULL;
 190     UnnamedOp->Common.ArgListLength = 0;
 191     UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
 192 
 193     /*
 194      * Get and append arguments until we find the node that contains
 195      * the name (the type ARGP_NAME).
 196      */
 197     while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
 198           (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
 199     {
 200         Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
 201                     GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
 202         if (ACPI_FAILURE (Status))
 203         {
 204             return_ACPI_STATUS (Status);
 205         }
 206 
 207         AcpiPsAppendArg (UnnamedOp, Arg);
 208         INCREMENT_ARG_LIST (WalkState->ArgTypes);
 209     }
 210 
 211     /*
 212      * Make sure that we found a NAME and didn't run out of arguments
 213      */
 214     if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
 215     {
 216         return_ACPI_STATUS (AE_AML_NO_OPERAND);
 217     }
 218 
 219     /* We know that this arg is a name, move to next arg */
 220 
 221     INCREMENT_ARG_LIST (WalkState->ArgTypes);
 222 
 223     /*
 224      * Find the object. This will either insert the object into
 225      * the namespace or simply look it up
 226      */
 227     WalkState->Op = NULL;
 228 
 229     Status = WalkState->DescendingCallback (WalkState, Op);
 230     if (ACPI_FAILURE (Status))
 231     {
 232         ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
 233         return_ACPI_STATUS (Status);
 234     }
 235 
 236     if (!*Op)
 237     {
 238         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
 239     }
 240 
 241     Status = AcpiPsNextParseState (WalkState, *Op, Status);
 242     if (ACPI_FAILURE (Status))
 243     {
 244         if (Status == AE_CTRL_PENDING)
 245         {
 246             return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
 247         }
 248         return_ACPI_STATUS (Status);
 249     }
 250 
 251     AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
 252 
 253     if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
 254         (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
 255     {
 256         /*
 257          * Defer final parsing of an OperationRegion body, because we don't
 258          * have enough info in the first pass to parse it correctly (i.e.,
 259          * there may be method calls within the TermArg elements of the body.)
 260          *
 261          * However, we must continue parsing because the opregion is not a
 262          * standalone package -- we don't know where the end is at this point.
 263          *
 264          * (Length is unknown until parse of the body complete)
 265          */
 266         (*Op)->Named.Data = AmlOpStart;
 267         (*Op)->Named.Length = 0;
 268     }
 269 
 270     return_ACPI_STATUS (AE_OK);
 271 }
 272 
 273 
 274 /*******************************************************************************
 275  *
 276  * FUNCTION:    AcpiPsCreateOp
 277  *
 278  * PARAMETERS:  WalkState           - Current state
 279  *              AmlOpStart          - Op start in AML
 280  *              NewOp               - Returned Op
 281  *
 282  * RETURN:      Status
 283  *
 284  * DESCRIPTION: Get Op from AML
 285  *
 286  ******************************************************************************/
 287 
 288 ACPI_STATUS
 289 AcpiPsCreateOp (
 290     ACPI_WALK_STATE         *WalkState,
 291     UINT8                   *AmlOpStart,
 292     ACPI_PARSE_OBJECT       **NewOp)
 293 {
 294     ACPI_STATUS             Status = AE_OK;
 295     ACPI_PARSE_OBJECT       *Op;
 296     ACPI_PARSE_OBJECT       *NamedOp = NULL;
 297     ACPI_PARSE_OBJECT       *ParentScope;
 298     UINT8                   ArgumentCount;
 299     const ACPI_OPCODE_INFO  *OpInfo;
 300 
 301 
 302     ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
 303 
 304 
 305     Status = AcpiPsGetAmlOpcode (WalkState);
 306     if (Status == AE_CTRL_PARSE_CONTINUE)
 307     {
 308         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
 309     }
 310 
 311     /* Create Op structure and append to parent's argument list */
 312 
 313     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
 314     Op = AcpiPsAllocOp (WalkState->Opcode);
 315     if (!Op)
 316     {
 317         return_ACPI_STATUS (AE_NO_MEMORY);
 318     }
 319 
 320     if (WalkState->OpInfo->Flags & AML_NAMED)
 321     {
 322         Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
 323         AcpiPsFreeOp (Op);
 324         if (ACPI_FAILURE (Status))
 325         {
 326             return_ACPI_STATUS (Status);
 327         }
 328 
 329         *NewOp = NamedOp;
 330         return_ACPI_STATUS (AE_OK);
 331     }
 332 
 333     /* Not a named opcode, just allocate Op and append to parent */
 334 
 335     if (WalkState->OpInfo->Flags & AML_CREATE)
 336     {
 337         /*
 338          * Backup to beginning of CreateXXXfield declaration
 339          * BodyLength is unknown until we parse the body
 340          */
 341         Op->Named.Data = AmlOpStart;
 342         Op->Named.Length = 0;
 343     }
 344 
 345     if (WalkState->Opcode == AML_BANK_FIELD_OP)
 346     {
 347         /*
 348          * Backup to beginning of BankField declaration
 349          * BodyLength is unknown until we parse the body
 350          */
 351         Op->Named.Data = AmlOpStart;
 352         Op->Named.Length = 0;
 353     }
 354 
 355     ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
 356     AcpiPsAppendArg (ParentScope, Op);
 357 
 358     if (ParentScope)
 359     {
 360         OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
 361         if (OpInfo->Flags & AML_HAS_TARGET)
 362         {
 363             ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
 364             if (ParentScope->Common.ArgListLength > ArgumentCount)
 365             {
 366                 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
 367             }
 368         }
 369         else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
 370         {
 371             Op->Common.Flags |= ACPI_PARSEOP_TARGET;
 372         }
 373     }
 374 
 375     if (WalkState->DescendingCallback != NULL)
 376     {
 377         /*
 378          * Find the object. This will either insert the object into
 379          * the namespace or simply look it up
 380          */
 381         WalkState->Op = *NewOp = Op;
 382 
 383         Status = WalkState->DescendingCallback (WalkState, &Op);
 384         Status = AcpiPsNextParseState (WalkState, Op, Status);
 385         if (Status == AE_CTRL_PENDING)
 386         {
 387             Status = AE_CTRL_PARSE_PENDING;
 388         }
 389     }
 390 
 391     return_ACPI_STATUS (Status);
 392 }
 393 
 394 
 395 /*******************************************************************************
 396  *
 397  * FUNCTION:    AcpiPsCompleteOp
 398  *
 399  * PARAMETERS:  WalkState           - Current state
 400  *              Op                  - Returned Op
 401  *              Status              - Parse status before complete Op
 402  *
 403  * RETURN:      Status
 404  *
 405  * DESCRIPTION: Complete Op
 406  *
 407  ******************************************************************************/
 408 
 409 ACPI_STATUS
 410 AcpiPsCompleteOp (
 411     ACPI_WALK_STATE         *WalkState,
 412     ACPI_PARSE_OBJECT       **Op,
 413     ACPI_STATUS             Status)
 414 {
 415     ACPI_STATUS             Status2;
 416 
 417 
 418     ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
 419 
 420 
 421     /*
 422      * Finished one argument of the containing scope
 423      */
 424     WalkState->ParserState.Scope->ParseScope.ArgCount--;
 425 
 426     /* Close this Op (will result in parse subtree deletion) */
 427 
 428     Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
 429     if (ACPI_FAILURE (Status2))
 430     {
 431         return_ACPI_STATUS (Status2);
 432     }
 433 
 434     *Op = NULL;
 435 
 436     switch (Status)
 437     {
 438     case AE_OK:
 439 
 440         break;
 441 
 442     case AE_CTRL_TRANSFER:
 443 
 444         /* We are about to transfer to a called method */
 445 
 446         WalkState->PrevOp = NULL;
 447         WalkState->PrevArgTypes = WalkState->ArgTypes;
 448         return_ACPI_STATUS (Status);
 449 
 450     case AE_CTRL_END:
 451 
 452         AcpiPsPopScope (&(WalkState->ParserState), Op,
 453             &WalkState->ArgTypes, &WalkState->ArgCount);
 454 
 455         if (*Op)
 456         {
 457             WalkState->Op = *Op;
 458             WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
 459             WalkState->Opcode = (*Op)->Common.AmlOpcode;
 460 
 461             Status = WalkState->AscendingCallback (WalkState);
 462             Status = AcpiPsNextParseState (WalkState, *Op, Status);
 463 
 464             Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
 465             if (ACPI_FAILURE (Status2))
 466             {
 467                 return_ACPI_STATUS (Status2);
 468             }
 469         }
 470 
 471         Status = AE_OK;
 472         break;
 473 
 474     case AE_CTRL_BREAK:
 475     case AE_CTRL_CONTINUE:
 476 
 477         /* Pop off scopes until we find the While */
 478 
 479         while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
 480         {
 481             AcpiPsPopScope (&(WalkState->ParserState), Op,
 482                 &WalkState->ArgTypes, &WalkState->ArgCount);
 483         }
 484 
 485         /* Close this iteration of the While loop */
 486 
 487         WalkState->Op = *Op;
 488         WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
 489         WalkState->Opcode = (*Op)->Common.AmlOpcode;
 490 
 491         Status = WalkState->AscendingCallback (WalkState);
 492         Status = AcpiPsNextParseState (WalkState, *Op, Status);
 493 
 494         Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
 495         if (ACPI_FAILURE (Status2))
 496         {
 497             return_ACPI_STATUS (Status2);
 498         }
 499 
 500         Status = AE_OK;
 501         break;
 502 
 503     case AE_CTRL_TERMINATE:
 504 
 505         /* Clean up */
 506         do
 507         {
 508             if (*Op)
 509             {
 510                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
 511                 if (ACPI_FAILURE (Status2))
 512                 {
 513                     return_ACPI_STATUS (Status2);
 514                 }
 515 
 516                 AcpiUtDeleteGenericState (
 517                     AcpiUtPopGenericState (&WalkState->ControlState));
 518             }
 519 
 520             AcpiPsPopScope (&(WalkState->ParserState), Op,
 521                 &WalkState->ArgTypes, &WalkState->ArgCount);
 522 
 523         } while (*Op);
 524 
 525         return_ACPI_STATUS (AE_OK);
 526 
 527     default:  /* All other non-AE_OK status */
 528 
 529         do
 530         {
 531             if (*Op)
 532             {
 533                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
 534                 if (ACPI_FAILURE (Status2))
 535                 {
 536                     return_ACPI_STATUS (Status2);
 537                 }
 538             }
 539 
 540             AcpiPsPopScope (&(WalkState->ParserState), Op,
 541                 &WalkState->ArgTypes, &WalkState->ArgCount);
 542 
 543         } while (*Op);
 544 
 545 
 546 #if 0
 547         /*
 548          * TBD: Cleanup parse ops on error
 549          */
 550         if (*Op == NULL)
 551         {
 552             AcpiPsPopScope (ParserState, Op,
 553                 &WalkState->ArgTypes, &WalkState->ArgCount);
 554         }
 555 #endif
 556         WalkState->PrevOp = NULL;
 557         WalkState->PrevArgTypes = WalkState->ArgTypes;
 558         return_ACPI_STATUS (Status);
 559     }
 560 
 561     /* This scope complete? */
 562 
 563     if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
 564     {
 565         AcpiPsPopScope (&(WalkState->ParserState), Op,
 566             &WalkState->ArgTypes, &WalkState->ArgCount);
 567         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
 568     }
 569     else
 570     {
 571         *Op = NULL;
 572     }
 573 
 574     return_ACPI_STATUS (AE_OK);
 575 }
 576 
 577 
 578 /*******************************************************************************
 579  *
 580  * FUNCTION:    AcpiPsCompleteFinalOp
 581  *
 582  * PARAMETERS:  WalkState           - Current state
 583  *              Op                  - Current Op
 584  *              Status              - Current parse status before complete last
 585  *                                    Op
 586  *
 587  * RETURN:      Status
 588  *
 589  * DESCRIPTION: Complete last Op.
 590  *
 591  ******************************************************************************/
 592 
 593 ACPI_STATUS
 594 AcpiPsCompleteFinalOp (
 595     ACPI_WALK_STATE         *WalkState,
 596     ACPI_PARSE_OBJECT       *Op,
 597     ACPI_STATUS             Status)
 598 {
 599     ACPI_STATUS             Status2;
 600 
 601 
 602     ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
 603 
 604 
 605     /*
 606      * Complete the last Op (if not completed), and clear the scope stack.
 607      * It is easily possible to end an AML "package" with an unbounded number
 608      * of open scopes (such as when several ASL blocks are closed with
 609      * sequential closing braces). We want to terminate each one cleanly.
 610      */
 611     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
 612     do
 613     {
 614         if (Op)
 615         {
 616             if (WalkState->AscendingCallback != NULL)
 617             {
 618                 WalkState->Op = Op;
 619                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
 620                 WalkState->Opcode = Op->Common.AmlOpcode;
 621 
 622                 Status = WalkState->AscendingCallback (WalkState);
 623                 Status = AcpiPsNextParseState (WalkState, Op, Status);
 624                 if (Status == AE_CTRL_PENDING)
 625                 {
 626                     Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
 627                     if (ACPI_FAILURE (Status))
 628                     {
 629                         return_ACPI_STATUS (Status);
 630                     }
 631                 }
 632 
 633                 if (Status == AE_CTRL_TERMINATE)
 634                 {
 635                     Status = AE_OK;
 636 
 637                     /* Clean up */
 638                     do
 639                     {
 640                         if (Op)
 641                         {
 642                             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
 643                             if (ACPI_FAILURE (Status2))
 644                             {
 645                                 return_ACPI_STATUS (Status2);
 646                             }
 647                         }
 648 
 649                         AcpiPsPopScope (&(WalkState->ParserState), &Op,
 650                             &WalkState->ArgTypes, &WalkState->ArgCount);
 651 
 652                     } while (Op);
 653 
 654                     return_ACPI_STATUS (Status);
 655                 }
 656 
 657                 else if (ACPI_FAILURE (Status))
 658                 {
 659                     /* First error is most important */
 660 
 661                     (void) AcpiPsCompleteThisOp (WalkState, Op);
 662                     return_ACPI_STATUS (Status);
 663                 }
 664             }
 665 
 666             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
 667             if (ACPI_FAILURE (Status2))
 668             {
 669                 return_ACPI_STATUS (Status2);
 670             }
 671         }
 672 
 673         AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
 674             &WalkState->ArgCount);
 675 
 676     } while (Op);
 677 
 678     return_ACPI_STATUS (Status);
 679 }