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