utmisc.c revision 107325
1/******************************************************************************* 2 * 3 * Module Name: utmisc - common utility procedures 4 * $Revision: 86 $ 5 * 6 ******************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2002, 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 "acnamesp.h" 122 123 124#define _COMPONENT ACPI_UTILITIES 125 ACPI_MODULE_NAME ("utmisc") 126 127 128/******************************************************************************* 129 * 130 * FUNCTION: AcpiUtPrintString 131 * 132 * PARAMETERS: String - Null terminated ASCII string 133 * 134 * RETURN: None 135 * 136 * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 137 * sequences. 138 * 139 ******************************************************************************/ 140 141void 142AcpiUtPrintString ( 143 char *String, 144 UINT8 MaxLength) 145{ 146 UINT32 i; 147 148 149 if (!String) 150 { 151 AcpiOsPrintf ("<\"NULL STRING PTR\">"); 152 return; 153 } 154 155 AcpiOsPrintf ("\""); 156 for (i = 0; String[i] && (i < MaxLength); i++) 157 { 158 /* Escape sequences */ 159 160 switch (String[i]) 161 { 162 case 0x07: 163 AcpiOsPrintf ("\\a"); /* BELL */ 164 break; 165 166 case 0x08: 167 AcpiOsPrintf ("\\b"); /* BACKSPACE */ 168 break; 169 170 case 0x0C: 171 AcpiOsPrintf ("\\f"); /* FORMFEED */ 172 break; 173 174 case 0x0A: 175 AcpiOsPrintf ("\\n"); /* LINEFEED */ 176 break; 177 178 case 0x0D: 179 AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 180 break; 181 182 case 0x09: 183 AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 184 break; 185 186 case 0x0B: 187 AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 188 break; 189 190 case '\'': /* Single Quote */ 191 case '\"': /* Double Quote */ 192 case '\\': /* Backslash */ 193 AcpiOsPrintf ("\\%c", (int) String[i]); 194 break; 195 196 default: 197 198 /* Check for printable character or hex escape */ 199 200 if (ACPI_IS_PRINT (String[i])) 201 { 202 /* This is a normal character */ 203 204 AcpiOsPrintf ("%c", (int) String[i]); 205 } 206 else 207 { 208 /* All others will be Hex escapes */ 209 210 AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 211 } 212 break; 213 } 214 } 215 AcpiOsPrintf ("\""); 216 217 if (i == MaxLength && String[i]) 218 { 219 AcpiOsPrintf ("..."); 220 } 221} 222 223 224/******************************************************************************* 225 * 226 * FUNCTION: AcpiUtDwordByteSwap 227 * 228 * PARAMETERS: Value - Value to be converted 229 * 230 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 231 * 232 ******************************************************************************/ 233 234UINT32 235AcpiUtDwordByteSwap ( 236 UINT32 Value) 237{ 238 union 239 { 240 UINT32 Value; 241 UINT8 Bytes[4]; 242 } Out; 243 244 union 245 { 246 UINT32 Value; 247 UINT8 Bytes[4]; 248 } In; 249 250 251 ACPI_FUNCTION_ENTRY (); 252 253 254 In.Value = Value; 255 256 Out.Bytes[0] = In.Bytes[3]; 257 Out.Bytes[1] = In.Bytes[2]; 258 Out.Bytes[2] = In.Bytes[1]; 259 Out.Bytes[3] = In.Bytes[0]; 260 261 return (Out.Value); 262} 263 264 265/******************************************************************************* 266 * 267 * FUNCTION: AcpiUtSetIntegerWidth 268 * 269 * PARAMETERS: Revision From DSDT header 270 * 271 * RETURN: None 272 * 273 * DESCRIPTION: Set the global integer bit width based upon the revision 274 * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 275 * For Revision 2 and above, Integers are 64 bits. Yes, this 276 * makes a difference. 277 * 278 ******************************************************************************/ 279 280void 281AcpiUtSetIntegerWidth ( 282 UINT8 Revision) 283{ 284 285 if (Revision <= 1) 286 { 287 AcpiGbl_IntegerBitWidth = 32; 288 AcpiGbl_IntegerByteWidth = 4; 289 } 290 else 291 { 292 AcpiGbl_IntegerBitWidth = 64; 293 AcpiGbl_IntegerByteWidth = 8; 294 } 295} 296 297 298#ifdef ACPI_DEBUG_OUTPUT 299/******************************************************************************* 300 * 301 * FUNCTION: AcpiUtDisplayInitPathname 302 * 303 * PARAMETERS: ObjHandle - Handle whose pathname will be displayed 304 * Path - Additional path string to be appended 305 * 306 * RETURN: ACPI_STATUS 307 * 308 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY 309 * 310 ******************************************************************************/ 311 312void 313AcpiUtDisplayInitPathname ( 314 ACPI_HANDLE ObjHandle, 315 char *Path) 316{ 317 ACPI_STATUS Status; 318 ACPI_BUFFER Buffer; 319 320 321 ACPI_FUNCTION_NAME ("UtDisplayInitPathname"); 322 323 324 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 325 326 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 327 if (ACPI_SUCCESS (Status)) 328 { 329 if (Path) 330 { 331 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", (char *) Buffer.Pointer, Path)); 332 } 333 else 334 { 335 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", (char *) Buffer.Pointer)); 336 } 337 338 ACPI_MEM_FREE (Buffer.Pointer); 339 } 340} 341#endif 342 343 344/******************************************************************************* 345 * 346 * FUNCTION: AcpiUtValidAcpiName 347 * 348 * PARAMETERS: Character - The character to be examined 349 * 350 * RETURN: 1 if Character may appear in a name, else 0 351 * 352 * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 353 * 1) Upper case alpha 354 * 2) numeric 355 * 3) underscore 356 * 357 ******************************************************************************/ 358 359BOOLEAN 360AcpiUtValidAcpiName ( 361 UINT32 Name) 362{ 363 NATIVE_CHAR *NamePtr = (NATIVE_CHAR *) &Name; 364 UINT32 i; 365 366 367 ACPI_FUNCTION_ENTRY (); 368 369 370 for (i = 0; i < ACPI_NAME_SIZE; i++) 371 { 372 if (!((NamePtr[i] == '_') || 373 (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') || 374 (NamePtr[i] >= '0' && NamePtr[i] <= '9'))) 375 { 376 return (FALSE); 377 } 378 } 379 380 return (TRUE); 381} 382 383 384/******************************************************************************* 385 * 386 * FUNCTION: AcpiUtValidAcpiCharacter 387 * 388 * PARAMETERS: Character - The character to be examined 389 * 390 * RETURN: 1 if Character may appear in a name, else 0 391 * 392 * DESCRIPTION: Check for a printable character 393 * 394 ******************************************************************************/ 395 396BOOLEAN 397AcpiUtValidAcpiCharacter ( 398 NATIVE_CHAR Character) 399{ 400 401 ACPI_FUNCTION_ENTRY (); 402 403 return ((BOOLEAN) ((Character == '_') || 404 (Character >= 'A' && Character <= 'Z') || 405 (Character >= '0' && Character <= '9'))); 406} 407 408 409/******************************************************************************* 410 * 411 * FUNCTION: AcpiUtStrtoul64 412 * 413 * PARAMETERS: String - Null terminated string 414 * Terminater - Where a pointer to the terminating byte is returned 415 * Base - Radix of the string 416 * 417 * RETURN: Converted value 418 * 419 * DESCRIPTION: Convert a string into an unsigned value. 420 * 421 ******************************************************************************/ 422#define NEGATIVE 1 423#define POSITIVE 0 424 425ACPI_STATUS 426AcpiUtStrtoul64 ( 427 NATIVE_CHAR *String, 428 UINT32 Base, 429 ACPI_INTEGER *RetInteger) 430{ 431 UINT32 Index; 432 ACPI_INTEGER ReturnValue = 0; 433 ACPI_STATUS Status = AE_OK; 434 ACPI_INTEGER Dividend; 435 ACPI_INTEGER Quotient; 436 437 438 *RetInteger = 0; 439 440 switch (Base) 441 { 442 case 0: 443 case 8: 444 case 10: 445 case 16: 446 break; 447 448 default: 449 /* 450 * The specified Base parameter is not in the domain of 451 * this function: 452 */ 453 return (AE_BAD_PARAMETER); 454 } 455 456 /* 457 * skip over any white space in the buffer: 458 */ 459 while (ACPI_IS_SPACE (*String) || *String == '\t') 460 { 461 ++String; 462 } 463 464 /* 465 * If the input parameter Base is zero, then we need to 466 * determine if it is octal, decimal, or hexadecimal: 467 */ 468 if (Base == 0) 469 { 470 if (*String == '0') 471 { 472 if (ACPI_TOLOWER (*(++String)) == 'x') 473 { 474 Base = 16; 475 ++String; 476 } 477 else 478 { 479 Base = 8; 480 } 481 } 482 else 483 { 484 Base = 10; 485 } 486 } 487 488 /* 489 * For octal and hexadecimal bases, skip over the leading 490 * 0 or 0x, if they are present. 491 */ 492 if (Base == 8 && *String == '0') 493 { 494 String++; 495 } 496 497 if (Base == 16 && 498 *String == '0' && 499 ACPI_TOLOWER (*(++String)) == 'x') 500 { 501 String++; 502 } 503 504 /* Main loop: convert the string to an unsigned long */ 505 506 while (*String) 507 { 508 if (ACPI_IS_DIGIT (*String)) 509 { 510 Index = ((UINT8) *String) - '0'; 511 } 512 else 513 { 514 Index = (UINT8) ACPI_TOUPPER (*String); 515 if (ACPI_IS_UPPER ((char) Index)) 516 { 517 Index = Index - 'A' + 10; 518 } 519 else 520 { 521 goto ErrorExit; 522 } 523 } 524 525 if (Index >= Base) 526 { 527 goto ErrorExit; 528 } 529 530 /* Check to see if value is out of range: */ 531 532 Dividend = ACPI_INTEGER_MAX - (ACPI_INTEGER) Index; 533 (void) AcpiUtShortDivide (&Dividend, Base, &Quotient, NULL); 534 if (ReturnValue > Quotient) 535 { 536 goto ErrorExit; 537 } 538 539 ReturnValue *= Base; 540 ReturnValue += Index; 541 ++String; 542 } 543 544 *RetInteger = ReturnValue; 545 return (Status); 546 547 548ErrorExit: 549 switch (Base) 550 { 551 case 8: 552 Status = AE_BAD_OCTAL_CONSTANT; 553 break; 554 555 case 10: 556 Status = AE_BAD_DECIMAL_CONSTANT; 557 break; 558 559 case 16: 560 Status = AE_BAD_HEX_CONSTANT; 561 break; 562 563 default: 564 /* Base validated above */ 565 break; 566 } 567 568 return (Status); 569} 570 571 572/******************************************************************************* 573 * 574 * FUNCTION: AcpiUtStrupr 575 * 576 * PARAMETERS: SrcString - The source string to convert to 577 * 578 * RETURN: SrcString 579 * 580 * DESCRIPTION: Convert string to uppercase 581 * 582 ******************************************************************************/ 583 584NATIVE_CHAR * 585AcpiUtStrupr ( 586 NATIVE_CHAR *SrcString) 587{ 588 NATIVE_CHAR *String; 589 590 591 ACPI_FUNCTION_ENTRY (); 592 593 594 /* Walk entire string, uppercasing the letters */ 595 596 for (String = SrcString; *String; ) 597 { 598 *String = (char) ACPI_TOUPPER (*String); 599 String++; 600 } 601 602 603 return (SrcString); 604} 605 606/******************************************************************************* 607 * 608 * FUNCTION: AcpiUtMutexInitialize 609 * 610 * PARAMETERS: None. 611 * 612 * RETURN: Status 613 * 614 * DESCRIPTION: Create the system mutex objects. 615 * 616 ******************************************************************************/ 617 618ACPI_STATUS 619AcpiUtMutexInitialize ( 620 void) 621{ 622 UINT32 i; 623 ACPI_STATUS Status; 624 625 626 ACPI_FUNCTION_TRACE ("UtMutexInitialize"); 627 628 629 /* 630 * Create each of the predefined mutex objects 631 */ 632 for (i = 0; i < NUM_MTX; i++) 633 { 634 Status = AcpiUtCreateMutex (i); 635 if (ACPI_FAILURE (Status)) 636 { 637 return_ACPI_STATUS (Status); 638 } 639 } 640 641 return_ACPI_STATUS (AE_OK); 642} 643 644 645/******************************************************************************* 646 * 647 * FUNCTION: AcpiUtMutexTerminate 648 * 649 * PARAMETERS: None. 650 * 651 * RETURN: None. 652 * 653 * DESCRIPTION: Delete all of the system mutex objects. 654 * 655 ******************************************************************************/ 656 657void 658AcpiUtMutexTerminate ( 659 void) 660{ 661 UINT32 i; 662 663 664 ACPI_FUNCTION_TRACE ("UtMutexTerminate"); 665 666 667 /* 668 * Delete each predefined mutex object 669 */ 670 for (i = 0; i < NUM_MTX; i++) 671 { 672 (void) AcpiUtDeleteMutex (i); 673 } 674 675 return_VOID; 676} 677 678 679/******************************************************************************* 680 * 681 * FUNCTION: AcpiUtCreateMutex 682 * 683 * PARAMETERS: MutexID - ID of the mutex to be created 684 * 685 * RETURN: Status 686 * 687 * DESCRIPTION: Create a mutex object. 688 * 689 ******************************************************************************/ 690 691ACPI_STATUS 692AcpiUtCreateMutex ( 693 ACPI_MUTEX_HANDLE MutexId) 694{ 695 ACPI_STATUS Status = AE_OK; 696 697 698 ACPI_FUNCTION_TRACE_U32 ("UtCreateMutex", MutexId); 699 700 701 if (MutexId > MAX_MTX) 702 { 703 return_ACPI_STATUS (AE_BAD_PARAMETER); 704 } 705 706 707 if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex) 708 { 709 Status = AcpiOsCreateSemaphore (1, 1, 710 &AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 711 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 712 AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0; 713 } 714 715 return_ACPI_STATUS (Status); 716} 717 718 719/******************************************************************************* 720 * 721 * FUNCTION: AcpiUtDeleteMutex 722 * 723 * PARAMETERS: MutexID - ID of the mutex to be deleted 724 * 725 * RETURN: Status 726 * 727 * DESCRIPTION: Delete a mutex object. 728 * 729 ******************************************************************************/ 730 731ACPI_STATUS 732AcpiUtDeleteMutex ( 733 ACPI_MUTEX_HANDLE MutexId) 734{ 735 ACPI_STATUS Status; 736 737 738 ACPI_FUNCTION_TRACE_U32 ("UtDeleteMutex", MutexId); 739 740 741 if (MutexId > MAX_MTX) 742 { 743 return_ACPI_STATUS (AE_BAD_PARAMETER); 744 } 745 746 747 Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex); 748 749 AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL; 750 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 751 752 return_ACPI_STATUS (Status); 753} 754 755 756/******************************************************************************* 757 * 758 * FUNCTION: AcpiUtAcquireMutex 759 * 760 * PARAMETERS: MutexID - ID of the mutex to be acquired 761 * 762 * RETURN: Status 763 * 764 * DESCRIPTION: Acquire a mutex object. 765 * 766 ******************************************************************************/ 767 768ACPI_STATUS 769AcpiUtAcquireMutex ( 770 ACPI_MUTEX_HANDLE MutexId) 771{ 772 ACPI_STATUS Status; 773 UINT32 i; 774 UINT32 ThisThreadId; 775 776 777 ACPI_FUNCTION_NAME ("UtAcquireMutex"); 778 779 780 if (MutexId > MAX_MTX) 781 { 782 return (AE_BAD_PARAMETER); 783 } 784 785 786 ThisThreadId = AcpiOsGetThreadId (); 787 788 /* 789 * Deadlock prevention. Check if this thread owns any mutexes of value 790 * greater than or equal to this one. If so, the thread has violated 791 * the mutex ordering rule. This indicates a coding error somewhere in 792 * the ACPI subsystem code. 793 */ 794 for (i = MutexId; i < MAX_MTX; i++) 795 { 796 if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) 797 { 798 if (i == MutexId) 799 { 800 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 801 "Mutex [%s] already acquired by this thread [%X]\n", 802 AcpiUtGetMutexName (MutexId), ThisThreadId)); 803 804 return (AE_ALREADY_ACQUIRED); 805 } 806 807 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 808 "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", 809 ThisThreadId, AcpiUtGetMutexName (i), 810 AcpiUtGetMutexName (MutexId))); 811 812 return (AE_ACQUIRE_DEADLOCK); 813 } 814 } 815 816 817 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, 818 "Thread %X attempting to acquire Mutex [%s]\n", 819 ThisThreadId, AcpiUtGetMutexName (MutexId))); 820 821 Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 822 1, ACPI_WAIT_FOREVER); 823 if (ACPI_SUCCESS (Status)) 824 { 825 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", 826 ThisThreadId, AcpiUtGetMutexName (MutexId))); 827 828 AcpiGbl_AcpiMutexInfo[MutexId].UseCount++; 829 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId; 830 } 831 832 else 833 { 834 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", 835 ThisThreadId, AcpiUtGetMutexName (MutexId), 836 AcpiFormatException (Status))); 837 } 838 839 return (Status); 840} 841 842 843/******************************************************************************* 844 * 845 * FUNCTION: AcpiUtReleaseMutex 846 * 847 * PARAMETERS: MutexID - ID of the mutex to be released 848 * 849 * RETURN: Status 850 * 851 * DESCRIPTION: Release a mutex object. 852 * 853 ******************************************************************************/ 854 855ACPI_STATUS 856AcpiUtReleaseMutex ( 857 ACPI_MUTEX_HANDLE MutexId) 858{ 859 ACPI_STATUS Status; 860 UINT32 i; 861 UINT32 ThisThreadId; 862 863 864 ACPI_FUNCTION_NAME ("UtReleaseMutex"); 865 866 867 ThisThreadId = AcpiOsGetThreadId (); 868 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, 869 "Thread %X releasing Mutex [%s]\n", ThisThreadId, 870 AcpiUtGetMutexName (MutexId))); 871 872 if (MutexId > MAX_MTX) 873 { 874 return (AE_BAD_PARAMETER); 875 } 876 877 878 /* 879 * Mutex must be acquired in order to release it! 880 */ 881 if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED) 882 { 883 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 884 "Mutex [%s] is not acquired, cannot release\n", 885 AcpiUtGetMutexName (MutexId))); 886 887 return (AE_NOT_ACQUIRED); 888 } 889 890 891 /* 892 * Deadlock prevention. Check if this thread owns any mutexes of value 893 * greater than this one. If so, the thread has violated the mutex 894 * ordering rule. This indicates a coding error somewhere in 895 * the ACPI subsystem code. 896 */ 897 for (i = MutexId; i < MAX_MTX; i++) 898 { 899 if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) 900 { 901 if (i == MutexId) 902 { 903 continue; 904 } 905 906 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 907 "Invalid release order: owns [%s], releasing [%s]\n", 908 AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); 909 910 return (AE_RELEASE_DEADLOCK); 911 } 912 } 913 914 915 /* Mark unlocked FIRST */ 916 917 AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; 918 919 Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1); 920 921 if (ACPI_FAILURE (Status)) 922 { 923 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", 924 ThisThreadId, AcpiUtGetMutexName (MutexId), 925 AcpiFormatException (Status))); 926 } 927 else 928 { 929 ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", 930 ThisThreadId, AcpiUtGetMutexName (MutexId))); 931 } 932 933 return (Status); 934} 935 936 937/******************************************************************************* 938 * 939 * FUNCTION: AcpiUtCreateUpdateStateAndPush 940 * 941 * PARAMETERS: *Object - Object to be added to the new state 942 * Action - Increment/Decrement 943 * StateList - List the state will be added to 944 * 945 * RETURN: None 946 * 947 * DESCRIPTION: Create a new state and push it 948 * 949 ******************************************************************************/ 950 951ACPI_STATUS 952AcpiUtCreateUpdateStateAndPush ( 953 ACPI_OPERAND_OBJECT *Object, 954 UINT16 Action, 955 ACPI_GENERIC_STATE **StateList) 956{ 957 ACPI_GENERIC_STATE *State; 958 959 960 ACPI_FUNCTION_ENTRY (); 961 962 963 /* Ignore null objects; these are expected */ 964 965 if (!Object) 966 { 967 return (AE_OK); 968 } 969 970 State = AcpiUtCreateUpdateState (Object, Action); 971 if (!State) 972 { 973 return (AE_NO_MEMORY); 974 } 975 976 977 AcpiUtPushGenericState (StateList, State); 978 return (AE_OK); 979} 980 981 982/******************************************************************************* 983 * 984 * FUNCTION: AcpiUtCreatePkgStateAndPush 985 * 986 * PARAMETERS: *Object - Object to be added to the new state 987 * Action - Increment/Decrement 988 * StateList - List the state will be added to 989 * 990 * RETURN: None 991 * 992 * DESCRIPTION: Create a new state and push it 993 * 994 ******************************************************************************/ 995 996ACPI_STATUS 997AcpiUtCreatePkgStateAndPush ( 998 void *InternalObject, 999 void *ExternalObject, 1000 UINT16 Index, 1001 ACPI_GENERIC_STATE **StateList) 1002{ 1003 ACPI_GENERIC_STATE *State; 1004 1005 1006 ACPI_FUNCTION_ENTRY (); 1007 1008 1009 State = AcpiUtCreatePkgState (InternalObject, ExternalObject, Index); 1010 if (!State) 1011 { 1012 return (AE_NO_MEMORY); 1013 } 1014 1015 1016 AcpiUtPushGenericState (StateList, State); 1017 return (AE_OK); 1018} 1019 1020 1021/******************************************************************************* 1022 * 1023 * FUNCTION: AcpiUtPushGenericState 1024 * 1025 * PARAMETERS: ListHead - Head of the state stack 1026 * State - State object to push 1027 * 1028 * RETURN: Status 1029 * 1030 * DESCRIPTION: Push a state object onto a state stack 1031 * 1032 ******************************************************************************/ 1033 1034void 1035AcpiUtPushGenericState ( 1036 ACPI_GENERIC_STATE **ListHead, 1037 ACPI_GENERIC_STATE *State) 1038{ 1039 ACPI_FUNCTION_TRACE ("UtPushGenericState"); 1040 1041 1042 /* Push the state object onto the front of the list (stack) */ 1043 1044 State->Common.Next = *ListHead; 1045 *ListHead = State; 1046 1047 return_VOID; 1048} 1049 1050 1051/******************************************************************************* 1052 * 1053 * FUNCTION: AcpiUtPopGenericState 1054 * 1055 * PARAMETERS: ListHead - Head of the state stack 1056 * 1057 * RETURN: Status 1058 * 1059 * DESCRIPTION: Pop a state object from a state stack 1060 * 1061 ******************************************************************************/ 1062 1063ACPI_GENERIC_STATE * 1064AcpiUtPopGenericState ( 1065 ACPI_GENERIC_STATE **ListHead) 1066{ 1067 ACPI_GENERIC_STATE *State; 1068 1069 1070 ACPI_FUNCTION_TRACE ("UtPopGenericState"); 1071 1072 1073 /* Remove the state object at the head of the list (stack) */ 1074 1075 State = *ListHead; 1076 if (State) 1077 { 1078 /* Update the list head */ 1079 1080 *ListHead = State->Common.Next; 1081 } 1082 1083 return_PTR (State); 1084} 1085 1086 1087/******************************************************************************* 1088 * 1089 * FUNCTION: AcpiUtCreateGenericState 1090 * 1091 * PARAMETERS: None 1092 * 1093 * RETURN: Status 1094 * 1095 * DESCRIPTION: Create a generic state object. Attempt to obtain one from 1096 * the global state cache; If none available, create a new one. 1097 * 1098 ******************************************************************************/ 1099 1100ACPI_GENERIC_STATE * 1101AcpiUtCreateGenericState (void) 1102{ 1103 ACPI_GENERIC_STATE *State; 1104 1105 1106 ACPI_FUNCTION_ENTRY (); 1107 1108 1109 State = AcpiUtAcquireFromCache (ACPI_MEM_LIST_STATE); 1110 1111 /* Initialize */ 1112 1113 if (State) 1114 { 1115 State->Common.DataType = ACPI_DESC_TYPE_STATE; 1116 } 1117 1118 return (State); 1119} 1120 1121 1122/******************************************************************************* 1123 * 1124 * FUNCTION: AcpiUtCreateThreadState 1125 * 1126 * PARAMETERS: None 1127 * 1128 * RETURN: Thread State 1129 * 1130 * DESCRIPTION: Create a "Thread State" - a flavor of the generic state used 1131 * to track per-thread info during method execution 1132 * 1133 ******************************************************************************/ 1134 1135ACPI_THREAD_STATE * 1136AcpiUtCreateThreadState ( 1137 void) 1138{ 1139 ACPI_GENERIC_STATE *State; 1140 1141 1142 ACPI_FUNCTION_TRACE ("UtCreateThreadState"); 1143 1144 1145 /* Create the generic state object */ 1146 1147 State = AcpiUtCreateGenericState (); 1148 if (!State) 1149 { 1150 return_PTR (NULL); 1151 } 1152 1153 /* Init fields specific to the update struct */ 1154 1155 State->Common.DataType = ACPI_DESC_TYPE_STATE_THREAD; 1156 State->Thread.ThreadId = AcpiOsGetThreadId (); 1157 1158 return_PTR ((ACPI_THREAD_STATE *) State); 1159} 1160 1161 1162/******************************************************************************* 1163 * 1164 * FUNCTION: AcpiUtCreateUpdateState 1165 * 1166 * PARAMETERS: Object - Initial Object to be installed in the 1167 * state 1168 * Action - Update action to be performed 1169 * 1170 * RETURN: Status 1171 * 1172 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used 1173 * to update reference counts and delete complex objects such 1174 * as packages. 1175 * 1176 ******************************************************************************/ 1177 1178ACPI_GENERIC_STATE * 1179AcpiUtCreateUpdateState ( 1180 ACPI_OPERAND_OBJECT *Object, 1181 UINT16 Action) 1182{ 1183 ACPI_GENERIC_STATE *State; 1184 1185 1186 ACPI_FUNCTION_TRACE_PTR ("UtCreateUpdateState", Object); 1187 1188 1189 /* Create the generic state object */ 1190 1191 State = AcpiUtCreateGenericState (); 1192 if (!State) 1193 { 1194 return_PTR (NULL); 1195 } 1196 1197 /* Init fields specific to the update struct */ 1198 1199 State->Common.DataType = ACPI_DESC_TYPE_STATE_UPDATE; 1200 State->Update.Object = Object; 1201 State->Update.Value = Action; 1202 1203 return_PTR (State); 1204} 1205 1206 1207/******************************************************************************* 1208 * 1209 * FUNCTION: AcpiUtCreatePkgState 1210 * 1211 * PARAMETERS: Object - Initial Object to be installed in the 1212 * state 1213 * Action - Update action to be performed 1214 * 1215 * RETURN: Status 1216 * 1217 * DESCRIPTION: Create a "Package State" 1218 * 1219 ******************************************************************************/ 1220 1221ACPI_GENERIC_STATE * 1222AcpiUtCreatePkgState ( 1223 void *InternalObject, 1224 void *ExternalObject, 1225 UINT16 Index) 1226{ 1227 ACPI_GENERIC_STATE *State; 1228 1229 1230 ACPI_FUNCTION_TRACE_PTR ("UtCreatePkgState", InternalObject); 1231 1232 1233 /* Create the generic state object */ 1234 1235 State = AcpiUtCreateGenericState (); 1236 if (!State) 1237 { 1238 return_PTR (NULL); 1239 } 1240 1241 /* Init fields specific to the update struct */ 1242 1243 State->Common.DataType = ACPI_DESC_TYPE_STATE_PACKAGE; 1244 State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject; 1245 State->Pkg.DestObject = ExternalObject; 1246 State->Pkg.Index = Index; 1247 State->Pkg.NumPackages = 1; 1248 1249 return_PTR (State); 1250} 1251 1252 1253/******************************************************************************* 1254 * 1255 * FUNCTION: AcpiUtCreateControlState 1256 * 1257 * PARAMETERS: None 1258 * 1259 * RETURN: Status 1260 * 1261 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used 1262 * to support nested IF/WHILE constructs in the AML. 1263 * 1264 ******************************************************************************/ 1265 1266ACPI_GENERIC_STATE * 1267AcpiUtCreateControlState ( 1268 void) 1269{ 1270 ACPI_GENERIC_STATE *State; 1271 1272 1273 ACPI_FUNCTION_TRACE ("UtCreateControlState"); 1274 1275 1276 /* Create the generic state object */ 1277 1278 State = AcpiUtCreateGenericState (); 1279 if (!State) 1280 { 1281 return_PTR (NULL); 1282 } 1283 1284 1285 /* Init fields specific to the control struct */ 1286 1287 State->Common.DataType = ACPI_DESC_TYPE_STATE_CONTROL; 1288 State->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING; 1289 1290 return_PTR (State); 1291} 1292 1293 1294/******************************************************************************* 1295 * 1296 * FUNCTION: AcpiUtDeleteGenericState 1297 * 1298 * PARAMETERS: State - The state object to be deleted 1299 * 1300 * RETURN: Status 1301 * 1302 * DESCRIPTION: Put a state object back into the global state cache. The object 1303 * is not actually freed at this time. 1304 * 1305 ******************************************************************************/ 1306 1307void 1308AcpiUtDeleteGenericState ( 1309 ACPI_GENERIC_STATE *State) 1310{ 1311 ACPI_FUNCTION_TRACE ("UtDeleteGenericState"); 1312 1313 1314 AcpiUtReleaseToCache (ACPI_MEM_LIST_STATE, State); 1315 return_VOID; 1316} 1317 1318 1319/******************************************************************************* 1320 * 1321 * FUNCTION: AcpiUtDeleteGenericStateCache 1322 * 1323 * PARAMETERS: None 1324 * 1325 * RETURN: Status 1326 * 1327 * DESCRIPTION: Purge the global state object cache. Used during subsystem 1328 * termination. 1329 * 1330 ******************************************************************************/ 1331 1332void 1333AcpiUtDeleteGenericStateCache ( 1334 void) 1335{ 1336 ACPI_FUNCTION_TRACE ("UtDeleteGenericStateCache"); 1337 1338 1339 AcpiUtDeleteGenericCache (ACPI_MEM_LIST_STATE); 1340 return_VOID; 1341} 1342 1343 1344/******************************************************************************* 1345 * 1346 * FUNCTION: AcpiUtWalkPackageTree 1347 * 1348 * PARAMETERS: ObjDesc - The Package object on which to resolve refs 1349 * 1350 * RETURN: Status 1351 * 1352 * DESCRIPTION: Walk through a package 1353 * 1354 ******************************************************************************/ 1355 1356ACPI_STATUS 1357AcpiUtWalkPackageTree ( 1358 ACPI_OPERAND_OBJECT *SourceObject, 1359 void *TargetObject, 1360 ACPI_PKG_CALLBACK WalkCallback, 1361 void *Context) 1362{ 1363 ACPI_STATUS Status = AE_OK; 1364 ACPI_GENERIC_STATE *StateList = NULL; 1365 ACPI_GENERIC_STATE *State; 1366 UINT32 ThisIndex; 1367 ACPI_OPERAND_OBJECT *ThisSourceObj; 1368 1369 1370 ACPI_FUNCTION_TRACE ("UtWalkPackageTree"); 1371 1372 1373 State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 1374 if (!State) 1375 { 1376 return_ACPI_STATUS (AE_NO_MEMORY); 1377 } 1378 1379 while (State) 1380 { 1381 ThisIndex = State->Pkg.Index; 1382 ThisSourceObj = (ACPI_OPERAND_OBJECT *) 1383 State->Pkg.SourceObject->Package.Elements[ThisIndex]; 1384 1385 /* 1386 * Check for: 1387 * 1) An uninitialized package element. It is completely 1388 * legal to declare a package and leave it uninitialized 1389 * 2) Not an internal object - can be a namespace node instead 1390 * 3) Any type other than a package. Packages are handled in else 1391 * case below. 1392 */ 1393 if ((!ThisSourceObj) || 1394 (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) || 1395 (ACPI_GET_OBJECT_TYPE (ThisSourceObj) != ACPI_TYPE_PACKAGE)) 1396 { 1397 Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 1398 State, Context); 1399 if (ACPI_FAILURE (Status)) 1400 { 1401 return_ACPI_STATUS (Status); 1402 } 1403 1404 State->Pkg.Index++; 1405 while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 1406 { 1407 /* 1408 * We've handled all of the objects at this level, This means 1409 * that we have just completed a package. That package may 1410 * have contained one or more packages itself. 1411 * 1412 * Delete this state and pop the previous state (package). 1413 */ 1414 AcpiUtDeleteGenericState (State); 1415 State = AcpiUtPopGenericState (&StateList); 1416 1417 /* Finished when there are no more states */ 1418 1419 if (!State) 1420 { 1421 /* 1422 * We have handled all of the objects in the top level 1423 * package just add the length of the package objects 1424 * and exit 1425 */ 1426 return_ACPI_STATUS (AE_OK); 1427 } 1428 1429 /* 1430 * Go back up a level and move the index past the just 1431 * completed package object. 1432 */ 1433 State->Pkg.Index++; 1434 } 1435 } 1436 else 1437 { 1438 /* This is a subobject of type package */ 1439 1440 Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 1441 State, Context); 1442 if (ACPI_FAILURE (Status)) 1443 { 1444 return_ACPI_STATUS (Status); 1445 } 1446 1447 /* 1448 * Push the current state and create a new one 1449 * The callback above returned a new target package object. 1450 */ 1451 AcpiUtPushGenericState (&StateList, State); 1452 State = AcpiUtCreatePkgState (ThisSourceObj, 1453 State->Pkg.ThisTargetObj, 0); 1454 if (!State) 1455 { 1456 return_ACPI_STATUS (AE_NO_MEMORY); 1457 } 1458 } 1459 } 1460 1461 /* We should never get here */ 1462 1463 return_ACPI_STATUS (AE_AML_INTERNAL); 1464} 1465 1466 1467/******************************************************************************* 1468 * 1469 * FUNCTION: AcpiUtGenerateChecksum 1470 * 1471 * PARAMETERS: Buffer - Buffer to be scanned 1472 * Length - number of bytes to examine 1473 * 1474 * RETURN: checksum 1475 * 1476 * DESCRIPTION: Generate a checksum on a raw buffer 1477 * 1478 ******************************************************************************/ 1479 1480UINT8 1481AcpiUtGenerateChecksum ( 1482 UINT8 *Buffer, 1483 UINT32 Length) 1484{ 1485 UINT32 i; 1486 signed char Sum = 0; 1487 1488 for (i = 0; i < Length; i++) 1489 { 1490 Sum = (signed char) (Sum + Buffer[i]); 1491 } 1492 1493 return ((UINT8) (0 - Sum)); 1494} 1495 1496 1497/******************************************************************************* 1498 * 1499 * FUNCTION: AcpiUtGetResourceEndTag 1500 * 1501 * PARAMETERS: ObjDesc - The resource template buffer object 1502 * 1503 * RETURN: Pointer to the end tag 1504 * 1505 * DESCRIPTION: Find the END_TAG resource descriptor in a resource template 1506 * 1507 ******************************************************************************/ 1508 1509 1510UINT8 * 1511AcpiUtGetResourceEndTag ( 1512 ACPI_OPERAND_OBJECT *ObjDesc) 1513{ 1514 UINT8 BufferByte; 1515 UINT8 *Buffer; 1516 UINT8 *EndBuffer; 1517 1518 1519 Buffer = ObjDesc->Buffer.Pointer; 1520 EndBuffer = Buffer + ObjDesc->Buffer.Length; 1521 1522 while (Buffer < EndBuffer) 1523 { 1524 BufferByte = *Buffer; 1525 if (BufferByte & ACPI_RDESC_TYPE_MASK) 1526 { 1527 /* Large Descriptor - Length is next 2 bytes */ 1528 1529 Buffer += ((*(Buffer+1) | (*(Buffer+2) << 8)) + 3); 1530 } 1531 else 1532 { 1533 /* Small Descriptor. End Tag will be found here */ 1534 1535 if ((BufferByte & ACPI_RDESC_SMALL_MASK) == ACPI_RDESC_TYPE_END_TAG) 1536 { 1537 /* Found the end tag descriptor, all done. */ 1538 1539 return (Buffer); 1540 } 1541 1542 /* Length is in the header */ 1543 1544 Buffer += ((BufferByte & 0x07) + 1); 1545 } 1546 } 1547 1548 /* End tag not found */ 1549 1550 return (NULL); 1551} 1552 1553 1554/******************************************************************************* 1555 * 1556 * FUNCTION: AcpiUtReportError 1557 * 1558 * PARAMETERS: ModuleName - Caller's module name (for error output) 1559 * LineNumber - Caller's line number (for error output) 1560 * ComponentId - Caller's component ID (for error output) 1561 * Message - Error message to use on failure 1562 * 1563 * RETURN: None 1564 * 1565 * DESCRIPTION: Print error message 1566 * 1567 ******************************************************************************/ 1568 1569void 1570AcpiUtReportError ( 1571 NATIVE_CHAR *ModuleName, 1572 UINT32 LineNumber, 1573 UINT32 ComponentId) 1574{ 1575 1576 1577 AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber); 1578} 1579 1580 1581/******************************************************************************* 1582 * 1583 * FUNCTION: AcpiUtReportWarning 1584 * 1585 * PARAMETERS: ModuleName - Caller's module name (for error output) 1586 * LineNumber - Caller's line number (for error output) 1587 * ComponentId - Caller's component ID (for error output) 1588 * Message - Error message to use on failure 1589 * 1590 * RETURN: None 1591 * 1592 * DESCRIPTION: Print warning message 1593 * 1594 ******************************************************************************/ 1595 1596void 1597AcpiUtReportWarning ( 1598 NATIVE_CHAR *ModuleName, 1599 UINT32 LineNumber, 1600 UINT32 ComponentId) 1601{ 1602 1603 AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber); 1604} 1605 1606 1607/******************************************************************************* 1608 * 1609 * FUNCTION: AcpiUtReportInfo 1610 * 1611 * PARAMETERS: ModuleName - Caller's module name (for error output) 1612 * LineNumber - Caller's line number (for error output) 1613 * ComponentId - Caller's component ID (for error output) 1614 * Message - Error message to use on failure 1615 * 1616 * RETURN: None 1617 * 1618 * DESCRIPTION: Print information message 1619 * 1620 ******************************************************************************/ 1621 1622void 1623AcpiUtReportInfo ( 1624 NATIVE_CHAR *ModuleName, 1625 UINT32 LineNumber, 1626 UINT32 ComponentId) 1627{ 1628 1629 AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber); 1630} 1631 1632 1633 1634