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