utmisc.c revision 82367
1/******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * $Revision: 46 $ 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 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 419 "Mutex [%s] already acquired by this thread [%X]\n", 420 AcpiUtGetMutexName (MutexId), ThisThreadId)); 421 422 return (AE_ALREADY_ACQUIRED); 423 } 424 425 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_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 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", 543 ThisThreadId, AcpiUtGetMutexName (MutexId), 544 AcpiFormatException (Status))); 545 } 546 else 547 { 548 ACPI_DEBUG_PRINT ((ACPI_DB_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 State = AcpiUtAcquireFromCache (ACPI_MEM_LIST_STATE); 719 720 /* Initialize */ 721 722 if (State) 723 { 724 State->Common.DataType = ACPI_DESC_TYPE_STATE; 725 } 726 727 return (State); 728} 729 730 731/******************************************************************************* 732 * 733 * FUNCTION: AcpiUtCreateUpdateState 734 * 735 * PARAMETERS: Object - Initial Object to be installed in the 736 * state 737 * Action - Update action to be performed 738 * 739 * RETURN: Status 740 * 741 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 742 * to update reference counts and delete complex objects such 743 * as packages. 744 * 745 ******************************************************************************/ 746 747ACPI_GENERIC_STATE * 748AcpiUtCreateUpdateState ( 749 ACPI_OPERAND_OBJECT *Object, 750 UINT16 Action) 751{ 752 ACPI_GENERIC_STATE *State; 753 754 755 FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object); 756 757 758 /* Create the generic state object */ 759 760 State = AcpiUtCreateGenericState (); 761 if (!State) 762 { 763 return (NULL); 764 } 765 766 /* Init fields specific to the update struct */ 767 768 State->Update.Object = Object; 769 State->Update.Value = Action; 770 771 return_PTR (State); 772} 773 774 775/******************************************************************************* 776 * 777 * FUNCTION: AcpiUtCreatePkgState 778 * 779 * PARAMETERS: Object - Initial Object to be installed in the 780 * state 781 * Action - Update action to be performed 782 * 783 * RETURN: Status 784 * 785 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 786 * to update reference counts and delete complex objects such 787 * as packages. 788 * 789 ******************************************************************************/ 790 791ACPI_GENERIC_STATE * 792AcpiUtCreatePkgState ( 793 void *InternalObject, 794 void *ExternalObject, 795 UINT16 Index) 796{ 797 ACPI_GENERIC_STATE *State; 798 799 800 FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject); 801 802 803 /* Create the generic state object */ 804 805 State = AcpiUtCreateGenericState (); 806 if (!State) 807 { 808 return (NULL); 809 } 810 811 /* Init fields specific to the update struct */ 812 813 State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject; 814 State->Pkg.DestObject = ExternalObject; 815 State->Pkg.Index = Index; 816 State->Pkg.NumPackages = 1; 817 818 return_PTR (State); 819} 820 821 822/******************************************************************************* 823 * 824 * FUNCTION: AcpiUtCreateControlState 825 * 826 * PARAMETERS: None 827 * 828 * RETURN: Status 829 * 830 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 831 * to support nested IF/WHILE constructs in the AML. 832 * 833 ******************************************************************************/ 834 835ACPI_GENERIC_STATE * 836AcpiUtCreateControlState ( 837 void) 838{ 839 ACPI_GENERIC_STATE *State; 840 841 842 FUNCTION_TRACE ("UtCreateControlState"); 843 844 /* Create the generic state object */ 845 846 State = AcpiUtCreateGenericState (); 847 if (!State) 848 { 849 return (NULL); 850 } 851 852 853 /* Init fields specific to the control struct */ 854 855 State->Common.State = CONTROL_CONDITIONAL_EXECUTING; 856 857 return_PTR (State); 858} 859 860 861/******************************************************************************* 862 * 863 * FUNCTION: AcpiUtDeleteGenericState 864 * 865 * PARAMETERS: State - The state object to be deleted 866 * 867 * RETURN: Status 868 * 869 * DESCRIPTION: Put a state object back into the global state cache. The object 870 * is not actually freed at this time. 871 * 872 ******************************************************************************/ 873 874void 875AcpiUtDeleteGenericState ( 876 ACPI_GENERIC_STATE *State) 877{ 878 FUNCTION_TRACE ("UtDeleteGenericState"); 879 880 881 AcpiUtReleaseToCache (ACPI_MEM_LIST_STATE, State); 882 return_VOID; 883} 884 885 886/******************************************************************************* 887 * 888 * FUNCTION: AcpiUtDeleteGenericStateCache 889 * 890 * PARAMETERS: None 891 * 892 * RETURN: Status 893 * 894 * DESCRIPTION: Purge the global state object cache. Used during subsystem 895 * termination. 896 * 897 ******************************************************************************/ 898 899void 900AcpiUtDeleteGenericStateCache ( 901 void) 902{ 903 FUNCTION_TRACE ("UtDeleteGenericStateCache"); 904 905 906 AcpiUtDeleteGenericCache (ACPI_MEM_LIST_STATE); 907 return_VOID; 908} 909 910 911/******************************************************************************* 912 * 913 * FUNCTION: AcpiUtResolvePackageReferences 914 * 915 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 916 * 917 * RETURN: Status 918 * 919 * DESCRIPTION: Walk through a package and turn internal references into values 920 * 921 ******************************************************************************/ 922 923ACPI_STATUS 924AcpiUtResolvePackageReferences ( 925 ACPI_OPERAND_OBJECT *ObjDesc) 926{ 927 UINT32 Count; 928 ACPI_OPERAND_OBJECT *SubObject; 929 930 931 FUNCTION_TRACE ("AcpiUtResolvePackageReferences"); 932 933 934 if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE) 935 { 936 /* The object must be a package */ 937 938 REPORT_ERROR (("Must resolve Package Refs on a Package\n")); 939 return_ACPI_STATUS(AE_ERROR); 940 } 941 942 /* 943 * TBD: what about nested packages? */ 944 945 for (Count = 0; Count < ObjDesc->Package.Count; Count++) 946 { 947 SubObject = ObjDesc->Package.Elements[Count]; 948 949 if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE) 950 { 951 if (SubObject->Reference.Opcode == AML_ZERO_OP) 952 { 953 SubObject->Common.Type = ACPI_TYPE_INTEGER; 954 SubObject->Integer.Value = 0; 955 } 956 957 else if (SubObject->Reference.Opcode == AML_ONE_OP) 958 { 959 SubObject->Common.Type = ACPI_TYPE_INTEGER; 960 SubObject->Integer.Value = 1; 961 } 962 963 else if (SubObject->Reference.Opcode == AML_ONES_OP) 964 { 965 SubObject->Common.Type = ACPI_TYPE_INTEGER; 966 SubObject->Integer.Value = ACPI_INTEGER_MAX; 967 } 968 } 969 } 970 971 return_ACPI_STATUS(AE_OK); 972} 973 974#ifdef ACPI_DEBUG 975 976/******************************************************************************* 977 * 978 * FUNCTION: AcpiUtDisplayInitPathname 979 * 980 * PARAMETERS: ObjHandle - Handle whose pathname will be displayed 981 * Path - Additional path string to be appended 982 * 983 * RETURN: ACPI_STATUS 984 * 985 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY 986 * 987 ******************************************************************************/ 988 989void 990AcpiUtDisplayInitPathname ( 991 ACPI_HANDLE ObjHandle, 992 char *Path) 993{ 994 ACPI_STATUS Status; 995 UINT32 Length = 128; 996 char Buffer[128]; 997 998 999 PROC_NAME ("AcpiUtDisplayInitPathname"); 1000 1001 1002 Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer); 1003 if (ACPI_SUCCESS (Status)) 1004 { 1005 if (Path) 1006 { 1007 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", Buffer, Path)); 1008 } 1009 else 1010 { 1011 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", Buffer)); 1012 } 1013 } 1014} 1015#endif 1016 1017/******************************************************************************* 1018 * 1019 * FUNCTION: AcpiUtWalkPackageTree 1020 * 1021 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 1022 * 1023 * RETURN: Status 1024 * 1025 * DESCRIPTION: Walk through a package 1026 * 1027 ******************************************************************************/ 1028 1029ACPI_STATUS 1030AcpiUtWalkPackageTree ( 1031 ACPI_OPERAND_OBJECT *SourceObject, 1032 void *TargetObject, 1033 ACPI_PKG_CALLBACK WalkCallback, 1034 void *Context) 1035{ 1036 ACPI_STATUS Status = AE_OK; 1037 ACPI_GENERIC_STATE *StateList = NULL; 1038 ACPI_GENERIC_STATE *State; 1039 UINT32 ThisIndex; 1040 ACPI_OPERAND_OBJECT *ThisSourceObj; 1041 1042 1043 FUNCTION_TRACE ("AcpiUtWalkPackageTree"); 1044 1045 1046 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 1047 if (!State) 1048 { 1049 return_ACPI_STATUS (AE_NO_MEMORY); 1050 } 1051 1052 while (State) 1053 { 1054 ThisIndex = State->Pkg.Index; 1055 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 1056 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 1057 1058 /* 1059 * Check for 1060 * 1) An uninitialized package element. It is completely 1061 * legal to declare a package and leave it uninitialized 1062 * 2) Not an internal object - can be a namespace node instead 1063 * 3) Any type other than a package. Packages are handled in else 1064 * case below. 1065 */ 1066 if ((!ThisSourceObj) || 1067 (!VALID_DESCRIPTOR_TYPE ( 1068 ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) || 1069 (!IS_THIS_OBJECT_TYPE ( 1070 ThisSourceObj, ACPI_TYPE_PACKAGE))) 1071 { 1072 1073 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 1074 State, Context); 1075 if (ACPI_FAILURE (Status)) 1076 { 1077 /* TBD: must delete package created up to this point */ 1078 1079 return_ACPI_STATUS (Status); 1080 } 1081 1082 State->Pkg.Index++; 1083 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 1084 { 1085 /* 1086 * We've handled all of the objects at this level, This means 1087 * that we have just completed a package. That package may 1088 * have contained one or more packages itself. 1089 * 1090 * Delete this state and pop the previous state (package). 1091 */ 1092 AcpiUtDeleteGenericState (State); 1093 State = AcpiUtPopGenericState (&StateList); 1094 1095 1096 /* Finished when there are no more states */ 1097 1098 if (!State) 1099 { 1100 /* 1101 * We have handled all of the objects in the top level 1102 * package just add the length of the package objects 1103 * and exit 1104 */ 1105 return_ACPI_STATUS (AE_OK); 1106 } 1107 1108 /* 1109 * Go back up a level and move the index past the just 1110 * completed package object. 1111 */ 1112 State->Pkg.Index++; 1113 } 1114 } 1115 1116 else 1117 { 1118 /* This is a sub-object of type package */ 1119 1120 Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 1121 State, Context); 1122 if (ACPI_FAILURE (Status)) 1123 { 1124 /* TBD: must delete package created up to this point */ 1125 1126 return_ACPI_STATUS (Status); 1127 } 1128 1129 1130 /* 1131 * The callback above returned a new target package object. 1132 */ 1133 1134 /* 1135 * Push the current state and create a new one 1136 */ 1137 AcpiUtPushGenericState (&StateList, State); 1138 State = AcpiUtCreatePkgState (ThisSourceObj, 1139 State->Pkg.ThisTargetObj, 0); 1140 if (!State) 1141 { 1142 /* TBD: must delete package created up to this point */ 1143 1144 return_ACPI_STATUS (AE_NO_MEMORY); 1145 } 1146 } 1147 } 1148 1149 /* We should never get here */ 1150 1151 return (AE_AML_INTERNAL); 1152 1153} 1154 1155 1156/******************************************************************************* 1157 * 1158 * FUNCTION: _ReportError 1159 * 1160 * PARAMETERS: ModuleName - Caller's module name (for error output) 1161 * LineNumber - Caller's line number (for error output) 1162 * ComponentId - Caller's component ID (for error output) 1163 * Message - Error message to use on failure 1164 * 1165 * RETURN: None 1166 * 1167 * DESCRIPTION: Print error message 1168 * 1169 ******************************************************************************/ 1170 1171void 1172_ReportError ( 1173 NATIVE_CHAR *ModuleName, 1174 UINT32 LineNumber, 1175 UINT32 ComponentId) 1176{ 1177 1178 1179 AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber); 1180} 1181 1182 1183/******************************************************************************* 1184 * 1185 * FUNCTION: _ReportWarning 1186 * 1187 * PARAMETERS: ModuleName - Caller's module name (for error output) 1188 * LineNumber - Caller's line number (for error output) 1189 * ComponentId - Caller's component ID (for error output) 1190 * Message - Error message to use on failure 1191 * 1192 * RETURN: None 1193 * 1194 * DESCRIPTION: Print warning message 1195 * 1196 ******************************************************************************/ 1197 1198void 1199_ReportWarning ( 1200 NATIVE_CHAR *ModuleName, 1201 UINT32 LineNumber, 1202 UINT32 ComponentId) 1203{ 1204 1205 AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber); 1206} 1207 1208 1209/******************************************************************************* 1210 * 1211 * FUNCTION: _ReportInfo 1212 * 1213 * PARAMETERS: ModuleName - Caller's module name (for error output) 1214 * LineNumber - Caller's line number (for error output) 1215 * ComponentId - Caller's component ID (for error output) 1216 * Message - Error message to use on failure 1217 * 1218 * RETURN: None 1219 * 1220 * DESCRIPTION: Print information message 1221 * 1222 ******************************************************************************/ 1223 1224void 1225_ReportInfo ( 1226 NATIVE_CHAR *ModuleName, 1227 UINT32 LineNumber, 1228 UINT32 ComponentId) 1229{ 1230 1231 AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber); 1232} 1233 1234 1235