13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: utmisc - common utility procedures 43446Smrj * 53446Smrj ******************************************************************************/ 63446Smrj 73446Smrj /****************************************************************************** 83446Smrj * 93446Smrj * 1. Copyright Notice 103446Smrj * 119980SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 123446Smrj * All rights reserved. 133446Smrj * 143446Smrj * 2. License 153446Smrj * 163446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 173446Smrj * rights. You may have additional license terms from the party that provided 183446Smrj * you this software, covering your right to use that party's intellectual 193446Smrj * property rights. 203446Smrj * 213446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 223446Smrj * copy of the source code appearing in this file ("Covered Code") an 233446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 243446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 253446Smrj * make derivatives, distribute, use and display any portion of the Covered 263446Smrj * Code in any form, with the right to sublicense such rights; and 273446Smrj * 283446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 293446Smrj * license (with the right to sublicense), under only those claims of Intel 303446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 313446Smrj * offer to sell, and import the Covered Code and derivative works thereof 323446Smrj * solely to the minimum extent necessary to exercise the above copyright 333446Smrj * license, and in no event shall the patent license extend to any additions 343446Smrj * to or modifications of the Original Intel Code. No other license or right 353446Smrj * is granted directly or by implication, estoppel or otherwise; 363446Smrj * 373446Smrj * The above copyright and patent license is granted only if the following 383446Smrj * conditions are met: 393446Smrj * 403446Smrj * 3. Conditions 413446Smrj * 423446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 433446Smrj * Redistribution of source code of any substantial portion of the Covered 443446Smrj * Code or modification with rights to further distribute source must include 453446Smrj * the above Copyright Notice, the above License, this list of Conditions, 463446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 473446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 483446Smrj * contain a file documenting the changes Licensee made to create that Covered 493446Smrj * Code and the date of any change. Licensee must include in that file the 503446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 513446Smrj * must include a prominent statement that the modification is derived, 523446Smrj * directly or indirectly, from Original Intel Code. 533446Smrj * 543446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 553446Smrj * Redistribution of source code of any substantial portion of the Covered 563446Smrj * Code or modification without rights to further distribute source must 573446Smrj * include the following Disclaimer and Export Compliance provision in the 583446Smrj * documentation and/or other materials provided with distribution. In 593446Smrj * addition, Licensee may not authorize further sublicense of source of any 603446Smrj * portion of the Covered Code, and must include terms to the effect that the 613446Smrj * license from Licensee to its licensee is limited to the intellectual 623446Smrj * property embodied in the software Licensee provides to its licensee, and 633446Smrj * not to intellectual property embodied in modifications its licensee may 643446Smrj * make. 653446Smrj * 663446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 673446Smrj * substantial portion of the Covered Code or modification must reproduce the 683446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 693446Smrj * provision in the documentation and/or other materials provided with the 703446Smrj * distribution. 713446Smrj * 723446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 733446Smrj * Intel Code. 743446Smrj * 753446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 763446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 773446Smrj * other dealings in products derived from or relating to the Covered Code 783446Smrj * without prior written authorization from Intel. 793446Smrj * 803446Smrj * 4. Disclaimer and Export Compliance 813446Smrj * 823446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 833446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 843446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 853446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 863446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 873446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 883446Smrj * PARTICULAR PURPOSE. 893446Smrj * 903446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 913446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 923446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 933446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 943446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 953446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 963446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 973446Smrj * LIMITED REMEDY. 983446Smrj * 993446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1003446Smrj * software or system incorporating such software without first obtaining any 1013446Smrj * required license or other approval from the U. S. Department of Commerce or 1023446Smrj * any other agency or department of the United States Government. In the 1033446Smrj * event Licensee exports any such software from the United States or 1043446Smrj * re-exports any such software from a foreign destination, Licensee shall 1053446Smrj * ensure that the distribution and export/re-export of the software is in 1063446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1073446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1083446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1093446Smrj * software, or service, directly or indirectly, to any country for which the 1103446Smrj * United States government or any agency thereof requires an export license, 1113446Smrj * other governmental approval, or letter of assurance, without first obtaining 1123446Smrj * such license, approval or letter. 1133446Smrj * 1143446Smrj *****************************************************************************/ 1153446Smrj 1163446Smrj 1173446Smrj #define __UTMISC_C__ 1183446Smrj 1193446Smrj #include "acpi.h" 1209980SDana.Myers@Sun.COM #include "accommon.h" 1213446Smrj #include "acnamesp.h" 1223446Smrj 1233446Smrj 1243446Smrj #define _COMPONENT ACPI_UTILITIES 1253446Smrj ACPI_MODULE_NAME ("utmisc") 1263446Smrj 127*11225SDana.Myers@Sun.COM /* 128*11225SDana.Myers@Sun.COM * Common suffix for messages 129*11225SDana.Myers@Sun.COM */ 130*11225SDana.Myers@Sun.COM #define ACPI_COMMON_MSG_SUFFIX \ 131*11225SDana.Myers@Sun.COM AcpiOsPrintf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, ModuleName, LineNumber) 132*11225SDana.Myers@Sun.COM 1333446Smrj 1343446Smrj /******************************************************************************* 1353446Smrj * 1367851SDana.Myers@Sun.COM * FUNCTION: AcpiUtValidateException 1377851SDana.Myers@Sun.COM * 1387851SDana.Myers@Sun.COM * PARAMETERS: Status - The ACPI_STATUS code to be formatted 1397851SDana.Myers@Sun.COM * 1407851SDana.Myers@Sun.COM * RETURN: A string containing the exception text. NULL if exception is 1417851SDana.Myers@Sun.COM * not valid. 1427851SDana.Myers@Sun.COM * 1437851SDana.Myers@Sun.COM * DESCRIPTION: This function validates and translates an ACPI exception into 1447851SDana.Myers@Sun.COM * an ASCII string. 1457851SDana.Myers@Sun.COM * 1467851SDana.Myers@Sun.COM ******************************************************************************/ 1477851SDana.Myers@Sun.COM 1487851SDana.Myers@Sun.COM const char * 1497851SDana.Myers@Sun.COM AcpiUtValidateException ( 1507851SDana.Myers@Sun.COM ACPI_STATUS Status) 1517851SDana.Myers@Sun.COM { 1527851SDana.Myers@Sun.COM UINT32 SubStatus; 1537851SDana.Myers@Sun.COM const char *Exception = NULL; 1547851SDana.Myers@Sun.COM 1557851SDana.Myers@Sun.COM 1567851SDana.Myers@Sun.COM ACPI_FUNCTION_ENTRY (); 1577851SDana.Myers@Sun.COM 1587851SDana.Myers@Sun.COM 1597851SDana.Myers@Sun.COM /* 1607851SDana.Myers@Sun.COM * Status is composed of two parts, a "type" and an actual code 1617851SDana.Myers@Sun.COM */ 1627851SDana.Myers@Sun.COM SubStatus = (Status & ~AE_CODE_MASK); 1637851SDana.Myers@Sun.COM 1647851SDana.Myers@Sun.COM switch (Status & AE_CODE_MASK) 1657851SDana.Myers@Sun.COM { 1667851SDana.Myers@Sun.COM case AE_CODE_ENVIRONMENTAL: 1677851SDana.Myers@Sun.COM 1687851SDana.Myers@Sun.COM if (SubStatus <= AE_CODE_ENV_MAX) 1697851SDana.Myers@Sun.COM { 1707851SDana.Myers@Sun.COM Exception = AcpiGbl_ExceptionNames_Env [SubStatus]; 1717851SDana.Myers@Sun.COM } 1727851SDana.Myers@Sun.COM break; 1737851SDana.Myers@Sun.COM 1747851SDana.Myers@Sun.COM case AE_CODE_PROGRAMMER: 1757851SDana.Myers@Sun.COM 1767851SDana.Myers@Sun.COM if (SubStatus <= AE_CODE_PGM_MAX) 1777851SDana.Myers@Sun.COM { 1787851SDana.Myers@Sun.COM Exception = AcpiGbl_ExceptionNames_Pgm [SubStatus]; 1797851SDana.Myers@Sun.COM } 1807851SDana.Myers@Sun.COM break; 1817851SDana.Myers@Sun.COM 1827851SDana.Myers@Sun.COM case AE_CODE_ACPI_TABLES: 1837851SDana.Myers@Sun.COM 1847851SDana.Myers@Sun.COM if (SubStatus <= AE_CODE_TBL_MAX) 1857851SDana.Myers@Sun.COM { 1867851SDana.Myers@Sun.COM Exception = AcpiGbl_ExceptionNames_Tbl [SubStatus]; 1877851SDana.Myers@Sun.COM } 1887851SDana.Myers@Sun.COM break; 1897851SDana.Myers@Sun.COM 1907851SDana.Myers@Sun.COM case AE_CODE_AML: 1917851SDana.Myers@Sun.COM 1927851SDana.Myers@Sun.COM if (SubStatus <= AE_CODE_AML_MAX) 1937851SDana.Myers@Sun.COM { 1947851SDana.Myers@Sun.COM Exception = AcpiGbl_ExceptionNames_Aml [SubStatus]; 1957851SDana.Myers@Sun.COM } 1967851SDana.Myers@Sun.COM break; 1977851SDana.Myers@Sun.COM 1987851SDana.Myers@Sun.COM case AE_CODE_CONTROL: 1997851SDana.Myers@Sun.COM 2007851SDana.Myers@Sun.COM if (SubStatus <= AE_CODE_CTRL_MAX) 2017851SDana.Myers@Sun.COM { 2027851SDana.Myers@Sun.COM Exception = AcpiGbl_ExceptionNames_Ctrl [SubStatus]; 2037851SDana.Myers@Sun.COM } 2047851SDana.Myers@Sun.COM break; 2057851SDana.Myers@Sun.COM 2067851SDana.Myers@Sun.COM default: 2077851SDana.Myers@Sun.COM break; 2087851SDana.Myers@Sun.COM } 2097851SDana.Myers@Sun.COM 2107851SDana.Myers@Sun.COM return (ACPI_CAST_PTR (const char, Exception)); 2117851SDana.Myers@Sun.COM } 2127851SDana.Myers@Sun.COM 2137851SDana.Myers@Sun.COM 2147851SDana.Myers@Sun.COM /******************************************************************************* 2157851SDana.Myers@Sun.COM * 216*11225SDana.Myers@Sun.COM * FUNCTION: AcpiUtIsPciRootBridge 217*11225SDana.Myers@Sun.COM * 218*11225SDana.Myers@Sun.COM * PARAMETERS: Id - The HID/CID in string format 219*11225SDana.Myers@Sun.COM * 220*11225SDana.Myers@Sun.COM * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge 221*11225SDana.Myers@Sun.COM * 222*11225SDana.Myers@Sun.COM * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. 223*11225SDana.Myers@Sun.COM * 224*11225SDana.Myers@Sun.COM ******************************************************************************/ 225*11225SDana.Myers@Sun.COM 226*11225SDana.Myers@Sun.COM BOOLEAN 227*11225SDana.Myers@Sun.COM AcpiUtIsPciRootBridge ( 228*11225SDana.Myers@Sun.COM char *Id) 229*11225SDana.Myers@Sun.COM { 230*11225SDana.Myers@Sun.COM 231*11225SDana.Myers@Sun.COM /* 232*11225SDana.Myers@Sun.COM * Check if this is a PCI root bridge. 233*11225SDana.Myers@Sun.COM * ACPI 3.0+: check for a PCI Express root also. 234*11225SDana.Myers@Sun.COM */ 235*11225SDana.Myers@Sun.COM if (!(ACPI_STRCMP (Id, 236*11225SDana.Myers@Sun.COM PCI_ROOT_HID_STRING)) || 237*11225SDana.Myers@Sun.COM 238*11225SDana.Myers@Sun.COM !(ACPI_STRCMP (Id, 239*11225SDana.Myers@Sun.COM PCI_EXPRESS_ROOT_HID_STRING))) 240*11225SDana.Myers@Sun.COM { 241*11225SDana.Myers@Sun.COM return (TRUE); 242*11225SDana.Myers@Sun.COM } 243*11225SDana.Myers@Sun.COM 244*11225SDana.Myers@Sun.COM return (FALSE); 245*11225SDana.Myers@Sun.COM } 246*11225SDana.Myers@Sun.COM 247*11225SDana.Myers@Sun.COM 248*11225SDana.Myers@Sun.COM /******************************************************************************* 249*11225SDana.Myers@Sun.COM * 2503446Smrj * FUNCTION: AcpiUtIsAmlTable 2513446Smrj * 2523446Smrj * PARAMETERS: Table - An ACPI table 2533446Smrj * 2543446Smrj * RETURN: TRUE if table contains executable AML; FALSE otherwise 2553446Smrj * 2563446Smrj * DESCRIPTION: Check ACPI Signature for a table that contains AML code. 2573446Smrj * Currently, these are DSDT,SSDT,PSDT. All other table types are 2583446Smrj * data tables that do not contain AML code. 2593446Smrj * 2603446Smrj ******************************************************************************/ 2613446Smrj 2623446Smrj BOOLEAN 2633446Smrj AcpiUtIsAmlTable ( 2643446Smrj ACPI_TABLE_HEADER *Table) 2653446Smrj { 2663446Smrj 2673446Smrj /* These are the only tables that contain executable AML */ 2683446Smrj 2697851SDana.Myers@Sun.COM if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) || 2707851SDana.Myers@Sun.COM ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) || 2717851SDana.Myers@Sun.COM ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT)) 2723446Smrj { 2733446Smrj return (TRUE); 2743446Smrj } 2753446Smrj 2763446Smrj return (FALSE); 2773446Smrj } 2783446Smrj 2793446Smrj 2803446Smrj /******************************************************************************* 2813446Smrj * 2823446Smrj * FUNCTION: AcpiUtAllocateOwnerId 2833446Smrj * 2843446Smrj * PARAMETERS: OwnerId - Where the new owner ID is returned 2853446Smrj * 2863446Smrj * RETURN: Status 2873446Smrj * 2883446Smrj * DESCRIPTION: Allocate a table or method owner ID. The owner ID is used to 2893446Smrj * track objects created by the table or method, to be deleted 2903446Smrj * when the method exits or the table is unloaded. 2913446Smrj * 2923446Smrj ******************************************************************************/ 2933446Smrj 2943446Smrj ACPI_STATUS 2953446Smrj AcpiUtAllocateOwnerId ( 2963446Smrj ACPI_OWNER_ID *OwnerId) 2973446Smrj { 2987851SDana.Myers@Sun.COM UINT32 i; 2997851SDana.Myers@Sun.COM UINT32 j; 3007851SDana.Myers@Sun.COM UINT32 k; 3013446Smrj ACPI_STATUS Status; 3023446Smrj 3033446Smrj 3043446Smrj ACPI_FUNCTION_TRACE (UtAllocateOwnerId); 3053446Smrj 3063446Smrj 3073446Smrj /* Guard against multiple allocations of ID to the same location */ 3083446Smrj 3093446Smrj if (*OwnerId) 3103446Smrj { 3113446Smrj ACPI_ERROR ((AE_INFO, "Owner ID [%2.2X] already exists", *OwnerId)); 3123446Smrj return_ACPI_STATUS (AE_ALREADY_EXISTS); 3133446Smrj } 3143446Smrj 3153446Smrj /* Mutex for the global ID mask */ 3163446Smrj 3173446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 3183446Smrj if (ACPI_FAILURE (Status)) 3193446Smrj { 3203446Smrj return_ACPI_STATUS (Status); 3213446Smrj } 3223446Smrj 3233446Smrj /* 3243446Smrj * Find a free owner ID, cycle through all possible IDs on repeated 3253446Smrj * allocations. (ACPI_NUM_OWNERID_MASKS + 1) because first index may have 3263446Smrj * to be scanned twice. 3273446Smrj */ 3283446Smrj for (i = 0, j = AcpiGbl_LastOwnerIdIndex; 3293446Smrj i < (ACPI_NUM_OWNERID_MASKS + 1); 3303446Smrj i++, j++) 3313446Smrj { 3323446Smrj if (j >= ACPI_NUM_OWNERID_MASKS) 3333446Smrj { 3343446Smrj j = 0; /* Wraparound to start of mask array */ 3353446Smrj } 3363446Smrj 3373446Smrj for (k = AcpiGbl_NextOwnerIdOffset; k < 32; k++) 3383446Smrj { 3393446Smrj if (AcpiGbl_OwnerIdMask[j] == ACPI_UINT32_MAX) 3403446Smrj { 3413446Smrj /* There are no free IDs in this mask */ 3423446Smrj 3433446Smrj break; 3443446Smrj } 3453446Smrj 3463446Smrj if (!(AcpiGbl_OwnerIdMask[j] & (1 << k))) 3473446Smrj { 3483446Smrj /* 3493446Smrj * Found a free ID. The actual ID is the bit index plus one, 3503446Smrj * making zero an invalid Owner ID. Save this as the last ID 3513446Smrj * allocated and update the global ID mask. 3523446Smrj */ 3533446Smrj AcpiGbl_OwnerIdMask[j] |= (1 << k); 3543446Smrj 3553446Smrj AcpiGbl_LastOwnerIdIndex = (UINT8) j; 3563446Smrj AcpiGbl_NextOwnerIdOffset = (UINT8) (k + 1); 3573446Smrj 3583446Smrj /* 3593446Smrj * Construct encoded ID from the index and bit position 3603446Smrj * 3613446Smrj * Note: Last [j].k (bit 255) is never used and is marked 3623446Smrj * permanently allocated (prevents +1 overflow) 3633446Smrj */ 3643446Smrj *OwnerId = (ACPI_OWNER_ID) ((k + 1) + ACPI_MUL_32 (j)); 3653446Smrj 3663446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_VALUES, 3673446Smrj "Allocated OwnerId: %2.2X\n", (unsigned int) *OwnerId)); 3683446Smrj goto Exit; 3693446Smrj } 3703446Smrj } 3713446Smrj 3723446Smrj AcpiGbl_NextOwnerIdOffset = 0; 3733446Smrj } 3743446Smrj 3753446Smrj /* 3763446Smrj * All OwnerIds have been allocated. This typically should 3773446Smrj * not happen since the IDs are reused after deallocation. The IDs are 3783446Smrj * allocated upon table load (one per table) and method execution, and 3793446Smrj * they are released when a table is unloaded or a method completes 3803446Smrj * execution. 3813446Smrj * 3823446Smrj * If this error happens, there may be very deep nesting of invoked control 3833446Smrj * methods, or there may be a bug where the IDs are not released. 3843446Smrj */ 3853446Smrj Status = AE_OWNER_ID_LIMIT; 3863446Smrj ACPI_ERROR ((AE_INFO, 3873446Smrj "Could not allocate new OwnerId (255 max), AE_OWNER_ID_LIMIT")); 3883446Smrj 3893446Smrj Exit: 3903446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 3913446Smrj return_ACPI_STATUS (Status); 3923446Smrj } 3933446Smrj 3943446Smrj 3953446Smrj /******************************************************************************* 3963446Smrj * 3973446Smrj * FUNCTION: AcpiUtReleaseOwnerId 3983446Smrj * 3993446Smrj * PARAMETERS: OwnerIdPtr - Pointer to a previously allocated OwnerID 4003446Smrj * 4013446Smrj * RETURN: None. No error is returned because we are either exiting a 4023446Smrj * control method or unloading a table. Either way, we would 4033446Smrj * ignore any error anyway. 4043446Smrj * 4053446Smrj * DESCRIPTION: Release a table or method owner ID. Valid IDs are 1 - 255 4063446Smrj * 4073446Smrj ******************************************************************************/ 4083446Smrj 4093446Smrj void 4103446Smrj AcpiUtReleaseOwnerId ( 4113446Smrj ACPI_OWNER_ID *OwnerIdPtr) 4123446Smrj { 4133446Smrj ACPI_OWNER_ID OwnerId = *OwnerIdPtr; 4143446Smrj ACPI_STATUS Status; 4157851SDana.Myers@Sun.COM UINT32 Index; 4163446Smrj UINT32 Bit; 4173446Smrj 4183446Smrj 4193446Smrj ACPI_FUNCTION_TRACE_U32 (UtReleaseOwnerId, OwnerId); 4203446Smrj 4213446Smrj 4223446Smrj /* Always clear the input OwnerId (zero is an invalid ID) */ 4233446Smrj 4243446Smrj *OwnerIdPtr = 0; 4253446Smrj 4263446Smrj /* Zero is not a valid OwnerID */ 4273446Smrj 4283446Smrj if (OwnerId == 0) 4293446Smrj { 4303446Smrj ACPI_ERROR ((AE_INFO, "Invalid OwnerId: %2.2X", OwnerId)); 4313446Smrj return_VOID; 4323446Smrj } 4333446Smrj 4343446Smrj /* Mutex for the global ID mask */ 4353446Smrj 4363446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES); 4373446Smrj if (ACPI_FAILURE (Status)) 4383446Smrj { 4393446Smrj return_VOID; 4403446Smrj } 4413446Smrj 4423446Smrj /* Normalize the ID to zero */ 4433446Smrj 4443446Smrj OwnerId--; 4453446Smrj 4463446Smrj /* Decode ID to index/offset pair */ 4473446Smrj 4483446Smrj Index = ACPI_DIV_32 (OwnerId); 4493446Smrj Bit = 1 << ACPI_MOD_32 (OwnerId); 4503446Smrj 4513446Smrj /* Free the owner ID only if it is valid */ 4523446Smrj 4533446Smrj if (AcpiGbl_OwnerIdMask[Index] & Bit) 4543446Smrj { 4553446Smrj AcpiGbl_OwnerIdMask[Index] ^= Bit; 4563446Smrj } 4573446Smrj else 4583446Smrj { 4593446Smrj ACPI_ERROR ((AE_INFO, 4603446Smrj "Release of non-allocated OwnerId: %2.2X", OwnerId + 1)); 4613446Smrj } 4623446Smrj 4633446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_CACHES); 4643446Smrj return_VOID; 4653446Smrj } 4663446Smrj 4673446Smrj 4683446Smrj /******************************************************************************* 4693446Smrj * 4703446Smrj * FUNCTION: AcpiUtStrupr (strupr) 4713446Smrj * 4723446Smrj * PARAMETERS: SrcString - The source string to convert 4733446Smrj * 4743446Smrj * RETURN: None 4753446Smrj * 4763446Smrj * DESCRIPTION: Convert string to uppercase 4773446Smrj * 4783446Smrj * NOTE: This is not a POSIX function, so it appears here, not in utclib.c 4793446Smrj * 4803446Smrj ******************************************************************************/ 4813446Smrj 4823446Smrj void 4833446Smrj AcpiUtStrupr ( 4843446Smrj char *SrcString) 4853446Smrj { 4863446Smrj char *String; 4873446Smrj 4883446Smrj 4893446Smrj ACPI_FUNCTION_ENTRY (); 4903446Smrj 4913446Smrj 4923446Smrj if (!SrcString) 4933446Smrj { 4943446Smrj return; 4953446Smrj } 4963446Smrj 4973446Smrj /* Walk entire string, uppercasing the letters */ 4983446Smrj 4993446Smrj for (String = SrcString; *String; String++) 5003446Smrj { 5013446Smrj *String = (char) ACPI_TOUPPER (*String); 5023446Smrj } 5033446Smrj 5043446Smrj return; 5053446Smrj } 5063446Smrj 5073446Smrj 5083446Smrj /******************************************************************************* 5093446Smrj * 5103446Smrj * FUNCTION: AcpiUtPrintString 5113446Smrj * 5123446Smrj * PARAMETERS: String - Null terminated ASCII string 5133446Smrj * MaxLength - Maximum output length 5143446Smrj * 5153446Smrj * RETURN: None 5163446Smrj * 5173446Smrj * DESCRIPTION: Dump an ASCII string with support for ACPI-defined escape 5183446Smrj * sequences. 5193446Smrj * 5203446Smrj ******************************************************************************/ 5213446Smrj 5223446Smrj void 5233446Smrj AcpiUtPrintString ( 5243446Smrj char *String, 5253446Smrj UINT8 MaxLength) 5263446Smrj { 5273446Smrj UINT32 i; 5283446Smrj 5293446Smrj 5303446Smrj if (!String) 5313446Smrj { 5323446Smrj AcpiOsPrintf ("<\"NULL STRING PTR\">"); 5333446Smrj return; 5343446Smrj } 5353446Smrj 5363446Smrj AcpiOsPrintf ("\""); 5373446Smrj for (i = 0; String[i] && (i < MaxLength); i++) 5383446Smrj { 5393446Smrj /* Escape sequences */ 5403446Smrj 5413446Smrj switch (String[i]) 5423446Smrj { 5433446Smrj case 0x07: 5443446Smrj AcpiOsPrintf ("\\a"); /* BELL */ 5453446Smrj break; 5463446Smrj 5473446Smrj case 0x08: 5483446Smrj AcpiOsPrintf ("\\b"); /* BACKSPACE */ 5493446Smrj break; 5503446Smrj 5513446Smrj case 0x0C: 5523446Smrj AcpiOsPrintf ("\\f"); /* FORMFEED */ 5533446Smrj break; 5543446Smrj 5553446Smrj case 0x0A: 5563446Smrj AcpiOsPrintf ("\\n"); /* LINEFEED */ 5573446Smrj break; 5583446Smrj 5593446Smrj case 0x0D: 5603446Smrj AcpiOsPrintf ("\\r"); /* CARRIAGE RETURN*/ 5613446Smrj break; 5623446Smrj 5633446Smrj case 0x09: 5643446Smrj AcpiOsPrintf ("\\t"); /* HORIZONTAL TAB */ 5653446Smrj break; 5663446Smrj 5673446Smrj case 0x0B: 5683446Smrj AcpiOsPrintf ("\\v"); /* VERTICAL TAB */ 5693446Smrj break; 5703446Smrj 5713446Smrj case '\'': /* Single Quote */ 5723446Smrj case '\"': /* Double Quote */ 5733446Smrj case '\\': /* Backslash */ 5743446Smrj AcpiOsPrintf ("\\%c", (int) String[i]); 5753446Smrj break; 5763446Smrj 5773446Smrj default: 5783446Smrj 5793446Smrj /* Check for printable character or hex escape */ 5803446Smrj 5813446Smrj if (ACPI_IS_PRINT (String[i])) 5823446Smrj { 5833446Smrj /* This is a normal character */ 5843446Smrj 5853446Smrj AcpiOsPrintf ("%c", (int) String[i]); 5863446Smrj } 5873446Smrj else 5883446Smrj { 5893446Smrj /* All others will be Hex escapes */ 5903446Smrj 5913446Smrj AcpiOsPrintf ("\\x%2.2X", (INT32) String[i]); 5923446Smrj } 5933446Smrj break; 5943446Smrj } 5953446Smrj } 5963446Smrj AcpiOsPrintf ("\""); 5973446Smrj 5983446Smrj if (i == MaxLength && String[i]) 5993446Smrj { 6003446Smrj AcpiOsPrintf ("..."); 6013446Smrj } 6023446Smrj } 6033446Smrj 6043446Smrj 6053446Smrj /******************************************************************************* 6063446Smrj * 6073446Smrj * FUNCTION: AcpiUtDwordByteSwap 6083446Smrj * 6093446Smrj * PARAMETERS: Value - Value to be converted 6103446Smrj * 6113446Smrj * RETURN: UINT32 integer with bytes swapped 6123446Smrj * 6133446Smrj * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes) 6143446Smrj * 6153446Smrj ******************************************************************************/ 6163446Smrj 6173446Smrj UINT32 6183446Smrj AcpiUtDwordByteSwap ( 6193446Smrj UINT32 Value) 6203446Smrj { 6213446Smrj union 6223446Smrj { 6233446Smrj UINT32 Value; 6243446Smrj UINT8 Bytes[4]; 6253446Smrj } Out; 6263446Smrj union 6273446Smrj { 6283446Smrj UINT32 Value; 6293446Smrj UINT8 Bytes[4]; 6303446Smrj } In; 6313446Smrj 6323446Smrj 6333446Smrj ACPI_FUNCTION_ENTRY (); 6343446Smrj 6353446Smrj 6363446Smrj In.Value = Value; 6373446Smrj 6383446Smrj Out.Bytes[0] = In.Bytes[3]; 6393446Smrj Out.Bytes[1] = In.Bytes[2]; 6403446Smrj Out.Bytes[2] = In.Bytes[1]; 6413446Smrj Out.Bytes[3] = In.Bytes[0]; 6423446Smrj 6433446Smrj return (Out.Value); 6443446Smrj } 6453446Smrj 6463446Smrj 6473446Smrj /******************************************************************************* 6483446Smrj * 6493446Smrj * FUNCTION: AcpiUtSetIntegerWidth 6503446Smrj * 6513446Smrj * PARAMETERS: Revision From DSDT header 6523446Smrj * 6533446Smrj * RETURN: None 6543446Smrj * 6553446Smrj * DESCRIPTION: Set the global integer bit width based upon the revision 6563446Smrj * of the DSDT. For Revision 1 and 0, Integers are 32 bits. 6573446Smrj * For Revision 2 and above, Integers are 64 bits. Yes, this 6583446Smrj * makes a difference. 6593446Smrj * 6603446Smrj ******************************************************************************/ 6613446Smrj 6623446Smrj void 6633446Smrj AcpiUtSetIntegerWidth ( 6643446Smrj UINT8 Revision) 6653446Smrj { 6663446Smrj 6677851SDana.Myers@Sun.COM if (Revision < 2) 6683446Smrj { 6693446Smrj /* 32-bit case */ 6703446Smrj 6713446Smrj AcpiGbl_IntegerBitWidth = 32; 6723446Smrj AcpiGbl_IntegerNybbleWidth = 8; 6733446Smrj AcpiGbl_IntegerByteWidth = 4; 6743446Smrj } 6753446Smrj else 6763446Smrj { 6773446Smrj /* 64-bit case (ACPI 2.0+) */ 6783446Smrj 6793446Smrj AcpiGbl_IntegerBitWidth = 64; 6803446Smrj AcpiGbl_IntegerNybbleWidth = 16; 6813446Smrj AcpiGbl_IntegerByteWidth = 8; 6823446Smrj } 6833446Smrj } 6843446Smrj 6853446Smrj 6863446Smrj #ifdef ACPI_DEBUG_OUTPUT 6873446Smrj /******************************************************************************* 6883446Smrj * 6893446Smrj * FUNCTION: AcpiUtDisplayInitPathname 6903446Smrj * 6913446Smrj * PARAMETERS: Type - Object type of the node 6923446Smrj * ObjHandle - Handle whose pathname will be displayed 6933446Smrj * Path - Additional path string to be appended. 6943446Smrj * (NULL if no extra path) 6953446Smrj * 6963446Smrj * RETURN: ACPI_STATUS 6973446Smrj * 6983446Smrj * DESCRIPTION: Display full pathname of an object, DEBUG ONLY 6993446Smrj * 7003446Smrj ******************************************************************************/ 7013446Smrj 7023446Smrj void 7033446Smrj AcpiUtDisplayInitPathname ( 7043446Smrj UINT8 Type, 7053446Smrj ACPI_NAMESPACE_NODE *ObjHandle, 7063446Smrj char *Path) 7073446Smrj { 7083446Smrj ACPI_STATUS Status; 7093446Smrj ACPI_BUFFER Buffer; 7103446Smrj 7113446Smrj 7123446Smrj ACPI_FUNCTION_ENTRY (); 7133446Smrj 7143446Smrj 7153446Smrj /* Only print the path if the appropriate debug level is enabled */ 7163446Smrj 7173446Smrj if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES)) 7183446Smrj { 7193446Smrj return; 7203446Smrj } 7213446Smrj 7223446Smrj /* Get the full pathname to the node */ 7233446Smrj 7243446Smrj Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 7253446Smrj Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 7263446Smrj if (ACPI_FAILURE (Status)) 7273446Smrj { 7283446Smrj return; 7293446Smrj } 7303446Smrj 7313446Smrj /* Print what we're doing */ 7323446Smrj 7333446Smrj switch (Type) 7343446Smrj { 7353446Smrj case ACPI_TYPE_METHOD: 7363446Smrj AcpiOsPrintf ("Executing "); 7373446Smrj break; 7383446Smrj 7393446Smrj default: 7403446Smrj AcpiOsPrintf ("Initializing "); 7413446Smrj break; 7423446Smrj } 7433446Smrj 7443446Smrj /* Print the object type and pathname */ 7453446Smrj 7463446Smrj AcpiOsPrintf ("%-12s %s", 7473446Smrj AcpiUtGetTypeName (Type), (char *) Buffer.Pointer); 7483446Smrj 7493446Smrj /* Extra path is used to append names like _STA, _INI, etc. */ 7503446Smrj 7513446Smrj if (Path) 7523446Smrj { 7533446Smrj AcpiOsPrintf (".%s", Path); 7543446Smrj } 7553446Smrj AcpiOsPrintf ("\n"); 7563446Smrj 7573446Smrj ACPI_FREE (Buffer.Pointer); 7583446Smrj } 7593446Smrj #endif 7603446Smrj 7613446Smrj 7623446Smrj /******************************************************************************* 7633446Smrj * 7643446Smrj * FUNCTION: AcpiUtValidAcpiChar 7653446Smrj * 7663446Smrj * PARAMETERS: Char - The character to be examined 7673446Smrj * Position - Byte position (0-3) 7683446Smrj * 7693446Smrj * RETURN: TRUE if the character is valid, FALSE otherwise 7703446Smrj * 7713446Smrj * DESCRIPTION: Check for a valid ACPI character. Must be one of: 7723446Smrj * 1) Upper case alpha 7733446Smrj * 2) numeric 7743446Smrj * 3) underscore 7753446Smrj * 7763446Smrj * We allow a '!' as the last character because of the ASF! table 7773446Smrj * 7783446Smrj ******************************************************************************/ 7793446Smrj 7803446Smrj BOOLEAN 7813446Smrj AcpiUtValidAcpiChar ( 7823446Smrj char Character, 7837851SDana.Myers@Sun.COM UINT32 Position) 7843446Smrj { 7853446Smrj 7863446Smrj if (!((Character >= 'A' && Character <= 'Z') || 7873446Smrj (Character >= '0' && Character <= '9') || 7883446Smrj (Character == '_'))) 7893446Smrj { 7903446Smrj /* Allow a '!' in the last position */ 7913446Smrj 7923446Smrj if (Character == '!' && Position == 3) 7933446Smrj { 7943446Smrj return (TRUE); 7953446Smrj } 7963446Smrj 7973446Smrj return (FALSE); 7983446Smrj } 7993446Smrj 8003446Smrj return (TRUE); 8013446Smrj } 8023446Smrj 8033446Smrj 8043446Smrj /******************************************************************************* 8053446Smrj * 8063446Smrj * FUNCTION: AcpiUtValidAcpiName 8073446Smrj * 8083446Smrj * PARAMETERS: Name - The name to be examined 8093446Smrj * 8103446Smrj * RETURN: TRUE if the name is valid, FALSE otherwise 8113446Smrj * 8123446Smrj * DESCRIPTION: Check for a valid ACPI name. Each character must be one of: 8133446Smrj * 1) Upper case alpha 8143446Smrj * 2) numeric 8153446Smrj * 3) underscore 8163446Smrj * 8173446Smrj ******************************************************************************/ 8183446Smrj 8193446Smrj BOOLEAN 8203446Smrj AcpiUtValidAcpiName ( 8213446Smrj UINT32 Name) 8223446Smrj { 8237851SDana.Myers@Sun.COM UINT32 i; 8243446Smrj 8253446Smrj 8263446Smrj ACPI_FUNCTION_ENTRY (); 8273446Smrj 8283446Smrj 8293446Smrj for (i = 0; i < ACPI_NAME_SIZE; i++) 8303446Smrj { 8313446Smrj if (!AcpiUtValidAcpiChar ((ACPI_CAST_PTR (char, &Name))[i], i)) 8323446Smrj { 8333446Smrj return (FALSE); 8343446Smrj } 8353446Smrj } 8363446Smrj 8373446Smrj return (TRUE); 8383446Smrj } 8393446Smrj 8403446Smrj 8413446Smrj /******************************************************************************* 8423446Smrj * 8433446Smrj * FUNCTION: AcpiUtRepairName 8443446Smrj * 8453446Smrj * PARAMETERS: Name - The ACPI name to be repaired 8463446Smrj * 8473446Smrj * RETURN: Repaired version of the name 8483446Smrj * 8493446Smrj * DESCRIPTION: Repair an ACPI name: Change invalid characters to '*' and 8507851SDana.Myers@Sun.COM * return the new name. NOTE: the Name parameter must reside in 8517851SDana.Myers@Sun.COM * read/write memory, cannot be a const. 8527851SDana.Myers@Sun.COM * 8537851SDana.Myers@Sun.COM * An ACPI Name must consist of valid ACPI characters. We will repair the name 8547851SDana.Myers@Sun.COM * if necessary because we don't want to abort because of this, but we want 8557851SDana.Myers@Sun.COM * all namespace names to be printable. A warning message is appropriate. 8567851SDana.Myers@Sun.COM * 8577851SDana.Myers@Sun.COM * This issue came up because there are in fact machines that exhibit 8587851SDana.Myers@Sun.COM * this problem, and we want to be able to enable ACPI support for them, 8597851SDana.Myers@Sun.COM * even though there are a few bad names. 8603446Smrj * 8613446Smrj ******************************************************************************/ 8623446Smrj 8637851SDana.Myers@Sun.COM void 8643446Smrj AcpiUtRepairName ( 8657851SDana.Myers@Sun.COM char *Name) 8663446Smrj { 8677851SDana.Myers@Sun.COM UINT32 i; 8687851SDana.Myers@Sun.COM BOOLEAN FoundBadChar = FALSE; 8697851SDana.Myers@Sun.COM 8703446Smrj 8717851SDana.Myers@Sun.COM ACPI_FUNCTION_NAME (UtRepairName); 8727851SDana.Myers@Sun.COM 8737851SDana.Myers@Sun.COM 8747851SDana.Myers@Sun.COM /* Check each character in the name */ 8753446Smrj 8763446Smrj for (i = 0; i < ACPI_NAME_SIZE; i++) 8773446Smrj { 8787851SDana.Myers@Sun.COM if (AcpiUtValidAcpiChar (Name[i], i)) 8797851SDana.Myers@Sun.COM { 8807851SDana.Myers@Sun.COM continue; 8817851SDana.Myers@Sun.COM } 8823446Smrj 8833446Smrj /* 8843446Smrj * Replace a bad character with something printable, yet technically 8853446Smrj * still invalid. This prevents any collisions with existing "good" 8863446Smrj * names in the namespace. 8873446Smrj */ 8887851SDana.Myers@Sun.COM Name[i] = '*'; 8897851SDana.Myers@Sun.COM FoundBadChar = TRUE; 8907851SDana.Myers@Sun.COM } 8917851SDana.Myers@Sun.COM 8927851SDana.Myers@Sun.COM if (FoundBadChar) 8937851SDana.Myers@Sun.COM { 8947851SDana.Myers@Sun.COM /* Report warning only if in strict mode or debug mode */ 8957851SDana.Myers@Sun.COM 8967851SDana.Myers@Sun.COM if (!AcpiGbl_EnableInterpreterSlack) 8973446Smrj { 8987851SDana.Myers@Sun.COM ACPI_WARNING ((AE_INFO, 8997851SDana.Myers@Sun.COM "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 9007851SDana.Myers@Sun.COM } 9017851SDana.Myers@Sun.COM else 9027851SDana.Myers@Sun.COM { 9037851SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 9047851SDana.Myers@Sun.COM "Found bad character(s) in name, repaired: [%4.4s]\n", Name)); 9053446Smrj } 9063446Smrj } 9073446Smrj } 9083446Smrj 9093446Smrj 9103446Smrj /******************************************************************************* 9113446Smrj * 9123446Smrj * FUNCTION: AcpiUtStrtoul64 9133446Smrj * 9143446Smrj * PARAMETERS: String - Null terminated string 9153446Smrj * Base - Radix of the string: 16 or ACPI_ANY_BASE; 9163446Smrj * ACPI_ANY_BASE means 'in behalf of ToInteger' 9173446Smrj * RetInteger - Where the converted integer is returned 9183446Smrj * 9193446Smrj * RETURN: Status and Converted value 9203446Smrj * 9213446Smrj * DESCRIPTION: Convert a string into an unsigned value. Performs either a 9223446Smrj * 32-bit or 64-bit conversion, depending on the current mode 9233446Smrj * of the interpreter. 9243446Smrj * NOTE: Does not support Octal strings, not needed. 9253446Smrj * 9263446Smrj ******************************************************************************/ 9273446Smrj 9283446Smrj ACPI_STATUS 9293446Smrj AcpiUtStrtoul64 ( 9303446Smrj char *String, 9313446Smrj UINT32 Base, 9323446Smrj ACPI_INTEGER *RetInteger) 9333446Smrj { 9343446Smrj UINT32 ThisDigit = 0; 9353446Smrj ACPI_INTEGER ReturnValue = 0; 9363446Smrj ACPI_INTEGER Quotient; 9373446Smrj ACPI_INTEGER Dividend; 9383446Smrj UINT32 ToIntegerOp = (Base == ACPI_ANY_BASE); 9393446Smrj UINT32 Mode32 = (AcpiGbl_IntegerByteWidth == 4); 9403446Smrj UINT8 ValidDigits = 0; 9413446Smrj UINT8 SignOf0x = 0; 9423446Smrj UINT8 Term = 0; 9433446Smrj 9443446Smrj 9453446Smrj ACPI_FUNCTION_TRACE_STR (UtStroul64, String); 9463446Smrj 9473446Smrj 9483446Smrj switch (Base) 9493446Smrj { 9503446Smrj case ACPI_ANY_BASE: 9513446Smrj case 16: 9523446Smrj break; 9533446Smrj 9543446Smrj default: 9553446Smrj /* Invalid Base */ 9563446Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 9573446Smrj } 9583446Smrj 9593446Smrj if (!String) 9603446Smrj { 9613446Smrj goto ErrorExit; 9623446Smrj } 9633446Smrj 9643446Smrj /* Skip over any white space in the buffer */ 9653446Smrj 9663446Smrj while ((*String) && (ACPI_IS_SPACE (*String) || *String == '\t')) 9673446Smrj { 9683446Smrj String++; 9693446Smrj } 9703446Smrj 9713446Smrj if (ToIntegerOp) 9723446Smrj { 9733446Smrj /* 9743446Smrj * Base equal to ACPI_ANY_BASE means 'ToInteger operation case'. 9753446Smrj * We need to determine if it is decimal or hexadecimal. 9763446Smrj */ 9773446Smrj if ((*String == '0') && (ACPI_TOLOWER (*(String + 1)) == 'x')) 9783446Smrj { 9793446Smrj SignOf0x = 1; 9803446Smrj Base = 16; 9813446Smrj 9823446Smrj /* Skip over the leading '0x' */ 9833446Smrj String += 2; 9843446Smrj } 9853446Smrj else 9863446Smrj { 9873446Smrj Base = 10; 9883446Smrj } 9893446Smrj } 9903446Smrj 9913446Smrj /* Any string left? Check that '0x' is not followed by white space. */ 9923446Smrj 9933446Smrj if (!(*String) || ACPI_IS_SPACE (*String) || *String == '\t') 9943446Smrj { 9953446Smrj if (ToIntegerOp) 9963446Smrj { 9973446Smrj goto ErrorExit; 9983446Smrj } 9993446Smrj else 10003446Smrj { 10013446Smrj goto AllDone; 10023446Smrj } 10033446Smrj } 10043446Smrj 10053446Smrj /* 10063446Smrj * Perform a 32-bit or 64-bit conversion, depending upon the current 10073446Smrj * execution mode of the interpreter 10083446Smrj */ 10093446Smrj Dividend = (Mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX; 10103446Smrj 10113446Smrj /* Main loop: convert the string to a 32- or 64-bit integer */ 10123446Smrj 10133446Smrj while (*String) 10143446Smrj { 10153446Smrj if (ACPI_IS_DIGIT (*String)) 10163446Smrj { 10173446Smrj /* Convert ASCII 0-9 to Decimal value */ 10183446Smrj 10193446Smrj ThisDigit = ((UINT8) *String) - '0'; 10203446Smrj } 10213446Smrj else if (Base == 10) 10223446Smrj { 10233446Smrj /* Digit is out of range; possible in ToInteger case only */ 10243446Smrj 10253446Smrj Term = 1; 10263446Smrj } 10273446Smrj else 10283446Smrj { 10293446Smrj ThisDigit = (UINT8) ACPI_TOUPPER (*String); 10303446Smrj if (ACPI_IS_XDIGIT ((char) ThisDigit)) 10313446Smrj { 10323446Smrj /* Convert ASCII Hex char to value */ 10333446Smrj 10343446Smrj ThisDigit = ThisDigit - 'A' + 10; 10353446Smrj } 10363446Smrj else 10373446Smrj { 10383446Smrj Term = 1; 10393446Smrj } 10403446Smrj } 10413446Smrj 10423446Smrj if (Term) 10433446Smrj { 10443446Smrj if (ToIntegerOp) 10453446Smrj { 10463446Smrj goto ErrorExit; 10473446Smrj } 10483446Smrj else 10493446Smrj { 10503446Smrj break; 10513446Smrj } 10523446Smrj } 10533446Smrj else if ((ValidDigits == 0) && (ThisDigit == 0) && !SignOf0x) 10543446Smrj { 10553446Smrj /* Skip zeros */ 10563446Smrj String++; 10573446Smrj continue; 10583446Smrj } 10593446Smrj 10603446Smrj ValidDigits++; 10613446Smrj 10623446Smrj if (SignOf0x && ((ValidDigits > 16) || ((ValidDigits > 8) && Mode32))) 10633446Smrj { 10643446Smrj /* 10653446Smrj * This is ToInteger operation case. 10663446Smrj * No any restrictions for string-to-integer conversion, 10673446Smrj * see ACPI spec. 10683446Smrj */ 10693446Smrj goto ErrorExit; 10703446Smrj } 10713446Smrj 10723446Smrj /* Divide the digit into the correct position */ 10733446Smrj 10743446Smrj (void) AcpiUtShortDivide ((Dividend - (ACPI_INTEGER) ThisDigit), 10753446Smrj Base, &Quotient, NULL); 10763446Smrj 10773446Smrj if (ReturnValue > Quotient) 10783446Smrj { 10793446Smrj if (ToIntegerOp) 10803446Smrj { 10813446Smrj goto ErrorExit; 10823446Smrj } 10833446Smrj else 10843446Smrj { 10853446Smrj break; 10863446Smrj } 10873446Smrj } 10883446Smrj 10893446Smrj ReturnValue *= Base; 10903446Smrj ReturnValue += ThisDigit; 10913446Smrj String++; 10923446Smrj } 10933446Smrj 10943446Smrj /* All done, normal exit */ 10953446Smrj 10963446Smrj AllDone: 10973446Smrj 10983446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n", 10993446Smrj ACPI_FORMAT_UINT64 (ReturnValue))); 11003446Smrj 11013446Smrj *RetInteger = ReturnValue; 11023446Smrj return_ACPI_STATUS (AE_OK); 11033446Smrj 11043446Smrj 11053446Smrj ErrorExit: 11063446Smrj /* Base was set/validated above */ 11073446Smrj 11083446Smrj if (Base == 10) 11093446Smrj { 11103446Smrj return_ACPI_STATUS (AE_BAD_DECIMAL_CONSTANT); 11113446Smrj } 11123446Smrj else 11133446Smrj { 11143446Smrj return_ACPI_STATUS (AE_BAD_HEX_CONSTANT); 11153446Smrj } 11163446Smrj } 11173446Smrj 11183446Smrj 11193446Smrj /******************************************************************************* 11203446Smrj * 11213446Smrj * FUNCTION: AcpiUtCreateUpdateStateAndPush 11223446Smrj * 11233446Smrj * PARAMETERS: Object - Object to be added to the new state 11243446Smrj * Action - Increment/Decrement 11253446Smrj * StateList - List the state will be added to 11263446Smrj * 11273446Smrj * RETURN: Status 11283446Smrj * 11293446Smrj * DESCRIPTION: Create a new state and push it 11303446Smrj * 11313446Smrj ******************************************************************************/ 11323446Smrj 11333446Smrj ACPI_STATUS 11343446Smrj AcpiUtCreateUpdateStateAndPush ( 11353446Smrj ACPI_OPERAND_OBJECT *Object, 11363446Smrj UINT16 Action, 11373446Smrj ACPI_GENERIC_STATE **StateList) 11383446Smrj { 11393446Smrj ACPI_GENERIC_STATE *State; 11403446Smrj 11413446Smrj 11423446Smrj ACPI_FUNCTION_ENTRY (); 11433446Smrj 11443446Smrj 11453446Smrj /* Ignore null objects; these are expected */ 11463446Smrj 11473446Smrj if (!Object) 11483446Smrj { 11493446Smrj return (AE_OK); 11503446Smrj } 11513446Smrj 11523446Smrj State = AcpiUtCreateUpdateState (Object, Action); 11533446Smrj if (!State) 11543446Smrj { 11553446Smrj return (AE_NO_MEMORY); 11563446Smrj } 11573446Smrj 11583446Smrj AcpiUtPushGenericState (StateList, State); 11593446Smrj return (AE_OK); 11603446Smrj } 11613446Smrj 11623446Smrj 11633446Smrj /******************************************************************************* 11643446Smrj * 11653446Smrj * FUNCTION: AcpiUtWalkPackageTree 11663446Smrj * 11673446Smrj * PARAMETERS: SourceObject - The package to walk 11683446Smrj * TargetObject - Target object (if package is being copied) 11693446Smrj * WalkCallback - Called once for each package element 11703446Smrj * Context - Passed to the callback function 11713446Smrj * 11723446Smrj * RETURN: Status 11733446Smrj * 11743446Smrj * DESCRIPTION: Walk through a package 11753446Smrj * 11763446Smrj ******************************************************************************/ 11773446Smrj 11783446Smrj ACPI_STATUS 11793446Smrj AcpiUtWalkPackageTree ( 11803446Smrj ACPI_OPERAND_OBJECT *SourceObject, 11813446Smrj void *TargetObject, 11823446Smrj ACPI_PKG_CALLBACK WalkCallback, 11833446Smrj void *Context) 11843446Smrj { 11853446Smrj ACPI_STATUS Status = AE_OK; 11863446Smrj ACPI_GENERIC_STATE *StateList = NULL; 11873446Smrj ACPI_GENERIC_STATE *State; 11883446Smrj UINT32 ThisIndex; 11893446Smrj ACPI_OPERAND_OBJECT *ThisSourceObj; 11903446Smrj 11913446Smrj 11923446Smrj ACPI_FUNCTION_TRACE (UtWalkPackageTree); 11933446Smrj 11943446Smrj 11953446Smrj State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0); 11963446Smrj if (!State) 11973446Smrj { 11983446Smrj return_ACPI_STATUS (AE_NO_MEMORY); 11993446Smrj } 12003446Smrj 12013446Smrj while (State) 12023446Smrj { 12033446Smrj /* Get one element of the package */ 12043446Smrj 12053446Smrj ThisIndex = State->Pkg.Index; 12063446Smrj ThisSourceObj = (ACPI_OPERAND_OBJECT *) 12073446Smrj State->Pkg.SourceObject->Package.Elements[ThisIndex]; 12083446Smrj 12093446Smrj /* 12103446Smrj * Check for: 12113446Smrj * 1) An uninitialized package element. It is completely 12123446Smrj * legal to declare a package and leave it uninitialized 12133446Smrj * 2) Not an internal object - can be a namespace node instead 12143446Smrj * 3) Any type other than a package. Packages are handled in else 12153446Smrj * case below. 12163446Smrj */ 12173446Smrj if ((!ThisSourceObj) || 12183446Smrj (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) || 12199980SDana.Myers@Sun.COM (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE)) 12203446Smrj { 12213446Smrj Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj, 12223446Smrj State, Context); 12233446Smrj if (ACPI_FAILURE (Status)) 12243446Smrj { 12253446Smrj return_ACPI_STATUS (Status); 12263446Smrj } 12273446Smrj 12283446Smrj State->Pkg.Index++; 12293446Smrj while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count) 12303446Smrj { 12313446Smrj /* 12323446Smrj * We've handled all of the objects at this level, This means 12333446Smrj * that we have just completed a package. That package may 12343446Smrj * have contained one or more packages itself. 12353446Smrj * 12363446Smrj * Delete this state and pop the previous state (package). 12373446Smrj */ 12383446Smrj AcpiUtDeleteGenericState (State); 12393446Smrj State = AcpiUtPopGenericState (&StateList); 12403446Smrj 12413446Smrj /* Finished when there are no more states */ 12423446Smrj 12433446Smrj if (!State) 12443446Smrj { 12453446Smrj /* 12463446Smrj * We have handled all of the objects in the top level 12473446Smrj * package just add the length of the package objects 12483446Smrj * and exit 12493446Smrj */ 12503446Smrj return_ACPI_STATUS (AE_OK); 12513446Smrj } 12523446Smrj 12533446Smrj /* 12543446Smrj * Go back up a level and move the index past the just 12553446Smrj * completed package object. 12563446Smrj */ 12573446Smrj State->Pkg.Index++; 12583446Smrj } 12593446Smrj } 12603446Smrj else 12613446Smrj { 12623446Smrj /* This is a subobject of type package */ 12633446Smrj 12643446Smrj Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj, 12653446Smrj State, Context); 12663446Smrj if (ACPI_FAILURE (Status)) 12673446Smrj { 12683446Smrj return_ACPI_STATUS (Status); 12693446Smrj } 12703446Smrj 12713446Smrj /* 12723446Smrj * Push the current state and create a new one 12733446Smrj * The callback above returned a new target package object. 12743446Smrj */ 12753446Smrj AcpiUtPushGenericState (&StateList, State); 12763446Smrj State = AcpiUtCreatePkgState (ThisSourceObj, 12773446Smrj State->Pkg.ThisTargetObj, 0); 12783446Smrj if (!State) 12793446Smrj { 12809980SDana.Myers@Sun.COM /* Free any stacked Update State objects */ 12819980SDana.Myers@Sun.COM 12829980SDana.Myers@Sun.COM while (StateList) 12839980SDana.Myers@Sun.COM { 12849980SDana.Myers@Sun.COM State = AcpiUtPopGenericState (&StateList); 12859980SDana.Myers@Sun.COM AcpiUtDeleteGenericState (State); 12869980SDana.Myers@Sun.COM } 12873446Smrj return_ACPI_STATUS (AE_NO_MEMORY); 12883446Smrj } 12893446Smrj } 12903446Smrj } 12913446Smrj 12923446Smrj /* We should never get here */ 12933446Smrj 12943446Smrj return_ACPI_STATUS (AE_AML_INTERNAL); 12953446Smrj } 12963446Smrj 12973446Smrj 12983446Smrj /******************************************************************************* 12993446Smrj * 13009980SDana.Myers@Sun.COM * FUNCTION: AcpiError, AcpiException, AcpiWarning, AcpiInfo 13013446Smrj * 13023446Smrj * PARAMETERS: ModuleName - Caller's module name (for error output) 13033446Smrj * LineNumber - Caller's line number (for error output) 13043446Smrj * Format - Printf format string + additional args 13053446Smrj * 13063446Smrj * RETURN: None 13073446Smrj * 13083446Smrj * DESCRIPTION: Print message with module/line/version info 13093446Smrj * 13103446Smrj ******************************************************************************/ 13113446Smrj 13123446Smrj void ACPI_INTERNAL_VAR_XFACE 13139980SDana.Myers@Sun.COM AcpiError ( 13147851SDana.Myers@Sun.COM const char *ModuleName, 13153446Smrj UINT32 LineNumber, 13167851SDana.Myers@Sun.COM const char *Format, 13173446Smrj ...) 13183446Smrj { 13193446Smrj va_list args; 13203446Smrj 13213446Smrj 13229980SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI Error: "); 13233446Smrj 13243446Smrj va_start (args, Format); 13253446Smrj AcpiOsVprintf (Format, args); 1326*11225SDana.Myers@Sun.COM ACPI_COMMON_MSG_SUFFIX; 13277851SDana.Myers@Sun.COM va_end (args); 13283446Smrj } 13293446Smrj 13303446Smrj void ACPI_INTERNAL_VAR_XFACE 13319980SDana.Myers@Sun.COM AcpiException ( 13327851SDana.Myers@Sun.COM const char *ModuleName, 13333446Smrj UINT32 LineNumber, 13343446Smrj ACPI_STATUS Status, 13357851SDana.Myers@Sun.COM const char *Format, 13363446Smrj ...) 13373446Smrj { 13383446Smrj va_list args; 13393446Smrj 13403446Smrj 13419980SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI Exception: %s, ", AcpiFormatException (Status)); 13423446Smrj 13433446Smrj va_start (args, Format); 13443446Smrj AcpiOsVprintf (Format, args); 1345*11225SDana.Myers@Sun.COM ACPI_COMMON_MSG_SUFFIX; 13467851SDana.Myers@Sun.COM va_end (args); 13473446Smrj } 13483446Smrj 13493446Smrj void ACPI_INTERNAL_VAR_XFACE 13509980SDana.Myers@Sun.COM AcpiWarning ( 13517851SDana.Myers@Sun.COM const char *ModuleName, 13523446Smrj UINT32 LineNumber, 13537851SDana.Myers@Sun.COM const char *Format, 13543446Smrj ...) 13553446Smrj { 13563446Smrj va_list args; 13573446Smrj 13583446Smrj 13599980SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI Warning: "); 13603446Smrj 13613446Smrj va_start (args, Format); 13623446Smrj AcpiOsVprintf (Format, args); 1363*11225SDana.Myers@Sun.COM ACPI_COMMON_MSG_SUFFIX; 13647851SDana.Myers@Sun.COM va_end (args); 13653446Smrj } 13663446Smrj 13673446Smrj void ACPI_INTERNAL_VAR_XFACE 13689980SDana.Myers@Sun.COM AcpiInfo ( 13697851SDana.Myers@Sun.COM const char *ModuleName, 13703446Smrj UINT32 LineNumber, 13717851SDana.Myers@Sun.COM const char *Format, 13723446Smrj ...) 13733446Smrj { 13743446Smrj va_list args; 13753446Smrj 13763446Smrj 13777851SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI: "); 13783446Smrj 13793446Smrj va_start (args, Format); 13803446Smrj AcpiOsVprintf (Format, args); 13817851SDana.Myers@Sun.COM AcpiOsPrintf ("\n"); 13827851SDana.Myers@Sun.COM va_end (args); 13833446Smrj } 13843446Smrj 13859980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiError) 13869980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiException) 13879980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiWarning) 13889980SDana.Myers@Sun.COM ACPI_EXPORT_SYMBOL (AcpiInfo) 13899980SDana.Myers@Sun.COM 13909980SDana.Myers@Sun.COM 1391*11225SDana.Myers@Sun.COM /******************************************************************************* 1392*11225SDana.Myers@Sun.COM * 1393*11225SDana.Myers@Sun.COM * FUNCTION: AcpiUtPredefinedWarning 1394*11225SDana.Myers@Sun.COM * 1395*11225SDana.Myers@Sun.COM * PARAMETERS: ModuleName - Caller's module name (for error output) 1396*11225SDana.Myers@Sun.COM * LineNumber - Caller's line number (for error output) 1397*11225SDana.Myers@Sun.COM * Pathname - Full pathname to the node 1398*11225SDana.Myers@Sun.COM * NodeFlags - From Namespace node for the method/object 1399*11225SDana.Myers@Sun.COM * Format - Printf format string + additional args 1400*11225SDana.Myers@Sun.COM * 1401*11225SDana.Myers@Sun.COM * RETURN: None 1402*11225SDana.Myers@Sun.COM * 1403*11225SDana.Myers@Sun.COM * DESCRIPTION: Warnings for the predefined validation module. Messages are 1404*11225SDana.Myers@Sun.COM * only emitted the first time a problem with a particular 1405*11225SDana.Myers@Sun.COM * method/object is detected. This prevents a flood of error 1406*11225SDana.Myers@Sun.COM * messages for methods that are repeatedly evaluated. 1407*11225SDana.Myers@Sun.COM * 1408*11225SDana.Myers@Sun.COM ******************************************************************************/ 1409*11225SDana.Myers@Sun.COM 1410*11225SDana.Myers@Sun.COM void ACPI_INTERNAL_VAR_XFACE 1411*11225SDana.Myers@Sun.COM AcpiUtPredefinedWarning ( 1412*11225SDana.Myers@Sun.COM const char *ModuleName, 1413*11225SDana.Myers@Sun.COM UINT32 LineNumber, 1414*11225SDana.Myers@Sun.COM char *Pathname, 1415*11225SDana.Myers@Sun.COM UINT8 NodeFlags, 1416*11225SDana.Myers@Sun.COM const char *Format, 1417*11225SDana.Myers@Sun.COM ...) 1418*11225SDana.Myers@Sun.COM { 1419*11225SDana.Myers@Sun.COM va_list args; 1420*11225SDana.Myers@Sun.COM 1421*11225SDana.Myers@Sun.COM 1422*11225SDana.Myers@Sun.COM /* 1423*11225SDana.Myers@Sun.COM * Warning messages for this method/object will be disabled after the 1424*11225SDana.Myers@Sun.COM * first time a validation fails or an object is successfully repaired. 1425*11225SDana.Myers@Sun.COM */ 1426*11225SDana.Myers@Sun.COM if (NodeFlags & ANOBJ_EVALUATED) 1427*11225SDana.Myers@Sun.COM { 1428*11225SDana.Myers@Sun.COM return; 1429*11225SDana.Myers@Sun.COM } 1430*11225SDana.Myers@Sun.COM 1431*11225SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI Warning for %s: ", Pathname); 1432*11225SDana.Myers@Sun.COM 1433*11225SDana.Myers@Sun.COM va_start (args, Format); 1434*11225SDana.Myers@Sun.COM AcpiOsVprintf (Format, args); 1435*11225SDana.Myers@Sun.COM ACPI_COMMON_MSG_SUFFIX; 1436*11225SDana.Myers@Sun.COM va_end (args); 1437*11225SDana.Myers@Sun.COM } 1438*11225SDana.Myers@Sun.COM 1439*11225SDana.Myers@Sun.COM /******************************************************************************* 1440*11225SDana.Myers@Sun.COM * 1441*11225SDana.Myers@Sun.COM * FUNCTION: AcpiUtPredefinedInfo 1442*11225SDana.Myers@Sun.COM * 1443*11225SDana.Myers@Sun.COM * PARAMETERS: ModuleName - Caller's module name (for error output) 1444*11225SDana.Myers@Sun.COM * LineNumber - Caller's line number (for error output) 1445*11225SDana.Myers@Sun.COM * Pathname - Full pathname to the node 1446*11225SDana.Myers@Sun.COM * NodeFlags - From Namespace node for the method/object 1447*11225SDana.Myers@Sun.COM * Format - Printf format string + additional args 1448*11225SDana.Myers@Sun.COM * 1449*11225SDana.Myers@Sun.COM * RETURN: None 1450*11225SDana.Myers@Sun.COM * 1451*11225SDana.Myers@Sun.COM * DESCRIPTION: Info messages for the predefined validation module. Messages 1452*11225SDana.Myers@Sun.COM * are only emitted the first time a problem with a particular 1453*11225SDana.Myers@Sun.COM * method/object is detected. This prevents a flood of 1454*11225SDana.Myers@Sun.COM * messages for methods that are repeatedly evaluated. 1455*11225SDana.Myers@Sun.COM * 1456*11225SDana.Myers@Sun.COM ******************************************************************************/ 1457*11225SDana.Myers@Sun.COM 1458*11225SDana.Myers@Sun.COM void ACPI_INTERNAL_VAR_XFACE 1459*11225SDana.Myers@Sun.COM AcpiUtPredefinedInfo ( 1460*11225SDana.Myers@Sun.COM const char *ModuleName, 1461*11225SDana.Myers@Sun.COM UINT32 LineNumber, 1462*11225SDana.Myers@Sun.COM char *Pathname, 1463*11225SDana.Myers@Sun.COM UINT8 NodeFlags, 1464*11225SDana.Myers@Sun.COM const char *Format, 1465*11225SDana.Myers@Sun.COM ...) 1466*11225SDana.Myers@Sun.COM { 1467*11225SDana.Myers@Sun.COM va_list args; 1468*11225SDana.Myers@Sun.COM 1469*11225SDana.Myers@Sun.COM 1470*11225SDana.Myers@Sun.COM /* 1471*11225SDana.Myers@Sun.COM * Warning messages for this method/object will be disabled after the 1472*11225SDana.Myers@Sun.COM * first time a validation fails or an object is successfully repaired. 1473*11225SDana.Myers@Sun.COM */ 1474*11225SDana.Myers@Sun.COM if (NodeFlags & ANOBJ_EVALUATED) 1475*11225SDana.Myers@Sun.COM { 1476*11225SDana.Myers@Sun.COM return; 1477*11225SDana.Myers@Sun.COM } 1478*11225SDana.Myers@Sun.COM 1479*11225SDana.Myers@Sun.COM AcpiOsPrintf ("ACPI Info for %s: ", Pathname); 1480*11225SDana.Myers@Sun.COM 1481*11225SDana.Myers@Sun.COM va_start (args, Format); 1482*11225SDana.Myers@Sun.COM AcpiOsVprintf (Format, args); 1483*11225SDana.Myers@Sun.COM ACPI_COMMON_MSG_SUFFIX; 1484*11225SDana.Myers@Sun.COM va_end (args); 1485*11225SDana.Myers@Sun.COM } 1486