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