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