xref: /onnv-gate/usr/src/uts/intel/io/acpica/namespace/nsxfeval.c (revision 11225:eb6056029d84)
13446Smrj /*******************************************************************************
23446Smrj  *
33446Smrj  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
43446Smrj  *                         ACPI Object evaluation interfaces
53446Smrj  *
63446Smrj  ******************************************************************************/
73446Smrj 
83446Smrj /******************************************************************************
93446Smrj  *
103446Smrj  * 1. Copyright Notice
113446Smrj  *
129980SDana.Myers@Sun.COM  * Some or all of this work - Copyright (c) 1999 - 2009, 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 
1183446Smrj #define __NSXFEVAL_C__
1193446Smrj 
1203446Smrj #include "acpi.h"
1219980SDana.Myers@Sun.COM #include "accommon.h"
1223446Smrj #include "acnamesp.h"
1233446Smrj #include "acinterp.h"
1243446Smrj 
1253446Smrj 
1263446Smrj #define _COMPONENT          ACPI_NAMESPACE
1273446Smrj         ACPI_MODULE_NAME    ("nsxfeval")
1283446Smrj 
1297851SDana.Myers@Sun.COM /* Local prototypes */
1307851SDana.Myers@Sun.COM 
1317851SDana.Myers@Sun.COM static void
1327851SDana.Myers@Sun.COM AcpiNsResolveReferences (
1337851SDana.Myers@Sun.COM     ACPI_EVALUATE_INFO      *Info);
1347851SDana.Myers@Sun.COM 
1353446Smrj 
1363446Smrj /*******************************************************************************
1373446Smrj  *
1383446Smrj  * FUNCTION:    AcpiEvaluateObjectTyped
1393446Smrj  *
1403446Smrj  * PARAMETERS:  Handle              - Object handle (optional)
1413446Smrj  *              Pathname            - Object pathname (optional)
1423446Smrj  *              ExternalParams      - List of parameters to pass to method,
1433446Smrj  *                                    terminated by NULL.  May be NULL
1443446Smrj  *                                    if no parameters are being passed.
1453446Smrj  *              ReturnBuffer        - Where to put method's return value (if
1463446Smrj  *                                    any).  If NULL, no value is returned.
1473446Smrj  *              ReturnType          - Expected type of return object
1483446Smrj  *
1493446Smrj  * RETURN:      Status
1503446Smrj  *
1513446Smrj  * DESCRIPTION: Find and evaluate the given object, passing the given
1523446Smrj  *              parameters if necessary.  One of "Handle" or "Pathname" must
1533446Smrj  *              be valid (non-null)
1543446Smrj  *
1553446Smrj  ******************************************************************************/
1563446Smrj 
1573446Smrj ACPI_STATUS
AcpiEvaluateObjectTyped(ACPI_HANDLE Handle,ACPI_STRING Pathname,ACPI_OBJECT_LIST * ExternalParams,ACPI_BUFFER * ReturnBuffer,ACPI_OBJECT_TYPE ReturnType)1583446Smrj AcpiEvaluateObjectTyped (
1593446Smrj     ACPI_HANDLE             Handle,
1603446Smrj     ACPI_STRING             Pathname,
1613446Smrj     ACPI_OBJECT_LIST        *ExternalParams,
1623446Smrj     ACPI_BUFFER             *ReturnBuffer,
1633446Smrj     ACPI_OBJECT_TYPE        ReturnType)
1643446Smrj {
1653446Smrj     ACPI_STATUS             Status;
1663446Smrj     BOOLEAN                 MustFree = FALSE;
1673446Smrj 
1683446Smrj 
1693446Smrj     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
1703446Smrj 
1713446Smrj 
1723446Smrj     /* Return buffer must be valid */
1733446Smrj 
1743446Smrj     if (!ReturnBuffer)
1753446Smrj     {
1763446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
1773446Smrj     }
1783446Smrj 
1793446Smrj     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
1803446Smrj     {
1813446Smrj         MustFree = TRUE;
1823446Smrj     }
1833446Smrj 
1843446Smrj     /* Evaluate the object */
1853446Smrj 
1863446Smrj     Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
1873446Smrj     if (ACPI_FAILURE (Status))
1883446Smrj     {
1893446Smrj         return_ACPI_STATUS (Status);
1903446Smrj     }
1913446Smrj 
1923446Smrj     /* Type ANY means "don't care" */
1933446Smrj 
1943446Smrj     if (ReturnType == ACPI_TYPE_ANY)
1953446Smrj     {
1963446Smrj         return_ACPI_STATUS (AE_OK);
1973446Smrj     }
1983446Smrj 
1993446Smrj     if (ReturnBuffer->Length == 0)
2003446Smrj     {
2013446Smrj         /* Error because caller specifically asked for a return value */
2023446Smrj 
2033446Smrj         ACPI_ERROR ((AE_INFO, "No return value"));
2043446Smrj         return_ACPI_STATUS (AE_NULL_OBJECT);
2053446Smrj     }
2063446Smrj 
2073446Smrj     /* Examine the object type returned from EvaluateObject */
2083446Smrj 
2093446Smrj     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
2103446Smrj     {
2113446Smrj         return_ACPI_STATUS (AE_OK);
2123446Smrj     }
2133446Smrj 
2143446Smrj     /* Return object type does not match requested type */
2153446Smrj 
2163446Smrj     ACPI_ERROR ((AE_INFO,
2173446Smrj         "Incorrect return type [%s] requested [%s]",
2183446Smrj         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
2193446Smrj         AcpiUtGetTypeName (ReturnType)));
2203446Smrj 
2213446Smrj     if (MustFree)
2223446Smrj     {
2233446Smrj         /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
2243446Smrj 
2253446Smrj         AcpiOsFree (ReturnBuffer->Pointer);
2263446Smrj         ReturnBuffer->Pointer = NULL;
2273446Smrj     }
2283446Smrj 
2293446Smrj     ReturnBuffer->Length = 0;
2303446Smrj     return_ACPI_STATUS (AE_TYPE);
2313446Smrj }
2323446Smrj 
ACPI_EXPORT_SYMBOL(AcpiEvaluateObjectTyped)2333446Smrj ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
2343446Smrj 
2353446Smrj 
2363446Smrj /*******************************************************************************
2373446Smrj  *
2383446Smrj  * FUNCTION:    AcpiEvaluateObject
2393446Smrj  *
2403446Smrj  * PARAMETERS:  Handle              - Object handle (optional)
2413446Smrj  *              Pathname            - Object pathname (optional)
2423446Smrj  *              ExternalParams      - List of parameters to pass to method,
2433446Smrj  *                                    terminated by NULL.  May be NULL
2443446Smrj  *                                    if no parameters are being passed.
2453446Smrj  *              ReturnBuffer        - Where to put method's return value (if
2463446Smrj  *                                    any).  If NULL, no value is returned.
2473446Smrj  *
2483446Smrj  * RETURN:      Status
2493446Smrj  *
2503446Smrj  * DESCRIPTION: Find and evaluate the given object, passing the given
2513446Smrj  *              parameters if necessary.  One of "Handle" or "Pathname" must
2523446Smrj  *              be valid (non-null)
2533446Smrj  *
2543446Smrj  ******************************************************************************/
2553446Smrj 
2563446Smrj ACPI_STATUS
2573446Smrj AcpiEvaluateObject (
2583446Smrj     ACPI_HANDLE             Handle,
2593446Smrj     ACPI_STRING             Pathname,
2603446Smrj     ACPI_OBJECT_LIST        *ExternalParams,
2613446Smrj     ACPI_BUFFER             *ReturnBuffer)
2623446Smrj {
2633446Smrj     ACPI_STATUS             Status;
2643446Smrj     ACPI_EVALUATE_INFO      *Info;
2653446Smrj     ACPI_SIZE               BufferSpaceNeeded;
2663446Smrj     UINT32                  i;
2673446Smrj 
2683446Smrj 
2693446Smrj     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
2703446Smrj 
2713446Smrj 
2723446Smrj     /* Allocate and initialize the evaluation information block */
2733446Smrj 
2743446Smrj     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
2753446Smrj     if (!Info)
2763446Smrj     {
2773446Smrj         return_ACPI_STATUS (AE_NO_MEMORY);
2783446Smrj     }
2793446Smrj 
2803446Smrj     Info->Pathname = Pathname;
2813446Smrj 
2823446Smrj     /* Convert and validate the device handle */
2833446Smrj 
2843446Smrj     Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
2853446Smrj     if (!Info->PrefixNode)
2863446Smrj     {
2873446Smrj         Status = AE_BAD_PARAMETER;
2883446Smrj         goto Cleanup;
2893446Smrj     }
2903446Smrj 
2913446Smrj     /*
2923446Smrj      * If there are parameters to be passed to a control method, the external
2933446Smrj      * objects must all be converted to internal objects
2943446Smrj      */
2953446Smrj     if (ExternalParams && ExternalParams->Count)
2963446Smrj     {
2973446Smrj         /*
2983446Smrj          * Allocate a new parameter block for the internal objects
2993446Smrj          * Add 1 to count to allow for null terminated internal list
3003446Smrj          */
3013446Smrj         Info->Parameters = ACPI_ALLOCATE_ZEROED (
3023446Smrj             ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
3033446Smrj         if (!Info->Parameters)
3043446Smrj         {
3053446Smrj             Status = AE_NO_MEMORY;
3063446Smrj             goto Cleanup;
3073446Smrj         }
3083446Smrj 
3093446Smrj         /* Convert each external object in the list to an internal object */
3103446Smrj 
3113446Smrj         for (i = 0; i < ExternalParams->Count; i++)
3123446Smrj         {
3133446Smrj             Status = AcpiUtCopyEobjectToIobject (
3143446Smrj                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
3153446Smrj             if (ACPI_FAILURE (Status))
3163446Smrj             {
3173446Smrj                 goto Cleanup;
3183446Smrj             }
3193446Smrj         }
3203446Smrj         Info->Parameters[ExternalParams->Count] = NULL;
3213446Smrj     }
3223446Smrj 
3233446Smrj     /*
3243446Smrj      * Three major cases:
3253446Smrj      * 1) Fully qualified pathname
3263446Smrj      * 2) No handle, not fully qualified pathname (error)
3273446Smrj      * 3) Valid handle
3283446Smrj      */
3293446Smrj     if ((Pathname) &&
3303446Smrj         (AcpiNsValidRootPrefix (Pathname[0])))
3313446Smrj     {
3323446Smrj         /* The path is fully qualified, just evaluate by name */
3333446Smrj 
3343446Smrj         Info->PrefixNode = NULL;
3353446Smrj         Status = AcpiNsEvaluate (Info);
3363446Smrj     }
3373446Smrj     else if (!Handle)
3383446Smrj     {
3393446Smrj         /*
3403446Smrj          * A handle is optional iff a fully qualified pathname is specified.
3413446Smrj          * Since we've already handled fully qualified names above, this is
3423446Smrj          * an error
3433446Smrj          */
3443446Smrj         if (!Pathname)
3453446Smrj         {
3463446Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
3473446Smrj                 "Both Handle and Pathname are NULL"));
3483446Smrj         }
3493446Smrj         else
3503446Smrj         {
3513446Smrj             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
3523446Smrj                 "Null Handle with relative pathname [%s]", Pathname));
3533446Smrj         }
3543446Smrj 
3553446Smrj         Status = AE_BAD_PARAMETER;
3563446Smrj     }
3573446Smrj     else
3583446Smrj     {
3593446Smrj         /* We have a namespace a node and a possible relative path */
3603446Smrj 
3613446Smrj         Status = AcpiNsEvaluate (Info);
3623446Smrj     }
3633446Smrj 
3643446Smrj     /*
3653446Smrj      * If we are expecting a return value, and all went well above,
3663446Smrj      * copy the return value to an external object.
3673446Smrj      */
3683446Smrj     if (ReturnBuffer)
3693446Smrj     {
3703446Smrj         if (!Info->ReturnObject)
3713446Smrj         {
3723446Smrj             ReturnBuffer->Length = 0;
3733446Smrj         }
3743446Smrj         else
3753446Smrj         {
3763446Smrj             if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
3773446Smrj                 ACPI_DESC_TYPE_NAMED)
3783446Smrj             {
3793446Smrj                 /*
3803446Smrj                  * If we received a NS Node as a return object, this means that
3813446Smrj                  * the object we are evaluating has nothing interesting to
3823446Smrj                  * return (such as a mutex, etc.)  We return an error because
3833446Smrj                  * these types are essentially unsupported by this interface.
3843446Smrj                  * We don't check up front because this makes it easier to add
3853446Smrj                  * support for various types at a later date if necessary.
3863446Smrj                  */
3873446Smrj                 Status = AE_TYPE;
3883446Smrj                 Info->ReturnObject = NULL;   /* No need to delete a NS Node */
3893446Smrj                 ReturnBuffer->Length = 0;
3903446Smrj             }
3913446Smrj 
3923446Smrj             if (ACPI_SUCCESS (Status))
3933446Smrj             {
3947851SDana.Myers@Sun.COM                 /* Dereference Index and RefOf references */
3957851SDana.Myers@Sun.COM 
3967851SDana.Myers@Sun.COM                 AcpiNsResolveReferences (Info);
3977851SDana.Myers@Sun.COM 
3983446Smrj                 /* Get the size of the returned object */
3993446Smrj 
4003446Smrj                 Status = AcpiUtGetObjectSize (Info->ReturnObject,
4013446Smrj                             &BufferSpaceNeeded);
4023446Smrj                 if (ACPI_SUCCESS (Status))
4033446Smrj                 {
4043446Smrj                     /* Validate/Allocate/Clear caller buffer */
4053446Smrj 
4063446Smrj                     Status = AcpiUtInitializeBuffer (ReturnBuffer,
4073446Smrj                                 BufferSpaceNeeded);
4083446Smrj                     if (ACPI_FAILURE (Status))
4093446Smrj                     {
4103446Smrj                         /*
4113446Smrj                          * Caller's buffer is too small or a new one can't
4123446Smrj                          * be allocated
4133446Smrj                          */
4143446Smrj                         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
4153446Smrj                             "Needed buffer size %X, %s\n",
4163446Smrj                             (UINT32) BufferSpaceNeeded,
4173446Smrj                             AcpiFormatException (Status)));
4183446Smrj                     }
4193446Smrj                     else
4203446Smrj                     {
4213446Smrj                         /* We have enough space for the object, build it */
4223446Smrj 
4233446Smrj                         Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
4243446Smrj                                     ReturnBuffer);
4253446Smrj                     }
4263446Smrj                 }
4273446Smrj             }
4283446Smrj         }
4293446Smrj     }
4303446Smrj 
4313446Smrj     if (Info->ReturnObject)
4323446Smrj     {
4333446Smrj         /*
4343446Smrj          * Delete the internal return object. NOTE: Interpreter must be
4353446Smrj          * locked to avoid race condition.
4363446Smrj          */
4377851SDana.Myers@Sun.COM         AcpiExEnterInterpreter ();
4383446Smrj 
4397851SDana.Myers@Sun.COM         /* Remove one reference on the return object (should delete it) */
4407851SDana.Myers@Sun.COM 
4417851SDana.Myers@Sun.COM         AcpiUtRemoveReference (Info->ReturnObject);
4427851SDana.Myers@Sun.COM         AcpiExExitInterpreter ();
4433446Smrj     }
4443446Smrj 
4453446Smrj 
4463446Smrj Cleanup:
4473446Smrj 
4483446Smrj     /* Free the input parameter list (if we created one) */
4493446Smrj 
4503446Smrj     if (Info->Parameters)
4513446Smrj     {
4523446Smrj         /* Free the allocated parameter block */
4533446Smrj 
4543446Smrj         AcpiUtDeleteInternalObjectList (Info->Parameters);
4553446Smrj     }
4563446Smrj 
4573446Smrj     ACPI_FREE (Info);
4583446Smrj     return_ACPI_STATUS (Status);
4593446Smrj }
4603446Smrj 
ACPI_EXPORT_SYMBOL(AcpiEvaluateObject)4613446Smrj ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
4623446Smrj 
4633446Smrj 
4643446Smrj /*******************************************************************************
4653446Smrj  *
4667851SDana.Myers@Sun.COM  * FUNCTION:    AcpiNsResolveReferences
4677851SDana.Myers@Sun.COM  *
4687851SDana.Myers@Sun.COM  * PARAMETERS:  Info                    - Evaluation info block
4697851SDana.Myers@Sun.COM  *
4707851SDana.Myers@Sun.COM  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
4717851SDana.Myers@Sun.COM  *
4727851SDana.Myers@Sun.COM  * DESCRIPTION: Dereference certain reference objects. Called before an
4737851SDana.Myers@Sun.COM  *              internal return object is converted to an external ACPI_OBJECT.
4747851SDana.Myers@Sun.COM  *
4757851SDana.Myers@Sun.COM  * Performs an automatic dereference of Index and RefOf reference objects.
4767851SDana.Myers@Sun.COM  * These reference objects are not supported by the ACPI_OBJECT, so this is a
4777851SDana.Myers@Sun.COM  * last resort effort to return something useful. Also, provides compatibility
4787851SDana.Myers@Sun.COM  * with other ACPI implementations.
4797851SDana.Myers@Sun.COM  *
4807851SDana.Myers@Sun.COM  * NOTE: does not handle references within returned package objects or nested
4817851SDana.Myers@Sun.COM  * references, but this support could be added later if found to be necessary.
4827851SDana.Myers@Sun.COM  *
4837851SDana.Myers@Sun.COM  ******************************************************************************/
4847851SDana.Myers@Sun.COM 
4857851SDana.Myers@Sun.COM static void
4867851SDana.Myers@Sun.COM AcpiNsResolveReferences (
4877851SDana.Myers@Sun.COM     ACPI_EVALUATE_INFO      *Info)
4887851SDana.Myers@Sun.COM {
4897851SDana.Myers@Sun.COM     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
4907851SDana.Myers@Sun.COM     ACPI_NAMESPACE_NODE     *Node;
4917851SDana.Myers@Sun.COM 
4927851SDana.Myers@Sun.COM 
4937851SDana.Myers@Sun.COM     /* We are interested in reference objects only */
4947851SDana.Myers@Sun.COM 
4959980SDana.Myers@Sun.COM     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
4967851SDana.Myers@Sun.COM     {
4977851SDana.Myers@Sun.COM         return;
4987851SDana.Myers@Sun.COM     }
4997851SDana.Myers@Sun.COM 
5007851SDana.Myers@Sun.COM     /*
5017851SDana.Myers@Sun.COM      * Two types of references are supported - those created by Index and
5027851SDana.Myers@Sun.COM      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
5037851SDana.Myers@Sun.COM      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
5047851SDana.Myers@Sun.COM      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
5057851SDana.Myers@Sun.COM      * an ACPI_OBJECT.
5067851SDana.Myers@Sun.COM      */
5077851SDana.Myers@Sun.COM     switch (Info->ReturnObject->Reference.Class)
5087851SDana.Myers@Sun.COM     {
5097851SDana.Myers@Sun.COM     case ACPI_REFCLASS_INDEX:
5107851SDana.Myers@Sun.COM 
5117851SDana.Myers@Sun.COM         ObjDesc = *(Info->ReturnObject->Reference.Where);
5127851SDana.Myers@Sun.COM         break;
5137851SDana.Myers@Sun.COM 
5147851SDana.Myers@Sun.COM     case ACPI_REFCLASS_REFOF:
5157851SDana.Myers@Sun.COM 
5167851SDana.Myers@Sun.COM         Node = Info->ReturnObject->Reference.Object;
5177851SDana.Myers@Sun.COM         if (Node)
5187851SDana.Myers@Sun.COM         {
5197851SDana.Myers@Sun.COM             ObjDesc = Node->Object;
5207851SDana.Myers@Sun.COM         }
5217851SDana.Myers@Sun.COM         break;
5227851SDana.Myers@Sun.COM 
5237851SDana.Myers@Sun.COM     default:
5247851SDana.Myers@Sun.COM         return;
5257851SDana.Myers@Sun.COM     }
5267851SDana.Myers@Sun.COM 
5277851SDana.Myers@Sun.COM     /* Replace the existing reference object */
5287851SDana.Myers@Sun.COM 
5297851SDana.Myers@Sun.COM     if (ObjDesc)
5307851SDana.Myers@Sun.COM     {
5317851SDana.Myers@Sun.COM         AcpiUtAddReference (ObjDesc);
5327851SDana.Myers@Sun.COM         AcpiUtRemoveReference (Info->ReturnObject);
5337851SDana.Myers@Sun.COM         Info->ReturnObject = ObjDesc;
5347851SDana.Myers@Sun.COM     }
5357851SDana.Myers@Sun.COM 
5367851SDana.Myers@Sun.COM     return;
5377851SDana.Myers@Sun.COM }
5387851SDana.Myers@Sun.COM 
5397851SDana.Myers@Sun.COM 
5407851SDana.Myers@Sun.COM /*******************************************************************************
5417851SDana.Myers@Sun.COM  *
5423446Smrj  * FUNCTION:    AcpiWalkNamespace
5433446Smrj  *
5443446Smrj  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
5453446Smrj  *              StartObject         - Handle in namespace where search begins
5463446Smrj  *              MaxDepth            - Depth to which search is to reach
547*11225SDana.Myers@Sun.COM  *              PreOrderVisit       - Called during tree pre-order visit
548*11225SDana.Myers@Sun.COM  *                                    when an object of "Type" is found
549*11225SDana.Myers@Sun.COM  *              PostOrderVisit      - Called during tree post-order visit
550*11225SDana.Myers@Sun.COM  *                                    when an object of "Type" is found
551*11225SDana.Myers@Sun.COM  *              Context             - Passed to user function(s) above
5523446Smrj  *              ReturnValue         - Location where return value of
5533446Smrj  *                                    UserFunction is put if terminated early
5543446Smrj  *
5553446Smrj  * RETURNS      Return value from the UserFunction if terminated early.
5563446Smrj  *              Otherwise, returns NULL.
5573446Smrj  *
5583446Smrj  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
5593446Smrj  *              starting (and ending) at the object specified by StartHandle.
560*11225SDana.Myers@Sun.COM  *              The callback function is called whenever an object that matches
561*11225SDana.Myers@Sun.COM  *              the type parameter is found. If the callback function returns
5623446Smrj  *              a non-zero value, the search is terminated immediately and this
5633446Smrj  *              value is returned to the caller.
5643446Smrj  *
5653446Smrj  *              The point of this procedure is to provide a generic namespace
5663446Smrj  *              walk routine that can be called from multiple places to
567*11225SDana.Myers@Sun.COM  *              provide multiple services; the callback function(s) can be
568*11225SDana.Myers@Sun.COM  *              tailored to each task, whether it is a print function,
569*11225SDana.Myers@Sun.COM  *              a compare function, etc.
5703446Smrj  *
5713446Smrj  ******************************************************************************/
5723446Smrj 
5733446Smrj ACPI_STATUS
AcpiWalkNamespace(ACPI_OBJECT_TYPE Type,ACPI_HANDLE StartObject,UINT32 MaxDepth,ACPI_WALK_CALLBACK PreOrderVisit,ACPI_WALK_CALLBACK PostOrderVisit,void * Context,void ** ReturnValue)5743446Smrj AcpiWalkNamespace (
5753446Smrj     ACPI_OBJECT_TYPE        Type,
5763446Smrj     ACPI_HANDLE             StartObject,
5773446Smrj     UINT32                  MaxDepth,
578*11225SDana.Myers@Sun.COM     ACPI_WALK_CALLBACK      PreOrderVisit,
579*11225SDana.Myers@Sun.COM     ACPI_WALK_CALLBACK      PostOrderVisit,
5803446Smrj     void                    *Context,
5813446Smrj     void                    **ReturnValue)
5823446Smrj {
5833446Smrj     ACPI_STATUS             Status;
5843446Smrj 
5853446Smrj 
5863446Smrj     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
5873446Smrj 
5883446Smrj 
5893446Smrj     /* Parameter validation */
5903446Smrj 
5913446Smrj     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
5923446Smrj         (!MaxDepth)                  ||
593*11225SDana.Myers@Sun.COM         (!PreOrderVisit && !PostOrderVisit))
5943446Smrj     {
5953446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
5963446Smrj     }
5973446Smrj 
5983446Smrj     /*
5999980SDana.Myers@Sun.COM      * Need to acquire the namespace reader lock to prevent interference
6009980SDana.Myers@Sun.COM      * with any concurrent table unloads (which causes the deletion of
6019980SDana.Myers@Sun.COM      * namespace objects). We cannot allow the deletion of a namespace node
6029980SDana.Myers@Sun.COM      * while the user function is using it. The exception to this are the
6039980SDana.Myers@Sun.COM      * nodes created and deleted during control method execution -- these
6049980SDana.Myers@Sun.COM      * nodes are marked as temporary nodes and are ignored by the namespace
6059980SDana.Myers@Sun.COM      * walk. Thus, control methods can be executed while holding the
6069980SDana.Myers@Sun.COM      * namespace deletion lock (and the user function can execute control
6079980SDana.Myers@Sun.COM      * methods.)
6089980SDana.Myers@Sun.COM      */
6099980SDana.Myers@Sun.COM     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
6109980SDana.Myers@Sun.COM     if (ACPI_FAILURE (Status))
6119980SDana.Myers@Sun.COM     {
6129980SDana.Myers@Sun.COM         return (Status);
6139980SDana.Myers@Sun.COM     }
6149980SDana.Myers@Sun.COM 
6159980SDana.Myers@Sun.COM     /*
6169980SDana.Myers@Sun.COM      * Lock the namespace around the walk. The namespace will be
6179980SDana.Myers@Sun.COM      * unlocked/locked around each call to the user function - since the user
6189980SDana.Myers@Sun.COM      * function must be allowed to make ACPICA calls itself (for example, it
6199980SDana.Myers@Sun.COM      * will typically execute control methods during device enumeration.)
6203446Smrj      */
6213446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
6223446Smrj     if (ACPI_FAILURE (Status))
6233446Smrj     {
6249980SDana.Myers@Sun.COM         goto UnlockAndExit;
6253446Smrj     }
6263446Smrj 
6273446Smrj     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
628*11225SDana.Myers@Sun.COM                 ACPI_NS_WALK_UNLOCK, PreOrderVisit,
629*11225SDana.Myers@Sun.COM                 PostOrderVisit, Context, ReturnValue);
6303446Smrj 
6313446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
6329980SDana.Myers@Sun.COM 
6339980SDana.Myers@Sun.COM UnlockAndExit:
6349980SDana.Myers@Sun.COM     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
6353446Smrj     return_ACPI_STATUS (Status);
6363446Smrj }
6373446Smrj 
ACPI_EXPORT_SYMBOL(AcpiWalkNamespace)6383446Smrj ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
6393446Smrj 
6403446Smrj 
6413446Smrj /*******************************************************************************
6423446Smrj  *
6433446Smrj  * FUNCTION:    AcpiNsGetDeviceCallback
6443446Smrj  *
6453446Smrj  * PARAMETERS:  Callback from AcpiGetDevice
6463446Smrj  *
6473446Smrj  * RETURN:      Status
6483446Smrj  *
6493446Smrj  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
6503446Smrj  *              present devices, or if they specified a HID, it filters based
6513446Smrj  *              on that.
6523446Smrj  *
6533446Smrj  ******************************************************************************/
6543446Smrj 
6553446Smrj static ACPI_STATUS
6563446Smrj AcpiNsGetDeviceCallback (
6573446Smrj     ACPI_HANDLE             ObjHandle,
6583446Smrj     UINT32                  NestingLevel,
6593446Smrj     void                    *Context,
6603446Smrj     void                    **ReturnValue)
6613446Smrj {
6623446Smrj     ACPI_GET_DEVICES_INFO   *Info = Context;
6633446Smrj     ACPI_STATUS             Status;
6643446Smrj     ACPI_NAMESPACE_NODE     *Node;
6653446Smrj     UINT32                  Flags;
666*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID          *Hid;
667*11225SDana.Myers@Sun.COM     ACPI_DEVICE_ID_LIST     *Cid;
6687851SDana.Myers@Sun.COM     UINT32                  i;
6697851SDana.Myers@Sun.COM     BOOLEAN                 Found;
670*11225SDana.Myers@Sun.COM     int                     NoMatch;
6713446Smrj 
6723446Smrj 
6733446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
6743446Smrj     if (ACPI_FAILURE (Status))
6753446Smrj     {
6763446Smrj         return (Status);
6773446Smrj     }
6783446Smrj 
6793446Smrj     Node = AcpiNsMapHandleToNode (ObjHandle);
6803446Smrj     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
6813446Smrj     if (ACPI_FAILURE (Status))
6823446Smrj     {
6833446Smrj         return (Status);
6843446Smrj     }
6853446Smrj 
6863446Smrj     if (!Node)
6873446Smrj     {
6883446Smrj         return (AE_BAD_PARAMETER);
6893446Smrj     }
6903446Smrj 
6913446Smrj     /* Run _STA to determine if device is present */
6923446Smrj 
6933446Smrj     Status = AcpiUtExecute_STA (Node, &Flags);
6943446Smrj     if (ACPI_FAILURE (Status))
6953446Smrj     {
6963446Smrj         return (AE_CTRL_DEPTH);
6973446Smrj     }
6983446Smrj 
6997851SDana.Myers@Sun.COM     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
7007851SDana.Myers@Sun.COM         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
7013446Smrj     {
7027851SDana.Myers@Sun.COM         /*
7037851SDana.Myers@Sun.COM          * Don't examine the children of the device only when the
7047851SDana.Myers@Sun.COM          * device is neither present nor functional. See ACPI spec,
7057851SDana.Myers@Sun.COM          * description of _STA for more information.
7067851SDana.Myers@Sun.COM          */
7073446Smrj         return (AE_CTRL_DEPTH);
7083446Smrj     }
7093446Smrj 
7103446Smrj     /* Filter based on device HID & CID */
7113446Smrj 
7123446Smrj     if (Info->Hid != NULL)
7133446Smrj     {
7143446Smrj         Status = AcpiUtExecute_HID (Node, &Hid);
7153446Smrj         if (Status == AE_NOT_FOUND)
7163446Smrj         {
7173446Smrj             return (AE_OK);
7183446Smrj         }
7193446Smrj         else if (ACPI_FAILURE (Status))
7203446Smrj         {
7213446Smrj             return (AE_CTRL_DEPTH);
7223446Smrj         }
7233446Smrj 
724*11225SDana.Myers@Sun.COM         NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
725*11225SDana.Myers@Sun.COM         ACPI_FREE (Hid);
726*11225SDana.Myers@Sun.COM 
727*11225SDana.Myers@Sun.COM         if (NoMatch)
7283446Smrj         {
7297851SDana.Myers@Sun.COM             /*
7307851SDana.Myers@Sun.COM              * HID does not match, attempt match within the
7317851SDana.Myers@Sun.COM              * list of Compatible IDs (CIDs)
7327851SDana.Myers@Sun.COM              */
7333446Smrj             Status = AcpiUtExecute_CID (Node, &Cid);
7343446Smrj             if (Status == AE_NOT_FOUND)
7353446Smrj             {
7363446Smrj                 return (AE_OK);
7373446Smrj             }
7383446Smrj             else if (ACPI_FAILURE (Status))
7393446Smrj             {
7403446Smrj                 return (AE_CTRL_DEPTH);
7413446Smrj             }
7423446Smrj 
7433446Smrj             /* Walk the CID list */
7443446Smrj 
7457851SDana.Myers@Sun.COM             Found = FALSE;
7463446Smrj             for (i = 0; i < Cid->Count; i++)
7473446Smrj             {
748*11225SDana.Myers@Sun.COM                 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
7493446Smrj                 {
7507851SDana.Myers@Sun.COM                     /* Found a matching CID */
7517851SDana.Myers@Sun.COM 
7527851SDana.Myers@Sun.COM                     Found = TRUE;
7537851SDana.Myers@Sun.COM                     break;
7543446Smrj                 }
7553446Smrj             }
7567851SDana.Myers@Sun.COM 
7573446Smrj             ACPI_FREE (Cid);
7587851SDana.Myers@Sun.COM             if (!Found)
7597851SDana.Myers@Sun.COM             {
7607851SDana.Myers@Sun.COM                 return (AE_OK);
7617851SDana.Myers@Sun.COM             }
7623446Smrj         }
7633446Smrj     }
7643446Smrj 
7657851SDana.Myers@Sun.COM     /* We have a valid device, invoke the user function */
7667851SDana.Myers@Sun.COM 
7673446Smrj     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
7683446Smrj                 ReturnValue);
7693446Smrj     return (Status);
7703446Smrj }
7713446Smrj 
7723446Smrj 
7733446Smrj /*******************************************************************************
7743446Smrj  *
7753446Smrj  * FUNCTION:    AcpiGetDevices
7763446Smrj  *
7773446Smrj  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
7783446Smrj  *              UserFunction        - Called when a matching object is found
7793446Smrj  *              Context             - Passed to user function
7803446Smrj  *              ReturnValue         - Location where return value of
7813446Smrj  *                                    UserFunction is put if terminated early
7823446Smrj  *
7833446Smrj  * RETURNS      Return value from the UserFunction if terminated early.
7843446Smrj  *              Otherwise, returns NULL.
7853446Smrj  *
7863446Smrj  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
7873446Smrj  *              starting (and ending) at the object specified by StartHandle.
7883446Smrj  *              The UserFunction is called whenever an object of type
7893446Smrj  *              Device is found.  If the user function returns
7903446Smrj  *              a non-zero value, the search is terminated immediately and this
7913446Smrj  *              value is returned to the caller.
7923446Smrj  *
7933446Smrj  *              This is a wrapper for WalkNamespace, but the callback performs
7947851SDana.Myers@Sun.COM  *              additional filtering. Please see AcpiNsGetDeviceCallback.
7953446Smrj  *
7963446Smrj  ******************************************************************************/
7973446Smrj 
7983446Smrj ACPI_STATUS
AcpiGetDevices(char * HID,ACPI_WALK_CALLBACK UserFunction,void * Context,void ** ReturnValue)7993446Smrj AcpiGetDevices (
8003446Smrj     char                    *HID,
8013446Smrj     ACPI_WALK_CALLBACK      UserFunction,
8023446Smrj     void                    *Context,
8033446Smrj     void                    **ReturnValue)
8043446Smrj {
8053446Smrj     ACPI_STATUS             Status;
8063446Smrj     ACPI_GET_DEVICES_INFO   Info;
8073446Smrj 
8083446Smrj 
8093446Smrj     ACPI_FUNCTION_TRACE (AcpiGetDevices);
8103446Smrj 
8113446Smrj 
8123446Smrj     /* Parameter validation */
8133446Smrj 
8143446Smrj     if (!UserFunction)
8153446Smrj     {
8163446Smrj         return_ACPI_STATUS (AE_BAD_PARAMETER);
8173446Smrj     }
8183446Smrj 
8193446Smrj     /*
8203446Smrj      * We're going to call their callback from OUR callback, so we need
8213446Smrj      * to know what it is, and their context parameter.
8223446Smrj      */
8233446Smrj     Info.Hid          = HID;
8243446Smrj     Info.Context      = Context;
8253446Smrj     Info.UserFunction = UserFunction;
8263446Smrj 
8273446Smrj     /*
8283446Smrj      * Lock the namespace around the walk.
8293446Smrj      * The namespace will be unlocked/locked around each call
8303446Smrj      * to the user function - since this function
8313446Smrj      * must be allowed to make Acpi calls itself.
8323446Smrj      */
8333446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
8343446Smrj     if (ACPI_FAILURE (Status))
8353446Smrj     {
8363446Smrj         return_ACPI_STATUS (Status);
8373446Smrj     }
8383446Smrj 
8393446Smrj     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
8403446Smrj                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
841*11225SDana.Myers@Sun.COM                 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
8423446Smrj 
8433446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
8443446Smrj     return_ACPI_STATUS (Status);
8453446Smrj }
8463446Smrj 
ACPI_EXPORT_SYMBOL(AcpiGetDevices)8473446Smrj ACPI_EXPORT_SYMBOL (AcpiGetDevices)
8483446Smrj 
8493446Smrj 
8503446Smrj /*******************************************************************************
8513446Smrj  *
8523446Smrj  * FUNCTION:    AcpiAttachData
8533446Smrj  *
8543446Smrj  * PARAMETERS:  ObjHandle           - Namespace node
8553446Smrj  *              Handler             - Handler for this attachment
8563446Smrj  *              Data                - Pointer to data to be attached
8573446Smrj  *
8583446Smrj  * RETURN:      Status
8593446Smrj  *
8603446Smrj  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
8613446Smrj  *
8623446Smrj  ******************************************************************************/
8633446Smrj 
8643446Smrj ACPI_STATUS
8653446Smrj AcpiAttachData (
8663446Smrj     ACPI_HANDLE             ObjHandle,
8673446Smrj     ACPI_OBJECT_HANDLER     Handler,
8683446Smrj     void                    *Data)
8693446Smrj {
8703446Smrj     ACPI_NAMESPACE_NODE     *Node;
8713446Smrj     ACPI_STATUS             Status;
8723446Smrj 
8733446Smrj 
8743446Smrj     /* Parameter validation */
8753446Smrj 
8763446Smrj     if (!ObjHandle  ||
8773446Smrj         !Handler    ||
8783446Smrj         !Data)
8793446Smrj     {
8803446Smrj         return (AE_BAD_PARAMETER);
8813446Smrj     }
8823446Smrj 
8833446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
8843446Smrj     if (ACPI_FAILURE (Status))
8853446Smrj     {
8863446Smrj         return (Status);
8873446Smrj     }
8883446Smrj 
8893446Smrj     /* Convert and validate the handle */
8903446Smrj 
8913446Smrj     Node = AcpiNsMapHandleToNode (ObjHandle);
8923446Smrj     if (!Node)
8933446Smrj     {
8943446Smrj         Status = AE_BAD_PARAMETER;
8953446Smrj         goto UnlockAndExit;
8963446Smrj     }
8973446Smrj 
8983446Smrj     Status = AcpiNsAttachData (Node, Handler, Data);
8993446Smrj 
9003446Smrj UnlockAndExit:
9013446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
9023446Smrj     return (Status);
9033446Smrj }
9043446Smrj 
ACPI_EXPORT_SYMBOL(AcpiAttachData)9053446Smrj ACPI_EXPORT_SYMBOL (AcpiAttachData)
9063446Smrj 
9073446Smrj 
9083446Smrj /*******************************************************************************
9093446Smrj  *
9103446Smrj  * FUNCTION:    AcpiDetachData
9113446Smrj  *
9123446Smrj  * PARAMETERS:  ObjHandle           - Namespace node handle
9133446Smrj  *              Handler             - Handler used in call to AcpiAttachData
9143446Smrj  *
9153446Smrj  * RETURN:      Status
9163446Smrj  *
9173446Smrj  * DESCRIPTION: Remove data that was previously attached to a node.
9183446Smrj  *
9193446Smrj  ******************************************************************************/
9203446Smrj 
9213446Smrj ACPI_STATUS
9223446Smrj AcpiDetachData (
9233446Smrj     ACPI_HANDLE             ObjHandle,
9243446Smrj     ACPI_OBJECT_HANDLER     Handler)
9253446Smrj {
9263446Smrj     ACPI_NAMESPACE_NODE     *Node;
9273446Smrj     ACPI_STATUS             Status;
9283446Smrj 
9293446Smrj 
9303446Smrj     /* Parameter validation */
9313446Smrj 
9323446Smrj     if (!ObjHandle  ||
9333446Smrj         !Handler)
9343446Smrj     {
9353446Smrj         return (AE_BAD_PARAMETER);
9363446Smrj     }
9373446Smrj 
9383446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
9393446Smrj     if (ACPI_FAILURE (Status))
9403446Smrj     {
9413446Smrj         return (Status);
9423446Smrj     }
9433446Smrj 
9443446Smrj     /* Convert and validate the handle */
9453446Smrj 
9463446Smrj     Node = AcpiNsMapHandleToNode (ObjHandle);
9473446Smrj     if (!Node)
9483446Smrj     {
9493446Smrj         Status = AE_BAD_PARAMETER;
9503446Smrj         goto UnlockAndExit;
9513446Smrj     }
9523446Smrj 
9533446Smrj     Status = AcpiNsDetachData (Node, Handler);
9543446Smrj 
9553446Smrj UnlockAndExit:
9563446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
9573446Smrj     return (Status);
9583446Smrj }
9593446Smrj 
ACPI_EXPORT_SYMBOL(AcpiDetachData)9603446Smrj ACPI_EXPORT_SYMBOL (AcpiDetachData)
9613446Smrj 
9623446Smrj 
9633446Smrj /*******************************************************************************
9643446Smrj  *
9653446Smrj  * FUNCTION:    AcpiGetData
9663446Smrj  *
9673446Smrj  * PARAMETERS:  ObjHandle           - Namespace node
9683446Smrj  *              Handler             - Handler used in call to AttachData
9693446Smrj  *              Data                - Where the data is returned
9703446Smrj  *
9713446Smrj  * RETURN:      Status
9723446Smrj  *
9733446Smrj  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
9743446Smrj  *
9753446Smrj  ******************************************************************************/
9763446Smrj 
9773446Smrj ACPI_STATUS
9783446Smrj AcpiGetData (
9793446Smrj     ACPI_HANDLE             ObjHandle,
9803446Smrj     ACPI_OBJECT_HANDLER     Handler,
9813446Smrj     void                    **Data)
9823446Smrj {
9833446Smrj     ACPI_NAMESPACE_NODE     *Node;
9843446Smrj     ACPI_STATUS             Status;
9853446Smrj 
9863446Smrj 
9873446Smrj     /* Parameter validation */
9883446Smrj 
9893446Smrj     if (!ObjHandle  ||
9903446Smrj         !Handler    ||
9913446Smrj         !Data)
9923446Smrj     {
9933446Smrj         return (AE_BAD_PARAMETER);
9943446Smrj     }
9953446Smrj 
9963446Smrj     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
9973446Smrj     if (ACPI_FAILURE (Status))
9983446Smrj     {
9993446Smrj         return (Status);
10003446Smrj     }
10013446Smrj 
10023446Smrj     /* Convert and validate the handle */
10033446Smrj 
10043446Smrj     Node = AcpiNsMapHandleToNode (ObjHandle);
10053446Smrj     if (!Node)
10063446Smrj     {
10073446Smrj         Status = AE_BAD_PARAMETER;
10083446Smrj         goto UnlockAndExit;
10093446Smrj     }
10103446Smrj 
10113446Smrj     Status = AcpiNsGetAttachedData (Node, Handler, Data);
10123446Smrj 
10133446Smrj UnlockAndExit:
10143446Smrj     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
10153446Smrj     return (Status);
10163446Smrj }
10173446Smrj 
10183446Smrj ACPI_EXPORT_SYMBOL (AcpiGetData)
10193446Smrj 
10203446Smrj 
1021