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 *
AcpiUtValidateException(ACPI_STATUS Status)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
AcpiUtIsPciRootBridge(char * Id)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
AcpiUtIsAmlTable(ACPI_TABLE_HEADER * Table)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
AcpiUtAllocateOwnerId(ACPI_OWNER_ID * OwnerId)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
AcpiUtReleaseOwnerId(ACPI_OWNER_ID * OwnerIdPtr)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
AcpiUtStrupr(char * SrcString)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
AcpiUtPrintString(char * String,UINT8 MaxLength)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
AcpiUtDwordByteSwap(UINT32 Value)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
AcpiUtSetIntegerWidth(UINT8 Revision)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
AcpiUtDisplayInitPathname(UINT8 Type,ACPI_NAMESPACE_NODE * ObjHandle,char * Path)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
AcpiUtValidAcpiChar(char Character,UINT32 Position)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
AcpiUtValidAcpiName(UINT32 Name)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
AcpiUtRepairName(char * Name)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
AcpiUtStrtoul64(char * String,UINT32 Base,ACPI_INTEGER * RetInteger)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
AcpiUtCreateUpdateStateAndPush(ACPI_OPERAND_OBJECT * Object,UINT16 Action,ACPI_GENERIC_STATE ** StateList)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
AcpiUtWalkPackageTree(ACPI_OPERAND_OBJECT * SourceObject,void * TargetObject,ACPI_PKG_CALLBACK WalkCallback,void * Context)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
AcpiError(const char * ModuleName,UINT32 LineNumber,const char * Format,...)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
AcpiException(const char * ModuleName,UINT32 LineNumber,ACPI_STATUS Status,const char * Format,...)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
AcpiWarning(const char * ModuleName,UINT32 LineNumber,const char * Format,...)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
AcpiInfo(const char * ModuleName,UINT32 LineNumber,const char * Format,...)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)
ACPI_EXPORT_SYMBOL(AcpiException)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
AcpiUtPredefinedInfo(const char * ModuleName,UINT32 LineNumber,char * Pathname,UINT8 NodeFlags,const char * Format,...)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