dswstate.c revision 67754
1/****************************************************************************** 2 * 3 * Module Name: dswstate - Dispatcher parse tree walk management routines 4 * $Revision: 31 $ 5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 13 * reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118#define __DSWSTATE_C__ 119 120#include "acpi.h" 121#include "amlcode.h" 122#include "acparser.h" 123#include "acdispat.h" 124#include "acnamesp.h" 125#include "acinterp.h" 126 127#define _COMPONENT DISPATCHER 128 MODULE_NAME ("dswstate") 129 130 131/******************************************************************************* 132 * 133 * FUNCTION: AcpiDsResultStackClear 134 * 135 * PARAMETERS: WalkState - Current Walk state 136 * 137 * RETURN: Status 138 * 139 * DESCRIPTION: Reset this walk's result stack pointers to zero, thus setting 140 * the stack to zero. 141 * 142 ******************************************************************************/ 143 144ACPI_STATUS 145AcpiDsResultStackClear ( 146 ACPI_WALK_STATE *WalkState) 147{ 148 149 WalkState->NumResults = 0; 150 WalkState->CurrentResult = 0; 151 152 return (AE_OK); 153} 154 155 156/******************************************************************************* 157 * 158 * FUNCTION: AcpiDsResultStackPush 159 * 160 * PARAMETERS: Object - Object to push 161 * WalkState - Current Walk state 162 * 163 * RETURN: Status 164 * 165 * DESCRIPTION: Push an object onto this walk's result stack 166 * 167 ******************************************************************************/ 168 169ACPI_STATUS 170AcpiDsResultStackPush ( 171 void *Object, 172 ACPI_WALK_STATE *WalkState) 173{ 174 175 176 if (WalkState->NumResults >= OBJ_NUM_OPERANDS) 177 { 178 DEBUG_PRINT (ACPI_ERROR, 179 ("DsResultStackPush: overflow! Obj=%p State=%p Num=%X\n", 180 Object, WalkState, WalkState->NumResults)); 181 return (AE_STACK_OVERFLOW); 182 } 183 184 WalkState->Results [WalkState->NumResults] = Object; 185 WalkState->NumResults++; 186 187 DEBUG_PRINT (TRACE_EXEC, 188 ("DsResultStackPush: Obj=%p State=%p Num=%X Cur=%X\n", 189 Object, WalkState, WalkState->NumResults, WalkState->CurrentResult)); 190 191 return (AE_OK); 192} 193 194 195/******************************************************************************* 196 * 197 * FUNCTION: AcpiDsResultStackPop 198 * 199 * PARAMETERS: Object - Where to return the popped object 200 * WalkState - Current Walk state 201 * 202 * RETURN: Status 203 * 204 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In 205 * other words, this is a FIFO. 206 * 207 ******************************************************************************/ 208 209ACPI_STATUS 210AcpiDsResultStackPop ( 211 ACPI_OPERAND_OBJECT **Object, 212 ACPI_WALK_STATE *WalkState) 213{ 214 215 216 /* Check for stack underflow */ 217 218 if (WalkState->NumResults == 0) 219 { 220 DEBUG_PRINT (ACPI_ERROR, 221 ("DsResultStackPop: Underflow! State=%p Cur=%X Num=%X\n", 222 WalkState, WalkState->CurrentResult, WalkState->NumResults)); 223 return (AE_AML_NO_OPERAND); 224 } 225 226 227 /* Pop the stack */ 228 229 WalkState->NumResults--; 230 231 /* Check for a valid result object */ 232 233 if (!WalkState->Results [WalkState->NumResults]) 234 { 235 DEBUG_PRINT (ACPI_ERROR, 236 ("DsResultStackPop: Null operand! State=%p #Ops=%X\n", 237 WalkState, WalkState->NumResults)); 238 return (AE_AML_NO_OPERAND); 239 } 240 241 *Object = WalkState->Results [WalkState->NumResults]; 242 WalkState->Results [WalkState->NumResults] = NULL; 243 244 DEBUG_PRINT (TRACE_EXEC, 245 ("DsResultStackPop: Obj=%p State=%p Num=%X Cur=%X\n", 246 *Object, WalkState, WalkState->NumResults, WalkState->CurrentResult)); 247 248 return (AE_OK); 249} 250 251 252/******************************************************************************* 253 * 254 * FUNCTION: AcpiDsObjStackDeleteAll 255 * 256 * PARAMETERS: WalkState - Current Walk state 257 * 258 * RETURN: Status 259 * 260 * DESCRIPTION: Clear the object stack by deleting all objects that are on it. 261 * Should be used with great care, if at all! 262 * 263 ******************************************************************************/ 264 265ACPI_STATUS 266AcpiDsObjStackDeleteAll ( 267 ACPI_WALK_STATE *WalkState) 268{ 269 UINT32 i; 270 271 272 FUNCTION_TRACE_PTR ("DsObjStackDeleteAll", WalkState); 273 274 275 /* The stack size is configurable, but fixed */ 276 277 for (i = 0; i < OBJ_NUM_OPERANDS; i++) 278 { 279 if (WalkState->Operands[i]) 280 { 281 AcpiCmRemoveReference (WalkState->Operands[i]); 282 WalkState->Operands[i] = NULL; 283 } 284 } 285 286 return_ACPI_STATUS (AE_OK); 287} 288 289 290/******************************************************************************* 291 * 292 * FUNCTION: AcpiDsObjStackPush 293 * 294 * PARAMETERS: Object - Object to push 295 * WalkState - Current Walk state 296 * 297 * RETURN: Status 298 * 299 * DESCRIPTION: Push an object onto this walk's object/operand stack 300 * 301 ******************************************************************************/ 302 303ACPI_STATUS 304AcpiDsObjStackPush ( 305 void *Object, 306 ACPI_WALK_STATE *WalkState) 307{ 308 309 310 /* Check for stack overflow */ 311 312 if (WalkState->NumOperands >= OBJ_NUM_OPERANDS) 313 { 314 DEBUG_PRINT (ACPI_ERROR, 315 ("DsObjStackPush: overflow! Obj=%p State=%p #Ops=%X\n", 316 Object, WalkState, WalkState->NumOperands)); 317 return (AE_STACK_OVERFLOW); 318 } 319 320 /* Put the object onto the stack */ 321 322 WalkState->Operands [WalkState->NumOperands] = Object; 323 WalkState->NumOperands++; 324 325 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPush: Obj=%p State=%p #Ops=%X\n", 326 Object, WalkState, WalkState->NumOperands)); 327 328 return (AE_OK); 329} 330 331 332/******************************************************************************* 333 * 334 * FUNCTION: AcpiDsObjStackPopObject 335 * 336 * PARAMETERS: PopCount - Number of objects/entries to pop 337 * WalkState - Current Walk state 338 * 339 * RETURN: Status 340 * 341 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 342 * deleted by this routine. 343 * 344 ******************************************************************************/ 345 346ACPI_STATUS 347AcpiDsObjStackPopObject ( 348 ACPI_OPERAND_OBJECT **Object, 349 ACPI_WALK_STATE *WalkState) 350{ 351 352 353 /* Check for stack underflow */ 354 355 if (WalkState->NumOperands == 0) 356 { 357 DEBUG_PRINT (ACPI_ERROR, 358 ("DsObjStackPop: Missing operand/stack empty! State=%p #Ops=%X\n", 359 WalkState, WalkState->NumOperands)); 360 return (AE_AML_NO_OPERAND); 361 } 362 363 364 /* Pop the stack */ 365 366 WalkState->NumOperands--; 367 368 /* Check for a valid operand */ 369 370 if (!WalkState->Operands [WalkState->NumOperands]) 371 { 372 DEBUG_PRINT (ACPI_ERROR, 373 ("DsObjStackPop: Null operand! State=%p #Ops=%X\n", 374 WalkState, WalkState->NumOperands)); 375 return (AE_AML_NO_OPERAND); 376 } 377 378 /* Get operand and set stack entry to null */ 379 380 *Object = WalkState->Operands [WalkState->NumOperands]; 381 WalkState->Operands [WalkState->NumOperands] = NULL; 382 383 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPopObject: State=%p #Ops=%X\n", 384 WalkState, WalkState->NumOperands)); 385 386 return (AE_OK); 387} 388 389 390/******************************************************************************* 391 * 392 * FUNCTION: AcpiDsObjStackPop 393 * 394 * PARAMETERS: PopCount - Number of objects/entries to pop 395 * WalkState - Current Walk state 396 * 397 * RETURN: Status 398 * 399 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT 400 * deleted by this routine. 401 * 402 ******************************************************************************/ 403 404ACPI_STATUS 405AcpiDsObjStackPop ( 406 UINT32 PopCount, 407 ACPI_WALK_STATE *WalkState) 408{ 409 UINT32 i; 410 411 412 for (i = 0; i < PopCount; i++) 413 { 414 /* Check for stack underflow */ 415 416 if (WalkState->NumOperands == 0) 417 { 418 DEBUG_PRINT (ACPI_ERROR, 419 ("DsObjStackPop: Underflow! Count=%X State=%p #Ops=%X\n", 420 PopCount, WalkState, WalkState->NumOperands)); 421 return (AE_STACK_UNDERFLOW); 422 } 423 424 /* Just set the stack entry to null */ 425 426 WalkState->NumOperands--; 427 WalkState->Operands [WalkState->NumOperands] = NULL; 428 } 429 430 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPop: Count=%X State=%p #Ops=%X\n", 431 PopCount, WalkState, WalkState->NumOperands)); 432 433 return (AE_OK); 434} 435 436 437/******************************************************************************* 438 * 439 * FUNCTION: AcpiDsObjStackPopAndDelete 440 * 441 * PARAMETERS: PopCount - Number of objects/entries to pop 442 * WalkState - Current Walk state 443 * 444 * RETURN: Status 445 * 446 * DESCRIPTION: Pop this walk's object stack and delete each object that is 447 * popped off. 448 * 449 ******************************************************************************/ 450 451ACPI_STATUS 452AcpiDsObjStackPopAndDelete ( 453 UINT32 PopCount, 454 ACPI_WALK_STATE *WalkState) 455{ 456 UINT32 i; 457 ACPI_OPERAND_OBJECT *ObjDesc; 458 459 460 for (i = 0; i < PopCount; i++) 461 { 462 /* Check for stack underflow */ 463 464 if (WalkState->NumOperands == 0) 465 { 466 DEBUG_PRINT (ACPI_ERROR, 467 ("DsObjStackPop: Underflow! Count=%X State=%p #Ops=%X\n", 468 PopCount, WalkState, WalkState->NumOperands)); 469 return (AE_STACK_UNDERFLOW); 470 } 471 472 /* Pop the stack and delete an object if present in this stack entry */ 473 474 WalkState->NumOperands--; 475 ObjDesc = WalkState->Operands [WalkState->NumOperands]; 476 if (ObjDesc) 477 { 478 AcpiCmRemoveReference (WalkState->Operands [WalkState->NumOperands]); 479 WalkState->Operands [WalkState->NumOperands] = NULL; 480 } 481 } 482 483 DEBUG_PRINT (TRACE_EXEC, ("DsObjStackPop: Count=%X State=%p #Ops=%X\n", 484 PopCount, WalkState, WalkState->NumOperands)); 485 486 return (AE_OK); 487} 488 489 490/******************************************************************************* 491 * 492 * FUNCTION: AcpiDsObjStackGetValue 493 * 494 * PARAMETERS: Index - Stack index whose value is desired. Based 495 * on the top of the stack (index=0 == top) 496 * WalkState - Current Walk state 497 * 498 * RETURN: Status 499 * 500 * DESCRIPTION: Retrieve an object from this walk's object stack. Index must 501 * be within the range of the current stack pointer. 502 * 503 ******************************************************************************/ 504 505void * 506AcpiDsObjStackGetValue ( 507 UINT32 Index, 508 ACPI_WALK_STATE *WalkState) 509{ 510 511 FUNCTION_TRACE_PTR ("DsObjStackGetValue", WalkState); 512 513 514 /* Can't do it if the stack is empty */ 515 516 if (WalkState->NumOperands == 0) 517 { 518 return_VALUE (NULL); 519 } 520 521 /* or if the index is past the top of the stack */ 522 523 if (Index > (WalkState->NumOperands - (UINT32) 1)) 524 { 525 return_VALUE (NULL); 526 } 527 528 529 return_PTR (WalkState->Operands[(NATIVE_UINT)(WalkState->NumOperands - 1) - 530 Index]); 531} 532 533 534/******************************************************************************* 535 * 536 * FUNCTION: AcpiDsGetCurrentWalkState 537 * 538 * PARAMETERS: WalkList - Get current active state for this walk list 539 * 540 * RETURN: Pointer to the current walk state 541 * 542 * DESCRIPTION: Get the walk state that is at the head of the list (the "current" 543 * walk state. 544 * 545 ******************************************************************************/ 546 547ACPI_WALK_STATE * 548AcpiDsGetCurrentWalkState ( 549 ACPI_WALK_LIST *WalkList) 550 551{ 552 553 DEBUG_PRINT (TRACE_PARSE, ("DsGetCurrentWalkState, =%p\n", WalkList->WalkState)); 554 555 if (!WalkList) 556 { 557 return (NULL); 558 } 559 560 return (WalkList->WalkState); 561} 562 563 564/******************************************************************************* 565 * 566 * FUNCTION: AcpiDsPushWalkState 567 * 568 * PARAMETERS: WalkState - State to push 569 * WalkList - The list that owns the walk stack 570 * 571 * RETURN: None 572 * 573 * DESCRIPTION: Place the WalkState at the head of the state list. 574 * 575 ******************************************************************************/ 576 577void 578AcpiDsPushWalkState ( 579 ACPI_WALK_STATE *WalkState, 580 ACPI_WALK_LIST *WalkList) 581{ 582 583 584 FUNCTION_TRACE ("DsPushWalkState"); 585 586 587 WalkState->Next = WalkList->WalkState; 588 WalkList->WalkState = WalkState; 589 590 return_VOID; 591} 592 593 594/******************************************************************************* 595 * 596 * FUNCTION: AcpiDsPopWalkState 597 * 598 * PARAMETERS: WalkList - The list that owns the walk stack 599 * 600 * RETURN: A WalkState object popped from the stack 601 * 602 * DESCRIPTION: Remove and return the walkstate object that is at the head of 603 * the walk stack for the given walk list. NULL indicates that 604 * the list is empty. 605 * 606 ******************************************************************************/ 607 608ACPI_WALK_STATE * 609AcpiDsPopWalkState ( 610 ACPI_WALK_LIST *WalkList) 611{ 612 ACPI_WALK_STATE *WalkState; 613 614 615 FUNCTION_TRACE ("DsPopWalkState"); 616 617 618 WalkState = WalkList->WalkState; 619 620 if (WalkState) 621 { 622 /* Next walk state becomes the current walk state */ 623 624 WalkList->WalkState = WalkState->Next; 625 626 /* 627 * Don't clear the NEXT field, this serves as an indicator 628 * that there is a parent WALK STATE 629 * WalkState->Next = NULL; 630 */ 631 } 632 633 return_PTR (WalkState); 634} 635 636 637/******************************************************************************* 638 * 639 * FUNCTION: AcpiDsCreateWalkState 640 * 641 * PARAMETERS: Origin - Starting point for this walk 642 * WalkList - Owning walk list 643 * 644 * RETURN: Pointer to the new walk state. 645 * 646 * DESCRIPTION: Allocate and initialize a new walk state. The current walk state 647 * is set to this new state. 648 * 649 ******************************************************************************/ 650 651ACPI_WALK_STATE * 652AcpiDsCreateWalkState ( 653 ACPI_OWNER_ID OwnerId, 654 ACPI_PARSE_OBJECT *Origin, 655 ACPI_OPERAND_OBJECT *MthDesc, 656 ACPI_WALK_LIST *WalkList) 657{ 658 ACPI_WALK_STATE *WalkState; 659 660 661 FUNCTION_TRACE ("DsCreateWalkState"); 662 663 664 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 665 AcpiGbl_WalkStateCacheRequests++; 666 667 /* Check the cache first */ 668 669 if (AcpiGbl_WalkStateCache) 670 { 671 /* There is an object available, use it */ 672 673 WalkState = AcpiGbl_WalkStateCache; 674 AcpiGbl_WalkStateCache = WalkState->Next; 675 676 AcpiGbl_WalkStateCacheHits++; 677 AcpiGbl_WalkStateCacheDepth--; 678 679 DEBUG_PRINT (TRACE_EXEC, ("DsCreateWalkState: State %p from cache\n", WalkState)); 680 681 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 682 } 683 684 else 685 { 686 /* The cache is empty, create a new object */ 687 688 /* Avoid deadlock with AcpiCmCallocate */ 689 690 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 691 692 WalkState = AcpiCmCallocate (sizeof (ACPI_WALK_STATE)); 693 if (!WalkState) 694 { 695 return_VALUE (NULL); 696 } 697 } 698 699 WalkState->DataType = ACPI_DESC_TYPE_WALK; 700 WalkState->OwnerId = OwnerId; 701 WalkState->Origin = Origin; 702 WalkState->MethodDesc = MthDesc; 703 704 /* Init the method args/local */ 705 706 AcpiDsMethodDataInit (WalkState); 707 708 /* Put the new state at the head of the walk list */ 709 710 AcpiDsPushWalkState (WalkState, WalkList); 711 712 return_PTR (WalkState); 713} 714 715 716/******************************************************************************* 717 * 718 * FUNCTION: AcpiDsDeleteWalkState 719 * 720 * PARAMETERS: WalkState - State to delete 721 * 722 * RETURN: Status 723 * 724 * DESCRIPTION: Delete a walk state including all internal data structures 725 * 726 ******************************************************************************/ 727 728void 729AcpiDsDeleteWalkState ( 730 ACPI_WALK_STATE *WalkState) 731{ 732 ACPI_GENERIC_STATE *State; 733 734 735 FUNCTION_TRACE_PTR ("DsDeleteWalkState", WalkState); 736 737 738 if (!WalkState) 739 { 740 return; 741 } 742 743 if (WalkState->DataType != ACPI_DESC_TYPE_WALK) 744 { 745 DEBUG_PRINT (ACPI_ERROR, 746 ("DsDeleteWalkState: **** %p not a valid walk state\n", WalkState)); 747 return; 748 } 749 750 /* Always must free any linked control states */ 751 752 while (WalkState->ControlState) 753 { 754 State = WalkState->ControlState; 755 WalkState->ControlState = State->Common.Next; 756 757 AcpiCmDeleteGenericState (State); 758 } 759 760 761 /* Always must free any linked parse states */ 762 763 while (WalkState->ScopeInfo) 764 { 765 State = WalkState->ScopeInfo; 766 WalkState->ScopeInfo = State->Common.Next; 767 768 AcpiCmDeleteGenericState (State); 769 } 770 771 /* If walk cache is full, just free this wallkstate object */ 772 773 if (AcpiGbl_WalkStateCacheDepth >= MAX_WALK_CACHE_DEPTH) 774 { 775 AcpiCmFree (WalkState); 776 } 777 778 /* Otherwise put this object back into the cache */ 779 780 else 781 { 782 AcpiCmAcquireMutex (ACPI_MTX_CACHES); 783 784 /* Clear the state */ 785 786 MEMSET (WalkState, 0, sizeof (ACPI_WALK_STATE)); 787 WalkState->DataType = ACPI_DESC_TYPE_WALK; 788 789 /* Put the object at the head of the global cache list */ 790 791 WalkState->Next = AcpiGbl_WalkStateCache; 792 AcpiGbl_WalkStateCache = WalkState; 793 AcpiGbl_WalkStateCacheDepth++; 794 795 796 AcpiCmReleaseMutex (ACPI_MTX_CACHES); 797 } 798 799 return_VOID; 800} 801 802 803/****************************************************************************** 804 * 805 * FUNCTION: AcpiDsDeleteWalkStateCache 806 * 807 * PARAMETERS: None 808 * 809 * RETURN: Status 810 * 811 * DESCRIPTION: Purge the global state object cache. Used during subsystem 812 * termination. 813 * 814 ******************************************************************************/ 815 816void 817AcpiDsDeleteWalkStateCache ( 818 void) 819{ 820 ACPI_WALK_STATE *Next; 821 822 823 FUNCTION_TRACE ("DsDeleteWalkStateCache"); 824 825 826 /* Traverse the global cache list */ 827 828 while (AcpiGbl_WalkStateCache) 829 { 830 /* Delete one cached state object */ 831 832 Next = AcpiGbl_WalkStateCache->Next; 833 AcpiCmFree (AcpiGbl_WalkStateCache); 834 AcpiGbl_WalkStateCache = Next; 835 AcpiGbl_WalkStateCacheDepth--; 836 } 837 838 return_VOID; 839} 840 841 842