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