utmisc.c revision 80062
1/******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * $Revision: 44 $ 5 * 6 ******************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 13 * All rights 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 __UTMISC_C__ 119 120#include "acpi.h" 121#include "acevents.h" 122#include "achware.h" 123#include "acnamesp.h" 124#include "acinterp.h" 125#include "amlcode.h" 126#include "acdebug.h" 127 128 129#define _COMPONENT ACPI_UTILITIES 130 MODULE_NAME ("utmisc") 131 132 133/******************************************************************************* 134 * 135 * FUNCTION: AcpiUtValidAcpiName 136 * 137 * PARAMETERS: Character - The character to be examined 138 * 139 * RETURN: 1 if Character may appear in a name, else 0 140 * 141 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 142 * 1) Upper case alpha 143 * 2) numeric 144 * 3) underscore 145 * 146 ******************************************************************************/ 147 148BOOLEAN 149AcpiUtValidAcpiName ( 150 UINT32 Name) 151{ 152 NATIVE_CHAR *NamePtr = (NATIVE_CHAR *) &Name; 153 UINT32 i; 154 155 156 for (i = 0; i < ACPI_NAME_SIZE; i++) 157 { 158 if (!((NamePtr[i] == '_') || 159 (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') || 160 (NamePtr[i] >= '0' && NamePtr[i] <= '9'))) 161 { 162 return (FALSE); 163 } 164 } 165 166 167 return (TRUE); 168} 169 170 171/******************************************************************************* 172 * 173 * FUNCTION: AcpiUtValidAcpiCharacter 174 * 175 * PARAMETERS: Character - The character to be examined 176 * 177 * RETURN: 1 if Character may appear in a name, else 0 178 * 179 * DESCRIPTION: Check for a printable character 180 * 181 ******************************************************************************/ 182 183BOOLEAN 184AcpiUtValidAcpiCharacter ( 185 NATIVE_CHAR Character) 186{ 187 188 return ((BOOLEAN) ((Character == '_') || 189 (Character >= 'A' && Character <= 'Z') || 190 (Character >= '0' && Character <= '9'))); 191} 192 193/******************************************************************************* 194 * 195 * FUNCTION: AcpiUtStrupr 196 * 197 * PARAMETERS: SrcString - The source string to convert to 198 * 199 * RETURN: SrcString 200 * 201 * DESCRIPTION: Convert string to uppercase 202 * 203 ******************************************************************************/ 204 205NATIVE_CHAR * 206AcpiUtStrupr ( 207 NATIVE_CHAR *SrcString) 208{ 209 NATIVE_CHAR *String; 210 211 212 /* Walk entire string, uppercasing the letters */ 213 214 for (String = SrcString; *String; ) 215 { 216 *String = (char) TOUPPER (*String); 217 String++; 218 } 219 220 221 return (SrcString); 222} 223 224/******************************************************************************* 225 * 226 * FUNCTION: AcpiUtMutexInitialize 227 * 228 * PARAMETERS: None. 229 * 230 * RETURN: Status 231 * 232 * DESCRIPTION: Create the system mutex objects. 233 * 234 ******************************************************************************/ 235 236ACPI_STATUS 237AcpiUtMutexInitialize ( 238 void) 239{ 240 UINT32 i; 241 ACPI_STATUS Status; 242 243 244 FUNCTION_TRACE ("UtMutexInitialize"); 245 246 247 /* 248 * Create each of the predefined mutex objects 249 */ 250 for (i = 0; i < NUM_MTX; i++) 251 { 252 Status = AcpiUtCreateMutex (i); 253 if (ACPI_FAILURE (Status)) 254 { 255 return_ACPI_STATUS (Status); 256 } 257 } 258 259 return_ACPI_STATUS (AE_OK); 260} 261 262 263/******************************************************************************* 264 * 265 * FUNCTION: AcpiUtMutexTerminate 266 * 267 * PARAMETERS: None. 268 * 269 * RETURN: None. 270 * 271 * DESCRIPTION: Delete all of the system mutex objects. 272 * 273 ******************************************************************************/ 274 275void 276AcpiUtMutexTerminate ( 277 void) 278{ 279 UINT32 i; 280 281 282 FUNCTION_TRACE ("UtMutexTerminate"); 283 284 285 /* 286 * Delete each predefined mutex object 287 */ 288 for (i = 0; i < NUM_MTX; i++) 289 { 290 AcpiUtDeleteMutex (i); 291 } 292 293 return_VOID; 294} 295 296 297/******************************************************************************* 298 * 299 * FUNCTION: AcpiUtCreateMutex 300 * 301 * PARAMETERS: MutexID - ID of the mutex to be created 302 * 303 * RETURN: Status 304 * 305 * DESCRIPTION: Create a mutex object. 306 * 307 ******************************************************************************/ 308 309ACPI_STATUS 310AcpiUtCreateMutex ( 311 ACPI_MUTEX_HANDLE MutexId) 312{ 313 ACPI_STATUS Status = AE_OK; 314 315 316 FUNCTION_TRACE_U32 ("UtCreateMutex", MutexId); 317 318 319 if (MutexId > MAX_MTX) 320 { 321 return_ACPI_STATUS (AE_BAD_PARAMETER); 322 } 323 324 325 if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex) 326 { 327 Status = AcpiOsCreateSemaphore (1, 1, 328 &AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 329 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 330 AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0; 331 } 332 333 return_ACPI_STATUS (Status); 334} 335 336 337/******************************************************************************* 338 * 339 * FUNCTION: AcpiUtDeleteMutex 340 * 341 * PARAMETERS: MutexID - ID of the mutex to be deleted 342 * 343 * RETURN: Status 344 * 345 * DESCRIPTION: Delete a mutex object. 346 * 347 ******************************************************************************/ 348 349ACPI_STATUS 350AcpiUtDeleteMutex ( 351 ACPI_MUTEX_HANDLE MutexId) 352{ 353 ACPI_STATUS Status; 354 355 356 FUNCTION_TRACE_U32 ("UtDeleteMutex", MutexId); 357 358 359 if (MutexId > MAX_MTX) 360 { 361 return_ACPI_STATUS (AE_BAD_PARAMETER); 362 } 363 364 365 Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 366 367 AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL; 368 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 369 370 return_ACPI_STATUS (Status); 371} 372 373 374/******************************************************************************* 375 * 376 * FUNCTION: AcpiUtAcquireMutex 377 * 378 * PARAMETERS: MutexID - ID of the mutex to be acquired 379 * 380 * RETURN: Status 381 * 382 * DESCRIPTION: Acquire a mutex object. 383 * 384 ******************************************************************************/ 385 386ACPI_STATUS 387AcpiUtAcquireMutex ( 388 ACPI_MUTEX_HANDLE MutexId) 389{ 390 ACPI_STATUS Status; 391 UINT32 i; 392 UINT32 ThisThreadId; 393 394 395 PROC_NAME ("UtAcquireMutex"); 396 397 398 if (MutexId > MAX_MTX) 399 { 400 return (AE_BAD_PARAMETER); 401 } 402 403 404 ThisThreadId = AcpiOsGetThreadId (); 405 406 /* 407 * Deadlock prevention. Check if this thread owns any mutexes of value 408 * greater than or equal to this one. If so, the thread has violated 409 * the mutex ordering rule. This indicates a coding error somewhere in 410 * the ACPI subsystem code. 411 */ 412 for (i = MutexId; i < MAX_MTX; i++) 413 { 414 if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) 415 { 416 if (i == MutexId) 417 { 418 DEBUG_PRINTP (ACPI_ERROR, 419 ("Mutex [%s] already acquired by this thread [%X]\n", 420 AcpiUtGetMutexName (MutexId), ThisThreadId)); 421 422 return (AE_ALREADY_ACQUIRED); 423 } 424 425 DEBUG_PRINTP (ACPI_ERROR, 426 ("Invalid acquire order: Thread %X owns [%s], wants [%s]\n", 427 ThisThreadId, AcpiUtGetMutexName (i), 428 AcpiUtGetMutexName (MutexId))); 429 430 return (AE_ACQUIRE_DEADLOCK); 431 } 432 } 433 434 435 DEBUG_PRINTP (TRACE_MUTEX, 436 ("Thread %X attempting to acquire Mutex [%s]\n", 437 ThisThreadId, AcpiUtGetMutexName (MutexId))); 438 439 Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 440 1, WAIT_FOREVER); 441 442 if (ACPI_SUCCESS (Status)) 443 { 444 DEBUG_PRINTP (TRACE_MUTEX, ("Thread %X acquired Mutex [%s]\n", 445 ThisThreadId, AcpiUtGetMutexName (MutexId))); 446 447 AcpiGbl_AcpiMutexInfo[MutexId].UseCount++; 448 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId; 449 } 450 451 else 452 { 453 DEBUG_PRINTP (ACPI_ERROR, ("Thread %X could not acquire Mutex [%s] %s\n", 454 ThisThreadId, AcpiUtGetMutexName (MutexId), 455 AcpiFormatException (Status))); 456 } 457 458 return (Status); 459} 460 461 462/******************************************************************************* 463 * 464 * FUNCTION: AcpiUtReleaseMutex 465 * 466 * PARAMETERS: MutexID - ID of the mutex to be released 467 * 468 * RETURN: Status 469 * 470 * DESCRIPTION: Release a mutex object. 471 * 472 ******************************************************************************/ 473 474ACPI_STATUS 475AcpiUtReleaseMutex ( 476 ACPI_MUTEX_HANDLE MutexId) 477{ 478 ACPI_STATUS Status; 479 UINT32 i; 480 UINT32 ThisThreadId; 481 482 483 PROC_NAME ("UtReleaseMutex"); 484 485 486 ThisThreadId = AcpiOsGetThreadId (); 487 DEBUG_PRINTP (TRACE_MUTEX, 488 ("Thread %X releasing Mutex [%s]\n", ThisThreadId, 489 AcpiUtGetMutexName (MutexId))); 490 491 if (MutexId > MAX_MTX) 492 { 493 return (AE_BAD_PARAMETER); 494 } 495 496 497 /* 498 * Mutex must be acquired in order to release it! 499 */ 500 if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED) 501 { 502 DEBUG_PRINTP (ACPI_ERROR, 503 ("Mutex [%s] is not acquired, cannot release\n", 504 AcpiUtGetMutexName (MutexId))); 505 506 return (AE_NOT_ACQUIRED); 507 } 508 509 510 /* 511 * Deadlock prevention. Check if this thread owns any mutexes of value 512 * greater than this one. If so, the thread has violated the mutex 513 * ordering rule. This indicates a coding error somewhere in 514 * the ACPI subsystem code. 515 */ 516 for (i = MutexId; i < MAX_MTX; i++) 517 { 518 if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) 519 { 520 if (i == MutexId) 521 { 522 continue; 523 } 524 525 DEBUG_PRINTP (ACPI_ERROR, 526 ("Invalid release order: owns [%s], releasing [%s]\n", 527 AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); 528 529 return (AE_RELEASE_DEADLOCK); 530 } 531 } 532 533 534 /* Mark unlocked FIRST */ 535 536 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 537 538 Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1); 539 540 if (ACPI_FAILURE (Status)) 541 { 542 DEBUG_PRINTP (ACPI_ERROR, ("Thread %X could not release Mutex [%s] %s\n", 543 ThisThreadId, AcpiUtGetMutexName (MutexId), 544 AcpiFormatException (Status))); 545 } 546 else 547 { 548 DEBUG_PRINTP (TRACE_MUTEX, ("Thread %X released Mutex [%s]\n", 549 ThisThreadId, AcpiUtGetMutexName (MutexId))); 550 } 551 552 return (Status); 553} 554 555 556/******************************************************************************* 557 * 558 * FUNCTION: AcpiUtCreateUpdateStateAndPush 559 * 560 * PARAMETERS: *Object - Object to be added to the new state 561 * Action - Increment/Decrement 562 * StateList - List the state will be added to 563 * 564 * RETURN: None 565 * 566 * DESCRIPTION: Create a new state and push it 567 * 568 ******************************************************************************/ 569 570ACPI_STATUS 571AcpiUtCreateUpdateStateAndPush ( 572 ACPI_OPERAND_OBJECT *Object, 573 UINT16 Action, 574 ACPI_GENERIC_STATE **StateList) 575{ 576 ACPI_GENERIC_STATE *State; 577 578 579 /* Ignore null objects; these are expected */ 580 581 if (!Object) 582 { 583 return (AE_OK); 584 } 585 586 State = AcpiUtCreateUpdateState (Object, Action); 587 if (!State) 588 { 589 return (AE_NO_MEMORY); 590 } 591 592 593 AcpiUtPushGenericState (StateList, State); 594 return (AE_OK); 595} 596 597 598/******************************************************************************* 599 * 600 * FUNCTION: AcpiUtCreatePkgStateAndPush 601 * 602 * PARAMETERS: *Object - Object to be added to the new state 603 * Action - Increment/Decrement 604 * StateList - List the state will be added to 605 * 606 * RETURN: None 607 * 608 * DESCRIPTION: Create a new state and push it 609 * 610 ******************************************************************************/ 611 612ACPI_STATUS 613AcpiUtCreatePkgStateAndPush ( 614 void *InternalObject, 615 void *ExternalObject, 616 UINT16 Index, 617 ACPI_GENERIC_STATE **StateList) 618{ 619 ACPI_GENERIC_STATE *State; 620 621 622 State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index); 623 if (!State) 624 { 625 return (AE_NO_MEMORY); 626 } 627 628 629 AcpiUtPushGenericState (StateList, State); 630 return (AE_OK); 631} 632 633 634/******************************************************************************* 635 * 636 * FUNCTION: AcpiUtPushGenericState 637 * 638 * PARAMETERS: ListHead - Head of the state stack 639 * State - State object to push 640 * 641 * RETURN: Status 642 * 643 * DESCRIPTION: Push a state object onto a state stack 644 * 645 ******************************************************************************/ 646 647void 648AcpiUtPushGenericState ( 649 ACPI_GENERIC_STATE **ListHead, 650 ACPI_GENERIC_STATE *State) 651{ 652 FUNCTION_TRACE ("UtPushGenericState"); 653 654 /* Push the state object onto the front of the list (stack) */ 655 656 State->Common.Next = *ListHead; 657 *ListHead = State; 658 659 return_VOID; 660} 661 662 663/******************************************************************************* 664 * 665 * FUNCTION: AcpiUtPopGenericState 666 * 667 * PARAMETERS: ListHead - Head of the state stack 668 * 669 * RETURN: Status 670 * 671 * DESCRIPTION: Pop a state object from a state stack 672 * 673 ******************************************************************************/ 674 675ACPI_GENERIC_STATE * 676AcpiUtPopGenericState ( 677 ACPI_GENERIC_STATE **ListHead) 678{ 679 ACPI_GENERIC_STATE *State; 680 681 682 FUNCTION_TRACE ("DsPopGenericState"); 683 684 685 /* Remove the state object at the head of the list (stack) */ 686 687 State = *ListHead; 688 if (State) 689 { 690 /* Update the list head */ 691 692 *ListHead = State->Common.Next; 693 } 694 695 return_PTR (State); 696} 697 698 699/******************************************************************************* 700 * 701 * FUNCTION: AcpiUtCreateGenericState 702 * 703 * PARAMETERS: None 704 * 705 * RETURN: Status 706 * 707 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 708 * the global state cache; If none available, create a new one. 709 * 710 ******************************************************************************/ 711 712ACPI_GENERIC_STATE * 713AcpiUtCreateGenericState (void) 714{ 715 ACPI_GENERIC_STATE *State; 716 717 718 AcpiUtAcquireMutex (ACPI_MTX_CACHES); 719 720 AcpiGbl_StateCacheRequests++; 721 722 /* Check the cache first */ 723 724 if (AcpiGbl_GenericStateCache) 725 { 726 /* There is an object available, use it */ 727 728 State = AcpiGbl_GenericStateCache; 729 AcpiGbl_GenericStateCache = State->Common.Next; 730 State->Common.Next = NULL; 731 732 AcpiGbl_StateCacheHits++; 733 AcpiGbl_GenericStateCacheDepth--; 734 735 AcpiUtReleaseMutex (ACPI_MTX_CACHES); 736 737 DEBUG_PRINT (TRACE_EXEC, ("CreateGenState: State %p from cache\n", State)); 738 } 739 740 else 741 { 742 /* The cache is empty, create a new object */ 743 744 AcpiUtReleaseMutex (ACPI_MTX_CACHES); 745 746 State = ACPI_MEM_CALLOCATE (sizeof (ACPI_GENERIC_STATE)); 747 } 748 749 /* Initialize */ 750 751 if (State) 752 { 753 /* Always zero out the object before init */ 754 755 MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE)); 756 757 State->Common.DataType = ACPI_DESC_TYPE_STATE; 758 } 759 760 return (State); 761} 762 763 764/******************************************************************************* 765 * 766 * FUNCTION: AcpiUtCreateUpdateState 767 * 768 * PARAMETERS: Object - Initial Object to be installed in the 769 * state 770 * Action - Update action to be performed 771 * 772 * RETURN: Status 773 * 774 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 775 * to update reference counts and delete complex objects such 776 * as packages. 777 * 778 ******************************************************************************/ 779 780ACPI_GENERIC_STATE * 781AcpiUtCreateUpdateState ( 782 ACPI_OPERAND_OBJECT *Object, 783 UINT16 Action) 784{ 785 ACPI_GENERIC_STATE *State; 786 787 788 FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object); 789 790 791 /* Create the generic state object */ 792 793 State = AcpiUtCreateGenericState (); 794 if (!State) 795 { 796 return (NULL); 797 } 798 799 /* Init fields specific to the update struct */ 800 801 State->Update.Object = Object; 802 State->Update.Value = Action; 803 804 return_PTR (State); 805} 806 807 808/******************************************************************************* 809 * 810 * FUNCTION: AcpiUtCreatePkgState 811 * 812 * PARAMETERS: Object - Initial Object to be installed in the 813 * state 814 * Action - Update action to be performed 815 * 816 * RETURN: Status 817 * 818 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 819 * to update reference counts and delete complex objects such 820 * as packages. 821 * 822 ******************************************************************************/ 823 824ACPI_GENERIC_STATE * 825AcpiUtCreatePkgState ( 826 void *InternalObject, 827 void *ExternalObject, 828 UINT16 Index) 829{ 830 ACPI_GENERIC_STATE *State; 831 832 833 FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject); 834 835 836 /* Create the generic state object */ 837 838 State = AcpiUtCreateGenericState (); 839 if (!State) 840 { 841 return (NULL); 842 } 843 844 /* Init fields specific to the update struct */ 845 846 State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject; 847 State->Pkg.DestObject = ExternalObject; 848 State->Pkg.Index = Index; 849 State->Pkg.NumPackages = 1; 850 851 return_PTR (State); 852} 853 854 855/******************************************************************************* 856 * 857 * FUNCTION: AcpiUtCreateControlState 858 * 859 * PARAMETERS: None 860 * 861 * RETURN: Status 862 * 863 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 864 * to support nested IF/WHILE constructs in the AML. 865 * 866 ******************************************************************************/ 867 868ACPI_GENERIC_STATE * 869AcpiUtCreateControlState ( 870 void) 871{ 872 ACPI_GENERIC_STATE *State; 873 874 875 FUNCTION_TRACE ("UtCreateControlState"); 876 877 /* Create the generic state object */ 878 879 State = AcpiUtCreateGenericState (); 880 if (!State) 881 { 882 return (NULL); 883 } 884 885 886 /* Init fields specific to the control struct */ 887 888 State->Common.State = CONTROL_CONDITIONAL_EXECUTING; 889 890 return_PTR (State); 891} 892 893 894/******************************************************************************* 895 * 896 * FUNCTION: AcpiUtDeleteGenericState 897 * 898 * PARAMETERS: State - The state object to be deleted 899 * 900 * RETURN: Status 901 * 902 * DESCRIPTION: Put a state object back into the global state cache. The object 903 * is not actually freed at this time. 904 * 905 ******************************************************************************/ 906 907void 908AcpiUtDeleteGenericState ( 909 ACPI_GENERIC_STATE *State) 910{ 911 FUNCTION_TRACE ("UtDeleteGenericState"); 912 913 914 /* If cache is full, just free this state object */ 915 916 if (AcpiGbl_GenericStateCacheDepth >= MAX_STATE_CACHE_DEPTH) 917 { 918 ACPI_MEM_FREE (State); 919 } 920 921 /* Otherwise put this object back into the cache */ 922 923 else 924 { 925 AcpiUtAcquireMutex (ACPI_MTX_CACHES); 926 927 /* Clear the state */ 928 929 MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE)); 930 State->Common.DataType = ACPI_DESC_TYPE_STATE; 931 932 /* Put the object at the head of the global cache list */ 933 934 State->Common.Next = AcpiGbl_GenericStateCache; 935 AcpiGbl_GenericStateCache = State; 936 AcpiGbl_GenericStateCacheDepth++; 937 938 939 AcpiUtReleaseMutex (ACPI_MTX_CACHES); 940 } 941 return_VOID; 942} 943 944 945/******************************************************************************* 946 * 947 * FUNCTION: AcpiUtDeleteGenericStateCache 948 * 949 * PARAMETERS: None 950 * 951 * RETURN: Status 952 * 953 * DESCRIPTION: Purge the global state object cache. Used during subsystem 954 * termination. 955 * 956 ******************************************************************************/ 957 958void 959AcpiUtDeleteGenericStateCache ( 960 void) 961{ 962 ACPI_GENERIC_STATE *Next; 963 964 965 FUNCTION_TRACE ("UtDeleteGenericStateCache"); 966 967 968 /* Traverse the global cache list */ 969 970 while (AcpiGbl_GenericStateCache) 971 { 972 /* Delete one cached state object */ 973 974 Next = AcpiGbl_GenericStateCache->Common.Next; 975 ACPI_MEM_FREE (AcpiGbl_GenericStateCache); 976 977 AcpiGbl_GenericStateCache = Next; 978 AcpiGbl_GenericStateCacheDepth--; 979 } 980 981 return_VOID; 982} 983 984 985/******************************************************************************* 986 * 987 * FUNCTION: AcpiUtResolvePackageReferences 988 * 989 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 990 * 991 * RETURN: Status 992 * 993 * DESCRIPTION: Walk through a package and turn internal references into values 994 * 995 ******************************************************************************/ 996 997ACPI_STATUS 998AcpiUtResolvePackageReferences ( 999 ACPI_OPERAND_OBJECT *ObjDesc) 1000{ 1001 UINT32 Count; 1002 ACPI_OPERAND_OBJECT *SubObject; 1003 1004 1005 FUNCTION_TRACE ("AcpiUtResolvePackageReferences"); 1006 1007 1008 if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE) 1009 { 1010 /* The object must be a package */ 1011 1012 REPORT_ERROR (("Must resolve Package Refs on a Package\n")); 1013 return_ACPI_STATUS(AE_ERROR); 1014 } 1015 1016 /* 1017 * TBD: what about nested packages? */ 1018 1019 for (Count = 0; Count < ObjDesc->Package.Count; Count++) 1020 { 1021 SubObject = ObjDesc->Package.Elements[Count]; 1022 1023 if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE) 1024 { 1025 if (SubObject->Reference.Opcode == AML_ZERO_OP) 1026 { 1027 SubObject->Common.Type = ACPI_TYPE_INTEGER; 1028 SubObject->Integer.Value = 0; 1029 } 1030 1031 else if (SubObject->Reference.Opcode == AML_ONE_OP) 1032 { 1033 SubObject->Common.Type = ACPI_TYPE_INTEGER; 1034 SubObject->Integer.Value = 1; 1035 } 1036 1037 else if (SubObject->Reference.Opcode == AML_ONES_OP) 1038 { 1039 SubObject->Common.Type = ACPI_TYPE_INTEGER; 1040 SubObject->Integer.Value = ACPI_INTEGER_MAX; 1041 } 1042 } 1043 } 1044 1045 return_ACPI_STATUS(AE_OK); 1046} 1047 1048#ifdef ACPI_DEBUG 1049 1050/******************************************************************************* 1051 * 1052 * FUNCTION: AcpiUtDisplayInitPathname 1053 * 1054 * PARAMETERS: ObjHandle - Handle whose pathname will be displayed 1055 * Path - Additional path string to be appended 1056 * 1057 * RETURN: ACPI_STATUS 1058 * 1059 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY 1060 * 1061 ******************************************************************************/ 1062 1063void 1064AcpiUtDisplayInitPathname ( 1065 ACPI_HANDLE ObjHandle, 1066 char *Path) 1067{ 1068 ACPI_STATUS Status; 1069 UINT32 Length = 128; 1070 char Buffer[128]; 1071 1072 1073 Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer); 1074 if (ACPI_SUCCESS (Status)) 1075 { 1076 if (Path) 1077 { 1078 DEBUG_PRINT (TRACE_INIT, ("%s.%s\n", Buffer, Path)) 1079 } 1080 else 1081 { 1082 DEBUG_PRINT (TRACE_INIT, ("%s\n", Buffer)) 1083 } 1084 } 1085} 1086#endif 1087 1088/******************************************************************************* 1089 * 1090 * FUNCTION: AcpiUtWalkPackageTree 1091 * 1092 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 1093 * 1094 * RETURN: Status 1095 * 1096 * DESCRIPTION: Walk through a package 1097 * 1098 ******************************************************************************/ 1099 1100ACPI_STATUS 1101AcpiUtWalkPackageTree ( 1102 ACPI_OPERAND_OBJECT *SourceObject, 1103 void *TargetObject, 1104 ACPI_PKG_CALLBACK WalkCallback, 1105 void *Context) 1106{ 1107 ACPI_STATUS Status = AE_OK; 1108 ACPI_GENERIC_STATE *StateList = NULL; 1109 ACPI_GENERIC_STATE *State; 1110 UINT32 ThisIndex; 1111 ACPI_OPERAND_OBJECT *ThisSourceObj; 1112 1113 1114 FUNCTION_TRACE ("AcpiUtWalkPackageTree"); 1115 1116 1117 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 1118 if (!State) 1119 { 1120 return_ACPI_STATUS (AE_NO_MEMORY); 1121 } 1122 1123 while (State) 1124 { 1125 ThisIndex = State->Pkg.Index; 1126 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 1127 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 1128 1129 /* 1130 * Check for 1131 * 1) An uninitialized package element. It is completely 1132 * legal to declare a package and leave it uninitialized 1133 * 2) Not an internal object - can be a namespace node instead 1134 * 3) Any type other than a package. Packages are handled in else 1135 * case below. 1136 */ 1137 if ((!ThisSourceObj) || 1138 (!VALID_DESCRIPTOR_TYPE ( 1139 ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) || 1140 (!IS_THIS_OBJECT_TYPE ( 1141 ThisSourceObj, ACPI_TYPE_PACKAGE))) 1142 { 1143 1144 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 1145 State, Context); 1146 if (ACPI_FAILURE (Status)) 1147 { 1148 /* TBD: must delete package created up to this point */ 1149 1150 return_ACPI_STATUS (Status); 1151 } 1152 1153 State->Pkg.Index++; 1154 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 1155 { 1156 /* 1157 * We've handled all of the objects at this level, This means 1158 * that we have just completed a package. That package may 1159 * have contained one or more packages itself. 1160 * 1161 * Delete this state and pop the previous state (package). 1162 */ 1163 AcpiUtDeleteGenericState (State); 1164 State = AcpiUtPopGenericState (&StateList); 1165 1166 1167 /* Finished when there are no more states */ 1168 1169 if (!State) 1170 { 1171 /* 1172 * We have handled all of the objects in the top level 1173 * package just add the length of the package objects 1174 * and exit 1175 */ 1176 return_ACPI_STATUS (AE_OK); 1177 } 1178 1179 /* 1180 * Go back up a level and move the index past the just 1181 * completed package object. 1182 */ 1183 State->Pkg.Index++; 1184 } 1185 } 1186 1187 else 1188 { 1189 /* This is a sub-object of type package */ 1190 1191 Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 1192 State, Context); 1193 if (ACPI_FAILURE (Status)) 1194 { 1195 /* TBD: must delete package created up to this point */ 1196 1197 return_ACPI_STATUS (Status); 1198 } 1199 1200 1201 /* 1202 * The callback above returned a new target package object. 1203 */ 1204 1205 /* 1206 * Push the current state and create a new one 1207 */ 1208 AcpiUtPushGenericState (&StateList, State); 1209 State = AcpiUtCreatePkgState (ThisSourceObj, 1210 State->Pkg.ThisTargetObj, 0); 1211 if (!State) 1212 { 1213 /* TBD: must delete package created up to this point */ 1214 1215 return_ACPI_STATUS (AE_NO_MEMORY); 1216 } 1217 } 1218 } 1219 1220 /* We should never get here */ 1221 1222 return (AE_AML_INTERNAL); 1223 1224} 1225 1226 1227/******************************************************************************* 1228 * 1229 * FUNCTION: _ReportError 1230 * 1231 * PARAMETERS: ModuleName - Caller's module name (for error output) 1232 * LineNumber - Caller's line number (for error output) 1233 * ComponentId - Caller's component ID (for error output) 1234 * Message - Error message to use on failure 1235 * 1236 * RETURN: None 1237 * 1238 * DESCRIPTION: Print error message 1239 * 1240 ******************************************************************************/ 1241 1242void 1243_ReportError ( 1244 NATIVE_CHAR *ModuleName, 1245 UINT32 LineNumber, 1246 UINT32 ComponentId) 1247{ 1248 1249 1250 AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber); 1251} 1252 1253 1254/******************************************************************************* 1255 * 1256 * FUNCTION: _ReportWarning 1257 * 1258 * PARAMETERS: ModuleName - Caller's module name (for error output) 1259 * LineNumber - Caller's line number (for error output) 1260 * ComponentId - Caller's component ID (for error output) 1261 * Message - Error message to use on failure 1262 * 1263 * RETURN: None 1264 * 1265 * DESCRIPTION: Print warning message 1266 * 1267 ******************************************************************************/ 1268 1269void 1270_ReportWarning ( 1271 NATIVE_CHAR *ModuleName, 1272 UINT32 LineNumber, 1273 UINT32 ComponentId) 1274{ 1275 1276 AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber); 1277} 1278 1279 1280/******************************************************************************* 1281 * 1282 * FUNCTION: _ReportInfo 1283 * 1284 * PARAMETERS: ModuleName - Caller's module name (for error output) 1285 * LineNumber - Caller's line number (for error output) 1286 * ComponentId - Caller's component ID (for error output) 1287 * Message - Error message to use on failure 1288 * 1289 * RETURN: None 1290 * 1291 * DESCRIPTION: Print information message 1292 * 1293 ******************************************************************************/ 1294 1295void 1296_ReportInfo ( 1297 NATIVE_CHAR *ModuleName, 1298 UINT32 LineNumber, 1299 UINT32 ComponentId) 1300{ 1301 1302 AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber); 1303} 1304 1305 1306