13446Smrj /******************************************************************************
23446Smrj  *
33446Smrj  * Module Name: uteval - Object evaluation
4*7851SDana.Myers@Sun.COM  *              $Revision: 1.73 $
53446Smrj  *
63446Smrj  *****************************************************************************/
73446Smrj 
83446Smrj /******************************************************************************
93446Smrj  *
103446Smrj  * 1. Copyright Notice
113446Smrj  *
12*7851SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp.
133446Smrj  * All rights reserved.
143446Smrj  *
153446Smrj  * 2. License
163446Smrj  *
173446Smrj  * 2.1. This is your license from Intel Corp. under its intellectual property
183446Smrj  * rights.  You may have additional license terms from the party that provided
193446Smrj  * you this software, covering your right to use that party's intellectual
203446Smrj  * property rights.
213446Smrj  *
223446Smrj  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
233446Smrj  * copy of the source code appearing in this file ("Covered Code") an
243446Smrj  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
253446Smrj  * base code distributed originally by Intel ("Original Intel Code") to copy,
263446Smrj  * make derivatives, distribute, use and display any portion of the Covered
273446Smrj  * Code in any form, with the right to sublicense such rights; and
283446Smrj  *
293446Smrj  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
303446Smrj  * license (with the right to sublicense), under only those claims of Intel
313446Smrj  * patents that are infringed by the Original Intel Code, to make, use, sell,
323446Smrj  * offer to sell, and import the Covered Code and derivative works thereof
333446Smrj  * solely to the minimum extent necessary to exercise the above copyright
343446Smrj  * license, and in no event shall the patent license extend to any additions
353446Smrj  * to or modifications of the Original Intel Code.  No other license or right
363446Smrj  * is granted directly or by implication, estoppel or otherwise;
373446Smrj  *
383446Smrj  * The above copyright and patent license is granted only if the following
393446Smrj  * conditions are met:
403446Smrj  *
413446Smrj  * 3. Conditions
423446Smrj  *
433446Smrj  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
443446Smrj  * Redistribution of source code of any substantial portion of the Covered
453446Smrj  * Code or modification with rights to further distribute source must include
463446Smrj  * the above Copyright Notice, the above License, this list of Conditions,
473446Smrj  * and the following Disclaimer and Export Compliance provision.  In addition,
483446Smrj  * Licensee must cause all Covered Code to which Licensee contributes to
493446Smrj  * contain a file documenting the changes Licensee made to create that Covered
503446Smrj  * Code and the date of any change.  Licensee must include in that file the
513446Smrj  * documentation of any changes made by any predecessor Licensee.  Licensee
523446Smrj  * must include a prominent statement that the modification is derived,
533446Smrj  * directly or indirectly, from Original Intel Code.
543446Smrj  *
553446Smrj  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
563446Smrj  * Redistribution of source code of any substantial portion of the Covered
573446Smrj  * Code or modification without rights to further distribute source must
583446Smrj  * include the following Disclaimer and Export Compliance provision in the
593446Smrj  * documentation and/or other materials provided with distribution.  In
603446Smrj  * addition, Licensee may not authorize further sublicense of source of any
613446Smrj  * portion of the Covered Code, and must include terms to the effect that the
623446Smrj  * license from Licensee to its licensee is limited to the intellectual
633446Smrj  * property embodied in the software Licensee provides to its licensee, and
643446Smrj  * not to intellectual property embodied in modifications its licensee may
653446Smrj  * make.
663446Smrj  *
673446Smrj  * 3.3. Redistribution of Executable. Redistribution in executable form of any
683446Smrj  * substantial portion of the Covered Code or modification must reproduce the
693446Smrj  * above Copyright Notice, and the following Disclaimer and Export Compliance
703446Smrj  * provision in the documentation and/or other materials provided with the
713446Smrj  * distribution.
723446Smrj  *
733446Smrj  * 3.4. Intel retains all right, title, and interest in and to the Original
743446Smrj  * Intel Code.
753446Smrj  *
763446Smrj  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
773446Smrj  * Intel shall be used in advertising or otherwise to promote the sale, use or
783446Smrj  * other dealings in products derived from or relating to the Covered Code
793446Smrj  * without prior written authorization from Intel.
803446Smrj  *
813446Smrj  * 4. Disclaimer and Export Compliance
823446Smrj  *
833446Smrj  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
843446Smrj  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
853446Smrj  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
863446Smrj  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
873446Smrj  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
883446Smrj  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
893446Smrj  * PARTICULAR PURPOSE.
903446Smrj  *
913446Smrj  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
923446Smrj  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
933446Smrj  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
943446Smrj  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
953446Smrj  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
963446Smrj  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
973446Smrj  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
983446Smrj  * LIMITED REMEDY.
993446Smrj  *
1003446Smrj  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1013446Smrj  * software or system incorporating such software without first obtaining any
1023446Smrj  * required license or other approval from the U. S. Department of Commerce or
1033446Smrj  * any other agency or department of the United States Government.  In the
1043446Smrj  * event Licensee exports any such software from the United States or
1053446Smrj  * re-exports any such software from a foreign destination, Licensee shall
1063446Smrj  * ensure that the distribution and export/re-export of the software is in
1073446Smrj  * compliance with all laws, regulations, orders, or other restrictions of the
1083446Smrj  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1093446Smrj  * any of its subsidiaries will export/re-export any technical data, process,
1103446Smrj  * software, or service, directly or indirectly, to any country for which the
1113446Smrj  * United States government or any agency thereof requires an export license,
1123446Smrj  * other governmental approval, or letter of assurance, without first obtaining
1133446Smrj  * such license, approval or letter.
1143446Smrj  *
1153446Smrj  *****************************************************************************/
1163446Smrj 
1173446Smrj #define __UTEVAL_C__
1183446Smrj 
1193446Smrj #include "acpi.h"
1203446Smrj #include "acnamesp.h"
1213446Smrj #include "acinterp.h"
1223446Smrj 
1233446Smrj 
1243446Smrj #define _COMPONENT          ACPI_UTILITIES
1253446Smrj         ACPI_MODULE_NAME    ("uteval")
1263446Smrj 
1273446Smrj /* Local prototypes */
1283446Smrj 
1293446Smrj static void
1303446Smrj AcpiUtCopyIdString (
1313446Smrj     char                    *Destination,
1323446Smrj     char                    *Source,
1333446Smrj     ACPI_SIZE               MaxLength);
1343446Smrj 
1353446Smrj static ACPI_STATUS
1363446Smrj AcpiUtTranslateOneCid (
1373446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc,
1383446Smrj     ACPI_COMPATIBLE_ID      *OneCid);
1393446Smrj 
1403446Smrj 
1413446Smrj /*
1423446Smrj  * Strings supported by the _OSI predefined (internal) method.
1433446Smrj  */
1443446Smrj static const char               *AcpiInterfacesSupported[] =
1453446Smrj {
1463446Smrj     /* Operating System Vendor Strings */
1473446Smrj 
1483446Smrj     "Linux",
149*7851SDana.Myers@Sun.COM     "Windows 2000",         /* Windows 2000 */
150*7851SDana.Myers@Sun.COM     "Windows 2001",         /* Windows XP */
151*7851SDana.Myers@Sun.COM     "Windows 2001 SP1",     /* Windows XP SP1 */
152*7851SDana.Myers@Sun.COM     "Windows 2001 SP2",     /* Windows XP SP2 */
153*7851SDana.Myers@Sun.COM     "Windows 2001.1",       /* Windows Server 2003 */
154*7851SDana.Myers@Sun.COM     "Windows 2001.1 SP1",   /* Windows Server 2003 SP1 - Added 03/2006 */
155*7851SDana.Myers@Sun.COM     "Windows 2006",         /* Windows Vista - Added 03/2006 */
1563446Smrj 
1573446Smrj     /* Feature Group Strings */
1583446Smrj 
1593446Smrj     "Extended Address Space Descriptor"
1603446Smrj 
1613446Smrj     /*
1623446Smrj      * All "optional" feature group strings (features that are implemented
1633446Smrj      * by the host) should be implemented in the host version of
1643446Smrj      * AcpiOsValidateInterface and should not be added here.
1653446Smrj      */
1663446Smrj };
1673446Smrj 
1683446Smrj 
1693446Smrj /*******************************************************************************
1703446Smrj  *
1713446Smrj  * FUNCTION:    AcpiUtOsiImplementation
1723446Smrj  *
1733446Smrj  * PARAMETERS:  WalkState           - Current walk state
1743446Smrj  *
1753446Smrj  * RETURN:      Status
1763446Smrj  *
1773446Smrj  * DESCRIPTION: Implementation of the _OSI predefined control method
1783446Smrj  *
1793446Smrj  ******************************************************************************/
1803446Smrj 
1813446Smrj ACPI_STATUS
1823446Smrj AcpiUtOsiImplementation (
1833446Smrj     ACPI_WALK_STATE         *WalkState)
1843446Smrj {
1853446Smrj     ACPI_STATUS             Status;
1863446Smrj     ACPI_OPERAND_OBJECT     *StringDesc;
1873446Smrj     ACPI_OPERAND_OBJECT     *ReturnDesc;
188*7851SDana.Myers@Sun.COM     UINT32                  i;
1893446Smrj 
1903446Smrj 
1913446Smrj     ACPI_FUNCTION_TRACE (UtOsiImplementation);
1923446Smrj 
1933446Smrj 
1943446Smrj     /* Validate the string input argument */
1953446Smrj 
1963446Smrj     StringDesc = WalkState->Arguments[0].Object;
1973446Smrj     if (!StringDesc || (StringDesc->Common.Type != ACPI_TYPE_STRING))
1983446Smrj     {
1993446Smrj         return_ACPI_STATUS (AE_TYPE);
2003446Smrj     }
2013446Smrj 
2023446Smrj     /* Create a return object */
2033446Smrj 
2043446Smrj     ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
2053446Smrj     if (!ReturnDesc)
2063446Smrj     {
2073446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
2083446Smrj     }
2093446Smrj 
2103446Smrj     /* Default return value is SUPPORTED */
2113446Smrj 
2123446Smrj     ReturnDesc->Integer.Value = ACPI_UINT32_MAX;
2133446Smrj     WalkState->ReturnDesc = ReturnDesc;
2143446Smrj 
2153446Smrj     /* Compare input string to static table of supported interfaces */
2163446Smrj 
2173446Smrj     for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiInterfacesSupported); i++)
2183446Smrj     {
2193446Smrj         if (!ACPI_STRCMP (StringDesc->String.Pointer, AcpiInterfacesSupported[i]))
2203446Smrj         {
2213446Smrj             /* The interface is supported */
2223446Smrj 
2233446Smrj             return_ACPI_STATUS (AE_CTRL_TERMINATE);
2243446Smrj         }
2253446Smrj     }
2263446Smrj 
2273446Smrj     /*
2283446Smrj      * Did not match the string in the static table, call the host OSL to
2293446Smrj      * check for a match with one of the optional strings (such as
2303446Smrj      * "Module Device", "3.0 Thermal Model", etc.)
2313446Smrj      */
2323446Smrj     Status = AcpiOsValidateInterface (StringDesc->String.Pointer);
2333446Smrj     if (ACPI_SUCCESS (Status))
2343446Smrj     {
2353446Smrj         /* The interface is supported */
2363446Smrj 
2373446Smrj         return_ACPI_STATUS (AE_CTRL_TERMINATE);
2383446Smrj     }
2393446Smrj 
2403446Smrj     /* The interface is not supported */
2413446Smrj 
2423446Smrj     ReturnDesc->Integer.Value = 0;
2433446Smrj     return_ACPI_STATUS (AE_CTRL_TERMINATE);
2443446Smrj }
2453446Smrj 
2463446Smrj 
2473446Smrj /*******************************************************************************
2483446Smrj  *
2493446Smrj  * FUNCTION:    AcpiUtEvaluateObject
2503446Smrj  *
2513446Smrj  * PARAMETERS:  PrefixNode          - Starting node
2523446Smrj  *              Path                - Path to object from starting node
2533446Smrj  *              ExpectedReturnTypes - Bitmap of allowed return types
2543446Smrj  *              ReturnDesc          - Where a return value is stored
2553446Smrj  *
2563446Smrj  * RETURN:      Status
2573446Smrj  *
2583446Smrj  * DESCRIPTION: Evaluates a namespace object and verifies the type of the
2593446Smrj  *              return object.  Common code that simplifies accessing objects
2603446Smrj  *              that have required return objects of fixed types.
2613446Smrj  *
2623446Smrj  *              NOTE: Internal function, no parameter validation
2633446Smrj  *
2643446Smrj  ******************************************************************************/
2653446Smrj 
2663446Smrj ACPI_STATUS
2673446Smrj AcpiUtEvaluateObject (
2683446Smrj     ACPI_NAMESPACE_NODE     *PrefixNode,
2693446Smrj     char                    *Path,
2703446Smrj     UINT32                  ExpectedReturnBtypes,
2713446Smrj     ACPI_OPERAND_OBJECT     **ReturnDesc)
2723446Smrj {
2733446Smrj     ACPI_EVALUATE_INFO      *Info;
2743446Smrj     ACPI_STATUS             Status;
2753446Smrj     UINT32                  ReturnBtype;
2763446Smrj 
2773446Smrj 
2783446Smrj     ACPI_FUNCTION_TRACE (UtEvaluateObject);
2793446Smrj 
2803446Smrj 
2813446Smrj     /* Allocate the evaluation information block */
2823446Smrj 
2833446Smrj     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
2843446Smrj     if (!Info)
2853446Smrj     {
2863446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
2873446Smrj     }
2883446Smrj 
2893446Smrj     Info->PrefixNode = PrefixNode;
2903446Smrj     Info->Pathname = Path;
2913446Smrj 
2923446Smrj     /* Evaluate the object/method */
2933446Smrj 
2943446Smrj     Status = AcpiNsEvaluate (Info);
2953446Smrj     if (ACPI_FAILURE (Status))
2963446Smrj     {
2973446Smrj         if (Status == AE_NOT_FOUND)
2983446Smrj         {
2993446Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s.%s] was not found\n",
3003446Smrj                 AcpiUtGetNodeName (PrefixNode), Path));
3013446Smrj         }
3023446Smrj         else
3033446Smrj         {
3043446Smrj             ACPI_ERROR_METHOD ("Method execution failed",
3053446Smrj                 PrefixNode, Path, Status);
3063446Smrj         }
3073446Smrj 
3083446Smrj         goto Cleanup;
3093446Smrj     }
3103446Smrj 
3113446Smrj     /* Did we get a return object? */
3123446Smrj 
3133446Smrj     if (!Info->ReturnObject)
3143446Smrj     {
3153446Smrj         if (ExpectedReturnBtypes)
3163446Smrj         {
3173446Smrj             ACPI_ERROR_METHOD ("No object was returned from",
3183446Smrj                 PrefixNode, Path, AE_NOT_EXIST);
3193446Smrj 
3203446Smrj             Status = AE_NOT_EXIST;
3213446Smrj         }
3223446Smrj 
3233446Smrj         goto Cleanup;
3243446Smrj     }
3253446Smrj 
3263446Smrj     /* Map the return object type to the bitmapped type */
3273446Smrj 
3283446Smrj     switch (ACPI_GET_OBJECT_TYPE (Info->ReturnObject))
3293446Smrj     {
3303446Smrj     case ACPI_TYPE_INTEGER:
3313446Smrj         ReturnBtype = ACPI_BTYPE_INTEGER;
3323446Smrj         break;
3333446Smrj 
3343446Smrj     case ACPI_TYPE_BUFFER:
3353446Smrj         ReturnBtype = ACPI_BTYPE_BUFFER;
3363446Smrj         break;
3373446Smrj 
3383446Smrj     case ACPI_TYPE_STRING:
3393446Smrj         ReturnBtype = ACPI_BTYPE_STRING;
3403446Smrj         break;
3413446Smrj 
3423446Smrj     case ACPI_TYPE_PACKAGE:
3433446Smrj         ReturnBtype = ACPI_BTYPE_PACKAGE;
3443446Smrj         break;
3453446Smrj 
3463446Smrj     default:
3473446Smrj         ReturnBtype = 0;
3483446Smrj         break;
3493446Smrj     }
3503446Smrj 
3513446Smrj     if ((AcpiGbl_EnableInterpreterSlack) &&
3523446Smrj         (!ExpectedReturnBtypes))
3533446Smrj     {
3543446Smrj         /*
3553446Smrj          * We received a return object, but one was not expected.  This can
3563446Smrj          * happen frequently if the "implicit return" feature is enabled.
3573446Smrj          * Just delete the return object and return AE_OK.
3583446Smrj          */
3593446Smrj         AcpiUtRemoveReference (Info->ReturnObject);
3603446Smrj         goto Cleanup;
3613446Smrj     }
3623446Smrj 
3633446Smrj     /* Is the return object one of the expected types? */
3643446Smrj 
3653446Smrj     if (!(ExpectedReturnBtypes & ReturnBtype))
3663446Smrj     {
3673446Smrj         ACPI_ERROR_METHOD ("Return object type is incorrect",
3683446Smrj             PrefixNode, Path, AE_TYPE);
3693446Smrj 
3703446Smrj         ACPI_ERROR ((AE_INFO,
3713446Smrj             "Type returned from %s was incorrect: %s, expected Btypes: %X",
3723446Smrj             Path, AcpiUtGetObjectTypeName (Info->ReturnObject),
3733446Smrj             ExpectedReturnBtypes));
3743446Smrj 
3753446Smrj         /* On error exit, we must delete the return object */
3763446Smrj 
3773446Smrj         AcpiUtRemoveReference (Info->ReturnObject);
3783446Smrj         Status = AE_TYPE;
3793446Smrj         goto Cleanup;
3803446Smrj     }
3813446Smrj 
3823446Smrj     /* Object type is OK, return it */
3833446Smrj 
3843446Smrj     *ReturnDesc = Info->ReturnObject;
3853446Smrj 
3863446Smrj Cleanup:
3873446Smrj     ACPI_FREE (Info);
3883446Smrj     return_ACPI_STATUS (Status);
3893446Smrj }
3903446Smrj 
3913446Smrj 
3923446Smrj /*******************************************************************************
3933446Smrj  *
3943446Smrj  * FUNCTION:    AcpiUtEvaluateNumericObject
3953446Smrj  *
3963446Smrj  * PARAMETERS:  ObjectName          - Object name to be evaluated
3973446Smrj  *              DeviceNode          - Node for the device
3983446Smrj  *              Address             - Where the value is returned
3993446Smrj  *
4003446Smrj  * RETURN:      Status
4013446Smrj  *
4023446Smrj  * DESCRIPTION: Evaluates a numeric namespace object for a selected device
4033446Smrj  *              and stores result in *Address.
4043446Smrj  *
4053446Smrj  *              NOTE: Internal function, no parameter validation
4063446Smrj  *
4073446Smrj  ******************************************************************************/
4083446Smrj 
4093446Smrj ACPI_STATUS
4103446Smrj AcpiUtEvaluateNumericObject (
4113446Smrj     char                    *ObjectName,
4123446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
4133446Smrj     ACPI_INTEGER            *Address)
4143446Smrj {
4153446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
4163446Smrj     ACPI_STATUS             Status;
4173446Smrj 
4183446Smrj 
4193446Smrj     ACPI_FUNCTION_TRACE (UtEvaluateNumericObject);
4203446Smrj 
4213446Smrj 
4223446Smrj     Status = AcpiUtEvaluateObject (DeviceNode, ObjectName,
4233446Smrj                 ACPI_BTYPE_INTEGER, &ObjDesc);
4243446Smrj     if (ACPI_FAILURE (Status))
4253446Smrj     {
4263446Smrj         return_ACPI_STATUS (Status);
4273446Smrj     }
4283446Smrj 
4293446Smrj     /* Get the returned Integer */
4303446Smrj 
4313446Smrj     *Address = ObjDesc->Integer.Value;
4323446Smrj 
4333446Smrj     /* On exit, we must delete the return object */
4343446Smrj 
4353446Smrj     AcpiUtRemoveReference (ObjDesc);
4363446Smrj     return_ACPI_STATUS (Status);
4373446Smrj }
4383446Smrj 
4393446Smrj 
4403446Smrj /*******************************************************************************
4413446Smrj  *
4423446Smrj  * FUNCTION:    AcpiUtCopyIdString
4433446Smrj  *
4443446Smrj  * PARAMETERS:  Destination         - Where to copy the string
4453446Smrj  *              Source              - Source string
4463446Smrj  *              MaxLength           - Length of the destination buffer
4473446Smrj  *
4483446Smrj  * RETURN:      None
4493446Smrj  *
4503446Smrj  * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods.
4513446Smrj  *              Performs removal of a leading asterisk if present -- workaround
4523446Smrj  *              for a known issue on a bunch of machines.
4533446Smrj  *
4543446Smrj  ******************************************************************************/
4553446Smrj 
4563446Smrj static void
4573446Smrj AcpiUtCopyIdString (
4583446Smrj     char                    *Destination,
4593446Smrj     char                    *Source,
4603446Smrj     ACPI_SIZE               MaxLength)
4613446Smrj {
4623446Smrj 
4633446Smrj     /*
4643446Smrj      * Workaround for ID strings that have a leading asterisk. This construct
4653446Smrj      * is not allowed by the ACPI specification  (ID strings must be
4663446Smrj      * alphanumeric), but enough existing machines have this embedded in their
4673446Smrj      * ID strings that the following code is useful.
4683446Smrj      */
4693446Smrj     if (*Source == '*')
4703446Smrj     {
4713446Smrj         Source++;
4723446Smrj     }
4733446Smrj 
4743446Smrj     /* Do the actual copy */
4753446Smrj 
4763446Smrj     ACPI_STRNCPY (Destination, Source, MaxLength);
4773446Smrj }
4783446Smrj 
4793446Smrj 
4803446Smrj /*******************************************************************************
4813446Smrj  *
4823446Smrj  * FUNCTION:    AcpiUtExecute_HID
4833446Smrj  *
4843446Smrj  * PARAMETERS:  DeviceNode          - Node for the device
4853446Smrj  *              Hid                 - Where the HID is returned
4863446Smrj  *
4873446Smrj  * RETURN:      Status
4883446Smrj  *
4893446Smrj  * DESCRIPTION: Executes the _HID control method that returns the hardware
4903446Smrj  *              ID of the device.
4913446Smrj  *
4923446Smrj  *              NOTE: Internal function, no parameter validation
4933446Smrj  *
4943446Smrj  ******************************************************************************/
4953446Smrj 
4963446Smrj ACPI_STATUS
4973446Smrj AcpiUtExecute_HID (
4983446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
4993446Smrj     ACPI_DEVICE_ID          *Hid)
5003446Smrj {
5013446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
5023446Smrj     ACPI_STATUS             Status;
5033446Smrj 
5043446Smrj 
5053446Smrj     ACPI_FUNCTION_TRACE (UtExecute_HID);
5063446Smrj 
5073446Smrj 
5083446Smrj     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__HID,
5093446Smrj                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
5103446Smrj     if (ACPI_FAILURE (Status))
5113446Smrj     {
5123446Smrj         return_ACPI_STATUS (Status);
5133446Smrj     }
5143446Smrj 
5153446Smrj     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER)
5163446Smrj     {
5173446Smrj         /* Convert the Numeric HID to string */
5183446Smrj 
5193446Smrj         AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, Hid->Value);
5203446Smrj     }
5213446Smrj     else
5223446Smrj     {
5233446Smrj         /* Copy the String HID from the returned object */
5243446Smrj 
5253446Smrj         AcpiUtCopyIdString (Hid->Value, ObjDesc->String.Pointer,
5263446Smrj                 sizeof (Hid->Value));
5273446Smrj     }
5283446Smrj 
5293446Smrj     /* On exit, we must delete the return object */
5303446Smrj 
5313446Smrj     AcpiUtRemoveReference (ObjDesc);
5323446Smrj     return_ACPI_STATUS (Status);
5333446Smrj }
5343446Smrj 
5353446Smrj 
5363446Smrj /*******************************************************************************
5373446Smrj  *
5383446Smrj  * FUNCTION:    AcpiUtTranslateOneCid
5393446Smrj  *
5403446Smrj  * PARAMETERS:  ObjDesc             - _CID object, must be integer or string
5413446Smrj  *              OneCid              - Where the CID string is returned
5423446Smrj  *
5433446Smrj  * RETURN:      Status
5443446Smrj  *
5453446Smrj  * DESCRIPTION: Return a numeric or string _CID value as a string.
5463446Smrj  *              (Compatible ID)
5473446Smrj  *
5483446Smrj  *              NOTE:  Assumes a maximum _CID string length of
5493446Smrj  *                     ACPI_MAX_CID_LENGTH.
5503446Smrj  *
5513446Smrj  ******************************************************************************/
5523446Smrj 
5533446Smrj static ACPI_STATUS
5543446Smrj AcpiUtTranslateOneCid (
5553446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc,
5563446Smrj     ACPI_COMPATIBLE_ID      *OneCid)
5573446Smrj {
5583446Smrj 
5593446Smrj 
5603446Smrj     switch (ACPI_GET_OBJECT_TYPE (ObjDesc))
5613446Smrj     {
5623446Smrj     case ACPI_TYPE_INTEGER:
5633446Smrj 
5643446Smrj         /* Convert the Numeric CID to string */
5653446Smrj 
5663446Smrj         AcpiExEisaIdToString ((UINT32) ObjDesc->Integer.Value, OneCid->Value);
5673446Smrj         return (AE_OK);
5683446Smrj 
5693446Smrj     case ACPI_TYPE_STRING:
5703446Smrj 
5713446Smrj         if (ObjDesc->String.Length > ACPI_MAX_CID_LENGTH)
5723446Smrj         {
5733446Smrj             return (AE_AML_STRING_LIMIT);
5743446Smrj         }
5753446Smrj 
5763446Smrj         /* Copy the String CID from the returned object */
5773446Smrj 
5783446Smrj         AcpiUtCopyIdString (OneCid->Value, ObjDesc->String.Pointer,
5793446Smrj                 ACPI_MAX_CID_LENGTH);
5803446Smrj         return (AE_OK);
5813446Smrj 
5823446Smrj     default:
5833446Smrj 
5843446Smrj         return (AE_TYPE);
5853446Smrj     }
5863446Smrj }
5873446Smrj 
5883446Smrj 
5893446Smrj /*******************************************************************************
5903446Smrj  *
5913446Smrj  * FUNCTION:    AcpiUtExecute_CID
5923446Smrj  *
5933446Smrj  * PARAMETERS:  DeviceNode          - Node for the device
5943446Smrj  *              ReturnCidList       - Where the CID list is returned
5953446Smrj  *
5963446Smrj  * RETURN:      Status
5973446Smrj  *
5983446Smrj  * DESCRIPTION: Executes the _CID control method that returns one or more
5993446Smrj  *              compatible hardware IDs for the device.
6003446Smrj  *
6013446Smrj  *              NOTE: Internal function, no parameter validation
6023446Smrj  *
6033446Smrj  ******************************************************************************/
6043446Smrj 
6053446Smrj ACPI_STATUS
6063446Smrj AcpiUtExecute_CID (
6073446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
6083446Smrj     ACPI_COMPATIBLE_ID_LIST **ReturnCidList)
6093446Smrj {
6103446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
6113446Smrj     ACPI_STATUS             Status;
6123446Smrj     UINT32                  Count;
6133446Smrj     UINT32                  Size;
6143446Smrj     ACPI_COMPATIBLE_ID_LIST *CidList;
615*7851SDana.Myers@Sun.COM     UINT32                  i;
6163446Smrj 
6173446Smrj 
6183446Smrj     ACPI_FUNCTION_TRACE (UtExecute_CID);
6193446Smrj 
6203446Smrj 
6213446Smrj     /* Evaluate the _CID method for this device */
6223446Smrj 
6233446Smrj     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__CID,
6243446Smrj                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE,
6253446Smrj                 &ObjDesc);
6263446Smrj     if (ACPI_FAILURE (Status))
6273446Smrj     {
6283446Smrj         return_ACPI_STATUS (Status);
6293446Smrj     }
6303446Smrj 
6313446Smrj     /* Get the number of _CIDs returned */
6323446Smrj 
6333446Smrj     Count = 1;
6343446Smrj     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE)
6353446Smrj     {
6363446Smrj         Count = ObjDesc->Package.Count;
6373446Smrj     }
6383446Smrj 
6393446Smrj     /* Allocate a worst-case buffer for the _CIDs */
6403446Smrj 
6413446Smrj     Size = (((Count - 1) * sizeof (ACPI_COMPATIBLE_ID)) +
6423446Smrj                            sizeof (ACPI_COMPATIBLE_ID_LIST));
6433446Smrj 
6443446Smrj     CidList = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) Size);
6453446Smrj     if (!CidList)
6463446Smrj     {
6473446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
6483446Smrj     }
6493446Smrj 
6503446Smrj     /* Init CID list */
6513446Smrj 
6523446Smrj     CidList->Count = Count;
6533446Smrj     CidList->Size  = Size;
6543446Smrj 
6553446Smrj     /*
6563446Smrj      *  A _CID can return either a single compatible ID or a package of
6573446Smrj      *  compatible IDs.  Each compatible ID can be one of the following:
6583446Smrj      *  1) Integer (32 bit compressed EISA ID) or
6593446Smrj      *  2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss")
6603446Smrj      */
6613446Smrj 
6623446Smrj     /* The _CID object can be either a single CID or a package (list) of CIDs */
6633446Smrj 
6643446Smrj     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_PACKAGE)
6653446Smrj     {
6663446Smrj         /* Translate each package element */
6673446Smrj 
6683446Smrj         for (i = 0; i < Count; i++)
6693446Smrj         {
6703446Smrj             Status = AcpiUtTranslateOneCid (ObjDesc->Package.Elements[i],
6713446Smrj                             &CidList->Id[i]);
6723446Smrj             if (ACPI_FAILURE (Status))
6733446Smrj             {
6743446Smrj                 break;
6753446Smrj             }
6763446Smrj         }
6773446Smrj     }
6783446Smrj     else
6793446Smrj     {
6803446Smrj         /* Only one CID, translate to a string */
6813446Smrj 
6823446Smrj         Status = AcpiUtTranslateOneCid (ObjDesc, CidList->Id);
6833446Smrj     }
6843446Smrj 
6853446Smrj     /* Cleanup on error */
6863446Smrj 
6873446Smrj     if (ACPI_FAILURE (Status))
6883446Smrj     {
6893446Smrj         ACPI_FREE (CidList);
6903446Smrj     }
6913446Smrj     else
6923446Smrj     {
6933446Smrj         *ReturnCidList = CidList;
6943446Smrj     }
6953446Smrj 
6963446Smrj     /* On exit, we must delete the _CID return object */
6973446Smrj 
6983446Smrj     AcpiUtRemoveReference (ObjDesc);
6993446Smrj     return_ACPI_STATUS (Status);
7003446Smrj }
7013446Smrj 
7023446Smrj 
7033446Smrj /*******************************************************************************
7043446Smrj  *
7053446Smrj  * FUNCTION:    AcpiUtExecute_UID
7063446Smrj  *
7073446Smrj  * PARAMETERS:  DeviceNode          - Node for the device
7083446Smrj  *              Uid                 - Where the UID is returned
7093446Smrj  *
7103446Smrj  * RETURN:      Status
7113446Smrj  *
7123446Smrj  * DESCRIPTION: Executes the _UID control method that returns the hardware
7133446Smrj  *              ID of the device.
7143446Smrj  *
7153446Smrj  *              NOTE: Internal function, no parameter validation
7163446Smrj  *
7173446Smrj  ******************************************************************************/
7183446Smrj 
7193446Smrj ACPI_STATUS
7203446Smrj AcpiUtExecute_UID (
7213446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
7223446Smrj     ACPI_DEVICE_ID          *Uid)
7233446Smrj {
7243446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
7253446Smrj     ACPI_STATUS             Status;
7263446Smrj 
7273446Smrj 
7283446Smrj     ACPI_FUNCTION_TRACE (UtExecute_UID);
7293446Smrj 
7303446Smrj 
7313446Smrj     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__UID,
7323446Smrj                 ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, &ObjDesc);
7333446Smrj     if (ACPI_FAILURE (Status))
7343446Smrj     {
7353446Smrj         return_ACPI_STATUS (Status);
7363446Smrj     }
7373446Smrj 
7383446Smrj     if (ACPI_GET_OBJECT_TYPE (ObjDesc) == ACPI_TYPE_INTEGER)
7393446Smrj     {
7403446Smrj         /* Convert the Numeric UID to string */
7413446Smrj 
7423446Smrj         AcpiExUnsignedIntegerToString (ObjDesc->Integer.Value, Uid->Value);
7433446Smrj     }
7443446Smrj     else
7453446Smrj     {
7463446Smrj         /* Copy the String UID from the returned object */
7473446Smrj 
7483446Smrj         AcpiUtCopyIdString (Uid->Value, ObjDesc->String.Pointer,
7493446Smrj                 sizeof (Uid->Value));
7503446Smrj     }
7513446Smrj 
7523446Smrj     /* On exit, we must delete the return object */
7533446Smrj 
7543446Smrj     AcpiUtRemoveReference (ObjDesc);
7553446Smrj     return_ACPI_STATUS (Status);
7563446Smrj }
7573446Smrj 
7583446Smrj 
7593446Smrj /*******************************************************************************
7603446Smrj  *
7613446Smrj  * FUNCTION:    AcpiUtExecute_STA
7623446Smrj  *
7633446Smrj  * PARAMETERS:  DeviceNode          - Node for the device
7643446Smrj  *              Flags               - Where the status flags are returned
7653446Smrj  *
7663446Smrj  * RETURN:      Status
7673446Smrj  *
7683446Smrj  * DESCRIPTION: Executes _STA for selected device and stores results in
7693446Smrj  *              *Flags.
7703446Smrj  *
7713446Smrj  *              NOTE: Internal function, no parameter validation
7723446Smrj  *
7733446Smrj  ******************************************************************************/
7743446Smrj 
7753446Smrj ACPI_STATUS
7763446Smrj AcpiUtExecute_STA (
7773446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
7783446Smrj     UINT32                  *Flags)
7793446Smrj {
7803446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
7813446Smrj     ACPI_STATUS             Status;
7823446Smrj 
7833446Smrj 
7843446Smrj     ACPI_FUNCTION_TRACE (UtExecute_STA);
7853446Smrj 
7863446Smrj 
7873446Smrj     Status = AcpiUtEvaluateObject (DeviceNode, METHOD_NAME__STA,
7883446Smrj                 ACPI_BTYPE_INTEGER, &ObjDesc);
7893446Smrj     if (ACPI_FAILURE (Status))
7903446Smrj     {
7913446Smrj         if (AE_NOT_FOUND == Status)
7923446Smrj         {
7933446Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
7943446Smrj                 "_STA on %4.4s was not found, assuming device is present\n",
7953446Smrj                 AcpiUtGetNodeName (DeviceNode)));
7963446Smrj 
7973446Smrj             *Flags = ACPI_UINT32_MAX;
7983446Smrj             Status = AE_OK;
7993446Smrj         }
8003446Smrj 
8013446Smrj         return_ACPI_STATUS (Status);
8023446Smrj     }
8033446Smrj 
8043446Smrj     /* Extract the status flags */
8053446Smrj 
8063446Smrj     *Flags = (UINT32) ObjDesc->Integer.Value;
8073446Smrj 
8083446Smrj     /* On exit, we must delete the return object */
8093446Smrj 
8103446Smrj     AcpiUtRemoveReference (ObjDesc);
8113446Smrj     return_ACPI_STATUS (Status);
8123446Smrj }
8133446Smrj 
8143446Smrj 
8153446Smrj /*******************************************************************************
8163446Smrj  *
8173446Smrj  * FUNCTION:    AcpiUtExecute_Sxds
8183446Smrj  *
8193446Smrj  * PARAMETERS:  DeviceNode          - Node for the device
8203446Smrj  *              Flags               - Where the status flags are returned
8213446Smrj  *
8223446Smrj  * RETURN:      Status
8233446Smrj  *
8243446Smrj  * DESCRIPTION: Executes _STA for selected device and stores results in
8253446Smrj  *              *Flags.
8263446Smrj  *
8273446Smrj  *              NOTE: Internal function, no parameter validation
8283446Smrj  *
8293446Smrj  ******************************************************************************/
8303446Smrj 
8313446Smrj ACPI_STATUS
8323446Smrj AcpiUtExecute_Sxds (
8333446Smrj     ACPI_NAMESPACE_NODE     *DeviceNode,
8343446Smrj     UINT8                   *Highest)
8353446Smrj {
8363446Smrj     ACPI_OPERAND_OBJECT     *ObjDesc;
8373446Smrj     ACPI_STATUS             Status;
8383446Smrj     UINT32                  i;
8393446Smrj 
8403446Smrj 
8413446Smrj     ACPI_FUNCTION_TRACE (UtExecute_Sxds);
8423446Smrj 
8433446Smrj 
8443446Smrj     for (i = 0; i < 4; i++)
8453446Smrj     {
8463446Smrj         Highest[i] = 0xFF;
8473446Smrj         Status = AcpiUtEvaluateObject (DeviceNode,
8483446Smrj                     ACPI_CAST_PTR (char, AcpiGbl_HighestDstateNames[i]),
8493446Smrj                     ACPI_BTYPE_INTEGER, &ObjDesc);
8503446Smrj         if (ACPI_FAILURE (Status))
8513446Smrj         {
8523446Smrj             if (Status != AE_NOT_FOUND)
8533446Smrj             {
8543446Smrj                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
8553446Smrj                     "%s on Device %4.4s, %s\n",
8563446Smrj                     ACPI_CAST_PTR (char, AcpiGbl_HighestDstateNames[i]),
8573446Smrj                     AcpiUtGetNodeName (DeviceNode),
8583446Smrj                     AcpiFormatException (Status)));
8593446Smrj 
8603446Smrj                 return_ACPI_STATUS (Status);
8613446Smrj             }
8623446Smrj         }
8633446Smrj         else
8643446Smrj         {
8653446Smrj             /* Extract the Dstate value */
8663446Smrj 
8673446Smrj             Highest[i] = (UINT8) ObjDesc->Integer.Value;
8683446Smrj 
8693446Smrj             /* Delete the return object */
8703446Smrj 
8713446Smrj             AcpiUtRemoveReference (ObjDesc);
8723446Smrj         }
8733446Smrj     }
8743446Smrj 
8753446Smrj     return_ACPI_STATUS (AE_OK);
8763446Smrj }
877