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