Home | History | Annotate | Line # | Download | only in dispatcher
dswstate.c revision 1.1.1.6
      1 /******************************************************************************
      2  *
      3  * Module Name: dswstate - Dispatcher parse tree walk management routines
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2016, 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 "acdispat.h"
     48 #include "acnamesp.h"
     49 
     50 #define _COMPONENT          ACPI_DISPATCHER
     51         ACPI_MODULE_NAME    ("dswstate")
     52 
     53 /* Local prototypes */
     54 
     55 static ACPI_STATUS
     56 AcpiDsResultStackPush (
     57     ACPI_WALK_STATE         *WalkState);
     58 
     59 static ACPI_STATUS
     60 AcpiDsResultStackPop (
     61     ACPI_WALK_STATE         *WalkState);
     62 
     63 
     64 /*******************************************************************************
     65  *
     66  * FUNCTION:    AcpiDsResultPop
     67  *
     68  * PARAMETERS:  Object              - Where to return the popped object
     69  *              WalkState           - Current Walk state
     70  *
     71  * RETURN:      Status
     72  *
     73  * DESCRIPTION: Pop an object off the top of this walk's result stack
     74  *
     75  ******************************************************************************/
     76 
     77 ACPI_STATUS
     78 AcpiDsResultPop (
     79     ACPI_OPERAND_OBJECT     **Object,
     80     ACPI_WALK_STATE         *WalkState)
     81 {
     82     UINT32                  Index;
     83     ACPI_GENERIC_STATE      *State;
     84     ACPI_STATUS             Status;
     85 
     86 
     87     ACPI_FUNCTION_NAME (DsResultPop);
     88 
     89 
     90     State = WalkState->Results;
     91 
     92     /* Incorrect state of result stack */
     93 
     94     if (State && !WalkState->ResultCount)
     95     {
     96         ACPI_ERROR ((AE_INFO, "No results on result stack"));
     97         return (AE_AML_INTERNAL);
     98     }
     99 
    100     if (!State && WalkState->ResultCount)
    101     {
    102         ACPI_ERROR ((AE_INFO, "No result state for result stack"));
    103         return (AE_AML_INTERNAL);
    104     }
    105 
    106     /* Empty result stack */
    107 
    108     if (!State)
    109     {
    110         ACPI_ERROR ((AE_INFO, "Result stack is empty! State=%p", WalkState));
    111         return (AE_AML_NO_RETURN_VALUE);
    112     }
    113 
    114     /* Return object of the top element and clean that top element result stack */
    115 
    116     WalkState->ResultCount--;
    117     Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
    118 
    119     *Object = State->Results.ObjDesc [Index];
    120     if (!*Object)
    121     {
    122         ACPI_ERROR ((AE_INFO, "No result objects on result stack, State=%p",
    123             WalkState));
    124         return (AE_AML_NO_RETURN_VALUE);
    125     }
    126 
    127     State->Results.ObjDesc [Index] = NULL;
    128     if (Index == 0)
    129     {
    130         Status = AcpiDsResultStackPop (WalkState);
    131         if (ACPI_FAILURE (Status))
    132         {
    133             return (Status);
    134         }
    135     }
    136 
    137     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    138         "Obj=%p [%s] Index=%X State=%p Num=%X\n", *Object,
    139         AcpiUtGetObjectTypeName (*Object),
    140         Index, WalkState, WalkState->ResultCount));
    141 
    142     return (AE_OK);
    143 }
    144 
    145 
    146 /*******************************************************************************
    147  *
    148  * FUNCTION:    AcpiDsResultPush
    149  *
    150  * PARAMETERS:  Object              - Where to return the popped object
    151  *              WalkState           - Current Walk state
    152  *
    153  * RETURN:      Status
    154  *
    155  * DESCRIPTION: Push an object onto the current result stack
    156  *
    157  ******************************************************************************/
    158 
    159 ACPI_STATUS
    160 AcpiDsResultPush (
    161     ACPI_OPERAND_OBJECT     *Object,
    162     ACPI_WALK_STATE         *WalkState)
    163 {
    164     ACPI_GENERIC_STATE      *State;
    165     ACPI_STATUS             Status;
    166     UINT32                  Index;
    167 
    168 
    169     ACPI_FUNCTION_NAME (DsResultPush);
    170 
    171 
    172     if (WalkState->ResultCount > WalkState->ResultSize)
    173     {
    174         ACPI_ERROR ((AE_INFO, "Result stack is full"));
    175         return (AE_AML_INTERNAL);
    176     }
    177     else if (WalkState->ResultCount == WalkState->ResultSize)
    178     {
    179         /* Extend the result stack */
    180 
    181         Status = AcpiDsResultStackPush (WalkState);
    182         if (ACPI_FAILURE (Status))
    183         {
    184             ACPI_ERROR ((AE_INFO, "Failed to extend the result stack"));
    185             return (Status);
    186         }
    187     }
    188 
    189     if (!(WalkState->ResultCount < WalkState->ResultSize))
    190     {
    191         ACPI_ERROR ((AE_INFO, "No free elements in result stack"));
    192         return (AE_AML_INTERNAL);
    193     }
    194 
    195     State = WalkState->Results;
    196     if (!State)
    197     {
    198         ACPI_ERROR ((AE_INFO, "No result stack frame during push"));
    199         return (AE_AML_INTERNAL);
    200     }
    201 
    202     if (!Object)
    203     {
    204         ACPI_ERROR ((AE_INFO,
    205             "Null Object! Obj=%p State=%p Num=%u",
    206             Object, WalkState, WalkState->ResultCount));
    207         return (AE_BAD_PARAMETER);
    208     }
    209 
    210     /* Assign the address of object to the top free element of result stack */
    211 
    212     Index = (UINT32) WalkState->ResultCount % ACPI_RESULTS_FRAME_OBJ_NUM;
    213     State->Results.ObjDesc [Index] = Object;
    214     WalkState->ResultCount++;
    215 
    216     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
    217         Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
    218         WalkState, WalkState->ResultCount, WalkState->CurrentResult));
    219 
    220     return (AE_OK);
    221 }
    222 
    223 
    224 /*******************************************************************************
    225  *
    226  * FUNCTION:    AcpiDsResultStackPush
    227  *
    228  * PARAMETERS:  WalkState           - Current Walk state
    229  *
    230  * RETURN:      Status
    231  *
    232  * DESCRIPTION: Push an object onto the WalkState result stack
    233  *
    234  ******************************************************************************/
    235 
    236 static ACPI_STATUS
    237 AcpiDsResultStackPush (
    238     ACPI_WALK_STATE         *WalkState)
    239 {
    240     ACPI_GENERIC_STATE      *State;
    241 
    242 
    243     ACPI_FUNCTION_NAME (DsResultStackPush);
    244 
    245 
    246     /* Check for stack overflow */
    247 
    248     if (((UINT32) WalkState->ResultSize + ACPI_RESULTS_FRAME_OBJ_NUM) >
    249         ACPI_RESULTS_OBJ_NUM_MAX)
    250     {
    251         ACPI_ERROR ((AE_INFO, "Result stack overflow: State=%p Num=%u",
    252             WalkState, WalkState->ResultSize));
    253         return (AE_STACK_OVERFLOW);
    254     }
    255 
    256     State = AcpiUtCreateGenericState ();
    257     if (!State)
    258     {
    259         return (AE_NO_MEMORY);
    260     }
    261 
    262     State->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RESULT;
    263     AcpiUtPushGenericState (&WalkState->Results, State);
    264 
    265     /* Increase the length of the result stack by the length of frame */
    266 
    267     WalkState->ResultSize += ACPI_RESULTS_FRAME_OBJ_NUM;
    268 
    269     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
    270         State, WalkState));
    271 
    272     return (AE_OK);
    273 }
    274 
    275 
    276 /*******************************************************************************
    277  *
    278  * FUNCTION:    AcpiDsResultStackPop
    279  *
    280  * PARAMETERS:  WalkState           - Current Walk state
    281  *
    282  * RETURN:      Status
    283  *
    284  * DESCRIPTION: Pop an object off of the WalkState result stack
    285  *
    286  ******************************************************************************/
    287 
    288 static ACPI_STATUS
    289 AcpiDsResultStackPop (
    290     ACPI_WALK_STATE         *WalkState)
    291 {
    292     ACPI_GENERIC_STATE      *State;
    293 
    294 
    295     ACPI_FUNCTION_NAME (DsResultStackPop);
    296 
    297 
    298     /* Check for stack underflow */
    299 
    300     if (WalkState->Results == NULL)
    301     {
    302         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    303             "Result stack underflow - State=%p\n", WalkState));
    304         return (AE_AML_NO_OPERAND);
    305     }
    306 
    307     if (WalkState->ResultSize < ACPI_RESULTS_FRAME_OBJ_NUM)
    308     {
    309         ACPI_ERROR ((AE_INFO, "Insufficient result stack size"));
    310         return (AE_AML_INTERNAL);
    311     }
    312 
    313     State = AcpiUtPopGenericState (&WalkState->Results);
    314     AcpiUtDeleteGenericState (State);
    315 
    316     /* Decrease the length of result stack by the length of frame */
    317 
    318     WalkState->ResultSize -= ACPI_RESULTS_FRAME_OBJ_NUM;
    319 
    320     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
    321         "Result=%p RemainingResults=%X State=%p\n",
    322         State, WalkState->ResultCount, WalkState));
    323 
    324     return (AE_OK);
    325 }
    326 
    327 
    328 /*******************************************************************************
    329  *
    330  * FUNCTION:    AcpiDsObjStackPush
    331  *
    332  * PARAMETERS:  Object              - Object to push
    333  *              WalkState           - Current Walk state
    334  *
    335  * RETURN:      Status
    336  *
    337  * DESCRIPTION: Push an object onto this walk's object/operand stack
    338  *
    339  ******************************************************************************/
    340 
    341 ACPI_STATUS
    342 AcpiDsObjStackPush (
    343     void                    *Object,
    344     ACPI_WALK_STATE         *WalkState)
    345 {
    346     ACPI_FUNCTION_NAME (DsObjStackPush);
    347 
    348 
    349     /* Check for stack overflow */
    350 
    351     if (WalkState->NumOperands >= ACPI_OBJ_NUM_OPERANDS)
    352     {
    353         ACPI_ERROR ((AE_INFO,
    354             "Object stack overflow! Obj=%p State=%p #Ops=%u",
    355             Object, WalkState, WalkState->NumOperands));
    356         return (AE_STACK_OVERFLOW);
    357     }
    358 
    359     /* Put the object onto the stack */
    360 
    361     WalkState->Operands [WalkState->OperandIndex] = Object;
    362     WalkState->NumOperands++;
    363 
    364     /* For the usual order of filling the operand stack */
    365 
    366     WalkState->OperandIndex++;
    367 
    368     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
    369         Object, AcpiUtGetObjectTypeName ((ACPI_OPERAND_OBJECT *) Object),
    370         WalkState, WalkState->NumOperands));
    371 
    372     return (AE_OK);
    373 }
    374 
    375 
    376 /*******************************************************************************
    377  *
    378  * FUNCTION:    AcpiDsObjStackPop
    379  *
    380  * PARAMETERS:  PopCount            - Number of objects/entries to pop
    381  *              WalkState           - Current Walk state
    382  *
    383  * RETURN:      Status
    384  *
    385  * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
    386  *              deleted by this routine.
    387  *
    388  ******************************************************************************/
    389 
    390 ACPI_STATUS
    391 AcpiDsObjStackPop (
    392     UINT32                  PopCount,
    393     ACPI_WALK_STATE         *WalkState)
    394 {
    395     UINT32                  i;
    396 
    397 
    398     ACPI_FUNCTION_NAME (DsObjStackPop);
    399 
    400 
    401     for (i = 0; i < PopCount; i++)
    402     {
    403         /* Check for stack underflow */
    404 
    405         if (WalkState->NumOperands == 0)
    406         {
    407             ACPI_ERROR ((AE_INFO,
    408                 "Object stack underflow! Count=%X State=%p #Ops=%u",
    409                 PopCount, WalkState, WalkState->NumOperands));
    410             return (AE_STACK_UNDERFLOW);
    411         }
    412 
    413         /* Just set the stack entry to null */
    414 
    415         WalkState->NumOperands--;
    416         WalkState->Operands [WalkState->NumOperands] = NULL;
    417     }
    418 
    419     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%u\n",
    420         PopCount, WalkState, WalkState->NumOperands));
    421 
    422     return (AE_OK);
    423 }
    424 
    425 
    426 /*******************************************************************************
    427  *
    428  * FUNCTION:    AcpiDsObjStackPopAndDelete
    429  *
    430  * PARAMETERS:  PopCount            - Number of objects/entries to pop
    431  *              WalkState           - Current Walk state
    432  *
    433  * RETURN:      Status
    434  *
    435  * DESCRIPTION: Pop this walk's object stack and delete each object that is
    436  *              popped off.
    437  *
    438  ******************************************************************************/
    439 
    440 void
    441 AcpiDsObjStackPopAndDelete (
    442     UINT32                  PopCount,
    443     ACPI_WALK_STATE         *WalkState)
    444 {
    445     INT32                   i;
    446     ACPI_OPERAND_OBJECT     *ObjDesc;
    447 
    448 
    449     ACPI_FUNCTION_NAME (DsObjStackPopAndDelete);
    450 
    451 
    452     if (PopCount == 0)
    453     {
    454         return;
    455     }
    456 
    457     for (i = (INT32) PopCount - 1; i >= 0; i--)
    458     {
    459         if (WalkState->NumOperands == 0)
    460         {
    461             return;
    462         }
    463 
    464         /* Pop the stack and delete an object if present in this stack entry */
    465 
    466         WalkState->NumOperands--;
    467         ObjDesc = WalkState->Operands [i];
    468         if (ObjDesc)
    469         {
    470             AcpiUtRemoveReference (WalkState->Operands [i]);
    471             WalkState->Operands [i] = NULL;
    472         }
    473     }
    474 
    475     ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
    476         PopCount, WalkState, WalkState->NumOperands));
    477 }
    478 
    479 
    480 /*******************************************************************************
    481  *
    482  * FUNCTION:    AcpiDsGetCurrentWalkState
    483  *
    484  * PARAMETERS:  Thread          - Get current active state for this Thread
    485  *
    486  * RETURN:      Pointer to the current walk state
    487  *
    488  * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
    489  *              walk state.)
    490  *
    491  ******************************************************************************/
    492 
    493 ACPI_WALK_STATE *
    494 AcpiDsGetCurrentWalkState (
    495     ACPI_THREAD_STATE       *Thread)
    496 {
    497     ACPI_FUNCTION_NAME (DsGetCurrentWalkState);
    498 
    499 
    500     if (!Thread)
    501     {
    502         return (NULL);
    503     }
    504 
    505     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current WalkState %p\n",
    506         Thread->WalkStateList));
    507 
    508     return (Thread->WalkStateList);
    509 }
    510 
    511 
    512 /*******************************************************************************
    513  *
    514  * FUNCTION:    AcpiDsPushWalkState
    515  *
    516  * PARAMETERS:  WalkState       - State to push
    517  *              Thread          - Thread state object
    518  *
    519  * RETURN:      None
    520  *
    521  * DESCRIPTION: Place the Thread state at the head of the state list
    522  *
    523  ******************************************************************************/
    524 
    525 void
    526 AcpiDsPushWalkState (
    527     ACPI_WALK_STATE         *WalkState,
    528     ACPI_THREAD_STATE       *Thread)
    529 {
    530     ACPI_FUNCTION_TRACE (DsPushWalkState);
    531 
    532 
    533     WalkState->Next = Thread->WalkStateList;
    534     Thread->WalkStateList = WalkState;
    535 
    536     return_VOID;
    537 }
    538 
    539 
    540 /*******************************************************************************
    541  *
    542  * FUNCTION:    AcpiDsPopWalkState
    543  *
    544  * PARAMETERS:  Thread      - Current thread state
    545  *
    546  * RETURN:      A WalkState object popped from the thread's stack
    547  *
    548  * DESCRIPTION: Remove and return the walkstate object that is at the head of
    549  *              the walk stack for the given walk list. NULL indicates that
    550  *              the list is empty.
    551  *
    552  ******************************************************************************/
    553 
    554 ACPI_WALK_STATE *
    555 AcpiDsPopWalkState (
    556     ACPI_THREAD_STATE       *Thread)
    557 {
    558     ACPI_WALK_STATE         *WalkState;
    559 
    560 
    561     ACPI_FUNCTION_TRACE (DsPopWalkState);
    562 
    563 
    564     WalkState = Thread->WalkStateList;
    565 
    566     if (WalkState)
    567     {
    568         /* Next walk state becomes the current walk state */
    569 
    570         Thread->WalkStateList = WalkState->Next;
    571 
    572         /*
    573          * Don't clear the NEXT field, this serves as an indicator
    574          * that there is a parent WALK STATE
    575          * Do Not: WalkState->Next = NULL;
    576          */
    577     }
    578 
    579     return_PTR (WalkState);
    580 }
    581 
    582 
    583 /*******************************************************************************
    584  *
    585  * FUNCTION:    AcpiDsCreateWalkState
    586  *
    587  * PARAMETERS:  OwnerId         - ID for object creation
    588  *              Origin          - Starting point for this walk
    589  *              MethodDesc      - Method object
    590  *              Thread          - Current thread state
    591  *
    592  * RETURN:      Pointer to the new walk state.
    593  *
    594  * DESCRIPTION: Allocate and initialize a new walk state. The current walk
    595  *              state is set to this new state.
    596  *
    597  ******************************************************************************/
    598 
    599 ACPI_WALK_STATE *
    600 AcpiDsCreateWalkState (
    601     ACPI_OWNER_ID           OwnerId,
    602     ACPI_PARSE_OBJECT       *Origin,
    603     ACPI_OPERAND_OBJECT     *MethodDesc,
    604     ACPI_THREAD_STATE       *Thread)
    605 {
    606     ACPI_WALK_STATE         *WalkState;
    607 
    608 
    609     ACPI_FUNCTION_TRACE (DsCreateWalkState);
    610 
    611 
    612     WalkState = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_WALK_STATE));
    613     if (!WalkState)
    614     {
    615         return_PTR (NULL);
    616     }
    617 
    618     WalkState->DescriptorType = ACPI_DESC_TYPE_WALK;
    619     WalkState->MethodDesc = MethodDesc;
    620     WalkState->OwnerId = OwnerId;
    621     WalkState->Origin = Origin;
    622     WalkState->Thread = Thread;
    623 
    624     WalkState->ParserState.StartOp = Origin;
    625 
    626     /* Init the method args/local */
    627 
    628 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
    629     AcpiDsMethodDataInit (WalkState);
    630 #endif
    631 
    632     /* Put the new state at the head of the walk list */
    633 
    634     if (Thread)
    635     {
    636         AcpiDsPushWalkState (WalkState, Thread);
    637     }
    638 
    639     return_PTR (WalkState);
    640 }
    641 
    642 
    643 /*******************************************************************************
    644  *
    645  * FUNCTION:    AcpiDsInitAmlWalk
    646  *
    647  * PARAMETERS:  WalkState       - New state to be initialized
    648  *              Op              - Current parse op
    649  *              MethodNode      - Control method NS node, if any
    650  *              AmlStart        - Start of AML
    651  *              AmlLength       - Length of AML
    652  *              Info            - Method info block (params, etc.)
    653  *              PassNumber      - 1, 2, or 3
    654  *
    655  * RETURN:      Status
    656  *
    657  * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
    658  *
    659  ******************************************************************************/
    660 
    661 ACPI_STATUS
    662 AcpiDsInitAmlWalk (
    663     ACPI_WALK_STATE         *WalkState,
    664     ACPI_PARSE_OBJECT       *Op,
    665     ACPI_NAMESPACE_NODE     *MethodNode,
    666     UINT8                   *AmlStart,
    667     UINT32                  AmlLength,
    668     ACPI_EVALUATE_INFO      *Info,
    669     UINT8                   PassNumber)
    670 {
    671     ACPI_STATUS             Status;
    672     ACPI_PARSE_STATE        *ParserState = &WalkState->ParserState;
    673     ACPI_PARSE_OBJECT       *ExtraOp;
    674 
    675 
    676     ACPI_FUNCTION_TRACE (DsInitAmlWalk);
    677 
    678 
    679     WalkState->ParserState.Aml =
    680     WalkState->ParserState.AmlStart = AmlStart;
    681     WalkState->ParserState.AmlEnd =
    682     WalkState->ParserState.PkgEnd = AmlStart + AmlLength;
    683 
    684     /* The NextOp of the NextWalk will be the beginning of the method */
    685 
    686     WalkState->NextOp = NULL;
    687     WalkState->PassNumber = PassNumber;
    688 
    689     if (Info)
    690     {
    691         WalkState->Params = Info->Parameters;
    692         WalkState->CallerReturnDesc = &Info->ReturnObject;
    693     }
    694 
    695     Status = AcpiPsInitScope (&WalkState->ParserState, Op);
    696     if (ACPI_FAILURE (Status))
    697     {
    698         return_ACPI_STATUS (Status);
    699     }
    700 
    701     if (MethodNode)
    702     {
    703         WalkState->ParserState.StartNode = MethodNode;
    704         WalkState->WalkType = ACPI_WALK_METHOD;
    705         WalkState->MethodNode = MethodNode;
    706         WalkState->MethodDesc = AcpiNsGetAttachedObject (MethodNode);
    707 
    708         /* Push start scope on scope stack and make it current  */
    709 
    710         Status = AcpiDsScopeStackPush (
    711             MethodNode, ACPI_TYPE_METHOD, WalkState);
    712         if (ACPI_FAILURE (Status))
    713         {
    714             return_ACPI_STATUS (Status);
    715         }
    716 
    717         /* Init the method arguments */
    718 
    719         Status = AcpiDsMethodDataInitArgs (WalkState->Params,
    720                     ACPI_METHOD_NUM_ARGS, WalkState);
    721         if (ACPI_FAILURE (Status))
    722         {
    723             return_ACPI_STATUS (Status);
    724         }
    725     }
    726     else
    727     {
    728         /*
    729          * Setup the current scope.
    730          * Find a Named Op that has a namespace node associated with it.
    731          * search upwards from this Op. Current scope is the first
    732          * Op with a namespace node.
    733          */
    734         ExtraOp = ParserState->StartOp;
    735         while (ExtraOp && !ExtraOp->Common.Node)
    736         {
    737             ExtraOp = ExtraOp->Common.Parent;
    738         }
    739 
    740         if (!ExtraOp)
    741         {
    742             ParserState->StartNode = NULL;
    743         }
    744         else
    745         {
    746             ParserState->StartNode = ExtraOp->Common.Node;
    747         }
    748 
    749         if (ParserState->StartNode)
    750         {
    751             /* Push start scope on scope stack and make it current  */
    752 
    753             Status = AcpiDsScopeStackPush (ParserState->StartNode,
    754                 ParserState->StartNode->Type, WalkState);
    755             if (ACPI_FAILURE (Status))
    756             {
    757                 return_ACPI_STATUS (Status);
    758             }
    759         }
    760     }
    761 
    762     Status = AcpiDsInitCallbacks (WalkState, PassNumber);
    763     return_ACPI_STATUS (Status);
    764 }
    765 
    766 
    767 /*******************************************************************************
    768  *
    769  * FUNCTION:    AcpiDsDeleteWalkState
    770  *
    771  * PARAMETERS:  WalkState       - State to delete
    772  *
    773  * RETURN:      Status
    774  *
    775  * DESCRIPTION: Delete a walk state including all internal data structures
    776  *
    777  ******************************************************************************/
    778 
    779 void
    780 AcpiDsDeleteWalkState (
    781     ACPI_WALK_STATE         *WalkState)
    782 {
    783     ACPI_GENERIC_STATE      *State;
    784 
    785 
    786     ACPI_FUNCTION_TRACE_PTR (DsDeleteWalkState, WalkState);
    787 
    788 
    789     if (!WalkState)
    790     {
    791         return_VOID;
    792     }
    793 
    794     if (WalkState->DescriptorType != ACPI_DESC_TYPE_WALK)
    795     {
    796         ACPI_ERROR ((AE_INFO, "%p is not a valid walk state",
    797             WalkState));
    798         return_VOID;
    799     }
    800 
    801     /* There should not be any open scopes */
    802 
    803     if (WalkState->ParserState.Scope)
    804     {
    805         ACPI_ERROR ((AE_INFO, "%p walk still has a scope list",
    806             WalkState));
    807         AcpiPsCleanupScope (&WalkState->ParserState);
    808     }
    809 
    810     /* Always must free any linked control states */
    811 
    812     while (WalkState->ControlState)
    813     {
    814         State = WalkState->ControlState;
    815         WalkState->ControlState = State->Common.Next;
    816 
    817         AcpiUtDeleteGenericState (State);
    818     }
    819 
    820     /* Always must free any linked parse states */
    821 
    822     while (WalkState->ScopeInfo)
    823     {
    824         State = WalkState->ScopeInfo;
    825         WalkState->ScopeInfo = State->Common.Next;
    826 
    827         AcpiUtDeleteGenericState (State);
    828     }
    829 
    830     /* Always must free any stacked result states */
    831 
    832     while (WalkState->Results)
    833     {
    834         State = WalkState->Results;
    835         WalkState->Results = State->Common.Next;
    836 
    837         AcpiUtDeleteGenericState (State);
    838     }
    839 
    840     ACPI_FREE (WalkState);
    841     return_VOID;
    842 }
    843