Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/acpica/nsxfeval.c need to be fixed.

0001 /*******************************************************************************
0002  *
0003  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
0004  *                         ACPI Object evaluation interfaces
0005  *
0006  ******************************************************************************/
0007 
0008 /******************************************************************************
0009  *
0010  * 1. Copyright Notice
0011  *
0012  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0013  * All rights reserved.
0014  *
0015  * 2. License
0016  *
0017  * 2.1. This is your license from Intel Corp. under its intellectual property
0018  * rights.  You may have additional license terms from the party that provided
0019  * you this software, covering your right to use that party's intellectual
0020  * property rights.
0021  *
0022  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0023  * copy of the source code appearing in this file ("Covered Code") an
0024  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0025  * base code distributed originally by Intel ("Original Intel Code") to copy,
0026  * make derivatives, distribute, use and display any portion of the Covered
0027  * Code in any form, with the right to sublicense such rights; and
0028  *
0029  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0030  * license (with the right to sublicense), under only those claims of Intel
0031  * patents that are infringed by the Original Intel Code, to make, use, sell,
0032  * offer to sell, and import the Covered Code and derivative works thereof
0033  * solely to the minimum extent necessary to exercise the above copyright
0034  * license, and in no event shall the patent license extend to any additions
0035  * to or modifications of the Original Intel Code.  No other license or right
0036  * is granted directly or by implication, estoppel or otherwise;
0037  *
0038  * The above copyright and patent license is granted only if the following
0039  * conditions are met:
0040  *
0041  * 3. Conditions
0042  *
0043  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0044  * Redistribution of source code of any substantial portion of the Covered
0045  * Code or modification with rights to further distribute source must include
0046  * the above Copyright Notice, the above License, this list of Conditions,
0047  * and the following Disclaimer and Export Compliance provision.  In addition,
0048  * Licensee must cause all Covered Code to which Licensee contributes to
0049  * contain a file documenting the changes Licensee made to create that Covered
0050  * Code and the date of any change.  Licensee must include in that file the
0051  * documentation of any changes made by any predecessor Licensee.  Licensee
0052  * must include a prominent statement that the modification is derived,
0053  * directly or indirectly, from Original Intel Code.
0054  *
0055  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0056  * Redistribution of source code of any substantial portion of the Covered
0057  * Code or modification without rights to further distribute source must
0058  * include the following Disclaimer and Export Compliance provision in the
0059  * documentation and/or other materials provided with distribution.  In
0060  * addition, Licensee may not authorize further sublicense of source of any
0061  * portion of the Covered Code, and must include terms to the effect that the
0062  * license from Licensee to its licensee is limited to the intellectual
0063  * property embodied in the software Licensee provides to its licensee, and
0064  * not to intellectual property embodied in modifications its licensee may
0065  * make.
0066  *
0067  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0068  * substantial portion of the Covered Code or modification must reproduce the
0069  * above Copyright Notice, and the following Disclaimer and Export Compliance
0070  * provision in the documentation and/or other materials provided with the
0071  * distribution.
0072  *
0073  * 3.4. Intel retains all right, title, and interest in and to the Original
0074  * Intel Code.
0075  *
0076  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0077  * Intel shall be used in advertising or otherwise to promote the sale, use or
0078  * other dealings in products derived from or relating to the Covered Code
0079  * without prior written authorization from Intel.
0080  *
0081  * 4. Disclaimer and Export Compliance
0082  *
0083  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0084  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0085  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0086  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0087  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0088  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0089  * PARTICULAR PURPOSE.
0090  *
0091  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0092  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0093  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0094  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0095  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0096  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0097  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0098  * LIMITED REMEDY.
0099  *
0100  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0101  * software or system incorporating such software without first obtaining any
0102  * required license or other approval from the U. S. Department of Commerce or
0103  * any other agency or department of the United States Government.  In the
0104  * event Licensee exports any such software from the United States or
0105  * re-exports any such software from a foreign destination, Licensee shall
0106  * ensure that the distribution and export/re-export of the software is in
0107  * compliance with all laws, regulations, orders, or other restrictions of the
0108  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0109  * any of its subsidiaries will export/re-export any technical data, process,
0110  * software, or service, directly or indirectly, to any country for which the
0111  * United States government or any agency thereof requires an export license,
0112  * other governmental approval, or letter of assurance, without first obtaining
0113  * such license, approval or letter.
0114  *
0115  *****************************************************************************/
0116 
0117 
0118 #define __NSXFEVAL_C__
0119 
0120 #include "acpi.h"
0121 #include "accommon.h"
0122 #include "acnamesp.h"
0123 #include "acinterp.h"
0124 
0125 
0126 #define _COMPONENT          ACPI_NAMESPACE
0127         ACPI_MODULE_NAME    ("nsxfeval")
0128 
0129 /* Local prototypes */
0130 
0131 static void
0132 AcpiNsResolveReferences (
0133     ACPI_EVALUATE_INFO      *Info);
0134 
0135 
0136 /*******************************************************************************
0137  *
0138  * FUNCTION:    AcpiEvaluateObjectTyped
0139  *
0140  * PARAMETERS:  Handle              - Object handle (optional)
0141  *              Pathname            - Object pathname (optional)
0142  *              ExternalParams      - List of parameters to pass to method,
0143  *                                    terminated by NULL.  May be NULL
0144  *                                    if no parameters are being passed.
0145  *              ReturnBuffer        - Where to put method's return value (if
0146  *                                    any).  If NULL, no value is returned.
0147  *              ReturnType          - Expected type of return object
0148  *
0149  * RETURN:      Status
0150  *
0151  * DESCRIPTION: Find and evaluate the given object, passing the given
0152  *              parameters if necessary.  One of "Handle" or "Pathname" must
0153  *              be valid (non-null)
0154  *
0155  ******************************************************************************/
0156 
0157 ACPI_STATUS
0158 AcpiEvaluateObjectTyped (
0159     ACPI_HANDLE             Handle,
0160     ACPI_STRING             Pathname,
0161     ACPI_OBJECT_LIST        *ExternalParams,
0162     ACPI_BUFFER             *ReturnBuffer,
0163     ACPI_OBJECT_TYPE        ReturnType)
0164 {
0165     ACPI_STATUS             Status;
0166     BOOLEAN                 MustFree = FALSE;
0167 
0168 
0169     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
0170 
0171 
0172     /* Return buffer must be valid */
0173 
0174     if (!ReturnBuffer)
0175     {
0176         return_ACPI_STATUS (AE_BAD_PARAMETER);
0177     }
0178 
0179     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
0180     {
0181         MustFree = TRUE;
0182     }
0183 
0184     /* Evaluate the object */
0185 
0186     Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
0187     if (ACPI_FAILURE (Status))
0188     {
0189         return_ACPI_STATUS (Status);
0190     }
0191 
0192     /* Type ANY means "don't care" */
0193 
0194     if (ReturnType == ACPI_TYPE_ANY)
0195     {
0196         return_ACPI_STATUS (AE_OK);
0197     }
0198 
0199     if (ReturnBuffer->Length == 0)
0200     {
0201         /* Error because caller specifically asked for a return value */
0202 
0203         ACPI_ERROR ((AE_INFO, "No return value"));
0204         return_ACPI_STATUS (AE_NULL_OBJECT);
0205     }
0206 
0207     /* Examine the object type returned from EvaluateObject */
0208 
0209     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
0210     {
0211         return_ACPI_STATUS (AE_OK);
0212     }
0213 
0214     /* Return object type does not match requested type */
0215 
0216     ACPI_ERROR ((AE_INFO,
0217         "Incorrect return type [%s] requested [%s]",
0218         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
0219         AcpiUtGetTypeName (ReturnType)));
0220 
0221     if (MustFree)
0222     {
0223         /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
0224 
0225         AcpiOsFree (ReturnBuffer->Pointer);
0226         ReturnBuffer->Pointer = NULL;
0227     }
0228 
0229     ReturnBuffer->Length = 0;
0230     return_ACPI_STATUS (AE_TYPE);
0231 }
0232 
0233 ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
0234 
0235 
0236 /*******************************************************************************
0237  *
0238  * FUNCTION:    AcpiEvaluateObject
0239  *
0240  * PARAMETERS:  Handle              - Object handle (optional)
0241  *              Pathname            - Object pathname (optional)
0242  *              ExternalParams      - List of parameters to pass to method,
0243  *                                    terminated by NULL.  May be NULL
0244  *                                    if no parameters are being passed.
0245  *              ReturnBuffer        - Where to put method's return value (if
0246  *                                    any).  If NULL, no value is returned.
0247  *
0248  * RETURN:      Status
0249  *
0250  * DESCRIPTION: Find and evaluate the given object, passing the given
0251  *              parameters if necessary.  One of "Handle" or "Pathname" must
0252  *              be valid (non-null)
0253  *
0254  ******************************************************************************/
0255 
0256 ACPI_STATUS
0257 AcpiEvaluateObject (
0258     ACPI_HANDLE             Handle,
0259     ACPI_STRING             Pathname,
0260     ACPI_OBJECT_LIST        *ExternalParams,
0261     ACPI_BUFFER             *ReturnBuffer)
0262 {
0263     ACPI_STATUS             Status;
0264     ACPI_EVALUATE_INFO      *Info;
0265     ACPI_SIZE               BufferSpaceNeeded;
0266     UINT32                  i;
0267 
0268 
0269     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
0270 
0271 
0272     /* Allocate and initialize the evaluation information block */
0273 
0274     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
0275     if (!Info)
0276     {
0277         return_ACPI_STATUS (AE_NO_MEMORY);
0278     }
0279 
0280     Info->Pathname = Pathname;
0281 
0282     /* Convert and validate the device handle */
0283 
0284     Info->PrefixNode = AcpiNsMapHandleToNode (Handle);
0285     if (!Info->PrefixNode)
0286     {
0287         Status = AE_BAD_PARAMETER;
0288         goto Cleanup;
0289     }
0290 
0291     /*
0292      * If there are parameters to be passed to a control method, the external
0293      * objects must all be converted to internal objects
0294      */
0295     if (ExternalParams && ExternalParams->Count)
0296     {
0297         /*
0298          * Allocate a new parameter block for the internal objects
0299          * Add 1 to count to allow for null terminated internal list
0300          */
0301         Info->Parameters = ACPI_ALLOCATE_ZEROED (
0302             ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
0303         if (!Info->Parameters)
0304         {
0305             Status = AE_NO_MEMORY;
0306             goto Cleanup;
0307         }
0308 
0309         /* Convert each external object in the list to an internal object */
0310 
0311         for (i = 0; i < ExternalParams->Count; i++)
0312         {
0313             Status = AcpiUtCopyEobjectToIobject (
0314                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
0315             if (ACPI_FAILURE (Status))
0316             {
0317                 goto Cleanup;
0318             }
0319         }
0320         Info->Parameters[ExternalParams->Count] = NULL;
0321     }
0322 
0323     /*
0324      * Three major cases:
0325      * 1) Fully qualified pathname
0326      * 2) No handle, not fully qualified pathname (error)
0327      * 3) Valid handle
0328      */
0329     if ((Pathname) &&
0330         (AcpiNsValidRootPrefix (Pathname[0])))
0331     {
0332         /* The path is fully qualified, just evaluate by name */
0333 
0334         Info->PrefixNode = NULL;
0335         Status = AcpiNsEvaluate (Info);
0336     }
0337     else if (!Handle)
0338     {
0339         /*
0340          * A handle is optional iff a fully qualified pathname is specified.
0341          * Since we've already handled fully qualified names above, this is
0342          * an error
0343          */
0344         if (!Pathname)
0345         {
0346             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0347                 "Both Handle and Pathname are NULL"));
0348         }
0349         else
0350         {
0351             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0352                 "Null Handle with relative pathname [%s]", Pathname));
0353         }
0354 
0355         Status = AE_BAD_PARAMETER;
0356     }
0357     else
0358     {
0359         /* We have a namespace a node and a possible relative path */
0360 
0361         Status = AcpiNsEvaluate (Info);
0362     }
0363 
0364     /*
0365      * If we are expecting a return value, and all went well above,
0366      * copy the return value to an external object.
0367      */
0368     if (ReturnBuffer)
0369     {
0370         if (!Info->ReturnObject)
0371         {
0372             ReturnBuffer->Length = 0;
0373         }
0374         else
0375         {
0376             if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
0377                 ACPI_DESC_TYPE_NAMED)
0378             {
0379                 /*
0380                  * If we received a NS Node as a return object, this means that
0381                  * the object we are evaluating has nothing interesting to
0382                  * return (such as a mutex, etc.)  We return an error because
0383                  * these types are essentially unsupported by this interface.
0384                  * We don't check up front because this makes it easier to add
0385                  * support for various types at a later date if necessary.
0386                  */
0387                 Status = AE_TYPE;
0388                 Info->ReturnObject = NULL;   /* No need to delete a NS Node */
0389                 ReturnBuffer->Length = 0;
0390             }
0391 
0392             if (ACPI_SUCCESS (Status))
0393             {
0394                 /* Dereference Index and RefOf references */
0395 
0396                 AcpiNsResolveReferences (Info);
0397 
0398                 /* Get the size of the returned object */
0399 
0400                 Status = AcpiUtGetObjectSize (Info->ReturnObject,
0401                             &BufferSpaceNeeded);
0402                 if (ACPI_SUCCESS (Status))
0403                 {
0404                     /* Validate/Allocate/Clear caller buffer */
0405 
0406                     Status = AcpiUtInitializeBuffer (ReturnBuffer,
0407                                 BufferSpaceNeeded);
0408                     if (ACPI_FAILURE (Status))
0409                     {
0410                         /*
0411                          * Caller's buffer is too small or a new one can't
0412                          * be allocated
0413                          */
0414                         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
0415                             "Needed buffer size %X, %s\n",
0416                             (UINT32) BufferSpaceNeeded,
0417                             AcpiFormatException (Status)));
0418                     }
0419                     else
0420                     {
0421                         /* We have enough space for the object, build it */
0422 
0423                         Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
0424                                     ReturnBuffer);
0425                     }
0426                 }
0427             }
0428         }
0429     }
0430 
0431     if (Info->ReturnObject)
0432     {
0433         /*
0434          * Delete the internal return object. NOTE: Interpreter must be
0435          * locked to avoid race condition.
0436          */
0437         AcpiExEnterInterpreter ();
0438 
0439         /* Remove one reference on the return object (should delete it) */
0440 
0441         AcpiUtRemoveReference (Info->ReturnObject);
0442         AcpiExExitInterpreter ();
0443     }
0444 
0445 
0446 Cleanup:
0447 
0448     /* Free the input parameter list (if we created one) */
0449 
0450     if (Info->Parameters)
0451     {
0452         /* Free the allocated parameter block */
0453 
0454         AcpiUtDeleteInternalObjectList (Info->Parameters);
0455     }
0456 
0457     ACPI_FREE (Info);
0458     return_ACPI_STATUS (Status);
0459 }
0460 
0461 ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
0462 
0463 
0464 /*******************************************************************************
0465  *
0466  * FUNCTION:    AcpiNsResolveReferences
0467  *
0468  * PARAMETERS:  Info                    - Evaluation info block
0469  *
0470  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
0471  *
0472  * DESCRIPTION: Dereference certain reference objects. Called before an
0473  *              internal return object is converted to an external ACPI_OBJECT.
0474  *
0475  * Performs an automatic dereference of Index and RefOf reference objects.
0476  * These reference objects are not supported by the ACPI_OBJECT, so this is a
0477  * last resort effort to return something useful. Also, provides compatibility
0478  * with other ACPI implementations.
0479  *
0480  * NOTE: does not handle references within returned package objects or nested
0481  * references, but this support could be added later if found to be necessary.
0482  *
0483  ******************************************************************************/
0484 
0485 static void
0486 AcpiNsResolveReferences (
0487     ACPI_EVALUATE_INFO      *Info)
0488 {
0489     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
0490     ACPI_NAMESPACE_NODE     *Node;
0491 
0492 
0493     /* We are interested in reference objects only */
0494 
0495     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
0496     {
0497         return;
0498     }
0499 
0500     /*
0501      * Two types of references are supported - those created by Index and
0502      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
0503      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
0504      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
0505      * an ACPI_OBJECT.
0506      */
0507     switch (Info->ReturnObject->Reference.Class)
0508     {
0509     case ACPI_REFCLASS_INDEX:
0510 
0511         ObjDesc = *(Info->ReturnObject->Reference.Where);
0512         break;
0513 
0514     case ACPI_REFCLASS_REFOF:
0515 
0516         Node = Info->ReturnObject->Reference.Object;
0517         if (Node)
0518         {
0519             ObjDesc = Node->Object;
0520         }
0521         break;
0522 
0523     default:
0524         return;
0525     }
0526 
0527     /* Replace the existing reference object */
0528 
0529     if (ObjDesc)
0530     {
0531         AcpiUtAddReference (ObjDesc);
0532         AcpiUtRemoveReference (Info->ReturnObject);
0533         Info->ReturnObject = ObjDesc;
0534     }
0535 
0536     return;
0537 }
0538 
0539 
0540 /*******************************************************************************
0541  *
0542  * FUNCTION:    AcpiWalkNamespace
0543  *
0544  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
0545  *              StartObject         - Handle in namespace where search begins
0546  *              MaxDepth            - Depth to which search is to reach
0547  *              UserFunction        - Called when an object of "Type" is found
0548  *              Context             - Passed to user function
0549  *              ReturnValue         - Location where return value of
0550  *                                    UserFunction is put if terminated early
0551  *
0552  * RETURNS      Return value from the UserFunction if terminated early.
0553  *              Otherwise, returns NULL.
0554  *
0555  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
0556  *              starting (and ending) at the object specified by StartHandle.
0557  *              The UserFunction is called whenever an object that matches
0558  *              the type parameter is found.  If the user function returns
0559  *              a non-zero value, the search is terminated immediately and this
0560  *              value is returned to the caller.
0561  *
0562  *              The point of this procedure is to provide a generic namespace
0563  *              walk routine that can be called from multiple places to
0564  *              provide multiple services;  the User Function can be tailored
0565  *              to each task, whether it is a print function, a compare
0566  *              function, etc.
0567  *
0568  ******************************************************************************/
0569 
0570 ACPI_STATUS
0571 AcpiWalkNamespace (
0572     ACPI_OBJECT_TYPE        Type,
0573     ACPI_HANDLE             StartObject,
0574     UINT32                  MaxDepth,
0575     ACPI_WALK_CALLBACK      UserFunction,
0576     void                    *Context,
0577     void                    **ReturnValue)
0578 {
0579     ACPI_STATUS             Status;
0580 
0581 
0582     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
0583 
0584 
0585     /* Parameter validation */
0586 
0587     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
0588         (!MaxDepth)                  ||
0589         (!UserFunction))
0590     {
0591         return_ACPI_STATUS (AE_BAD_PARAMETER);
0592     }
0593 
0594     /*
0595      * Need to acquire the namespace reader lock to prevent interference
0596      * with any concurrent table unloads (which causes the deletion of
0597      * namespace objects). We cannot allow the deletion of a namespace node
0598      * while the user function is using it. The exception to this are the
0599      * nodes created and deleted during control method execution -- these
0600      * nodes are marked as temporary nodes and are ignored by the namespace
0601      * walk. Thus, control methods can be executed while holding the
0602      * namespace deletion lock (and the user function can execute control
0603      * methods.)
0604      */
0605     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
0606     if (ACPI_FAILURE (Status))
0607     {
0608         return (Status);
0609     }
0610 
0611     /*
0612      * Lock the namespace around the walk. The namespace will be
0613      * unlocked/locked around each call to the user function - since the user
0614      * function must be allowed to make ACPICA calls itself (for example, it
0615      * will typically execute control methods during device enumeration.)
0616      */
0617     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0618     if (ACPI_FAILURE (Status))
0619     {
0620         goto UnlockAndExit;
0621     }
0622 
0623     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
0624                 ACPI_NS_WALK_UNLOCK, UserFunction, Context, ReturnValue);
0625 
0626     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0627 
0628 UnlockAndExit:
0629     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
0630     return_ACPI_STATUS (Status);
0631 }
0632 
0633 ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
0634 
0635 
0636 /*******************************************************************************
0637  *
0638  * FUNCTION:    AcpiNsGetDeviceCallback
0639  *
0640  * PARAMETERS:  Callback from AcpiGetDevice
0641  *
0642  * RETURN:      Status
0643  *
0644  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
0645  *              present devices, or if they specified a HID, it filters based
0646  *              on that.
0647  *
0648  ******************************************************************************/
0649 
0650 static ACPI_STATUS
0651 AcpiNsGetDeviceCallback (
0652     ACPI_HANDLE             ObjHandle,
0653     UINT32                  NestingLevel,
0654     void                    *Context,
0655     void                    **ReturnValue)
0656 {
0657     ACPI_GET_DEVICES_INFO   *Info = Context;
0658     ACPI_STATUS             Status;
0659     ACPI_NAMESPACE_NODE     *Node;
0660     UINT32                  Flags;
0661     ACPI_DEVICE_ID          *Hid;
0662     ACPI_DEVICE_ID_LIST     *Cid;
0663     UINT32                  i;
0664     BOOLEAN                 Found;
0665     int                     Match;
0666 
0667 
0668     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0669     if (ACPI_FAILURE (Status))
0670     {
0671         return (Status);
0672     }
0673 
0674     Node = AcpiNsMapHandleToNode (ObjHandle);
0675     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0676     if (ACPI_FAILURE (Status))
0677     {
0678         return (Status);
0679     }
0680 
0681     if (!Node)
0682     {
0683         return (AE_BAD_PARAMETER);
0684     }
0685 
0686     /* Run _STA to determine if device is present */
0687 
0688     Status = AcpiUtExecute_STA (Node, &Flags);
0689     if (ACPI_FAILURE (Status))
0690     {
0691         return (AE_CTRL_DEPTH);
0692     }
0693 
0694     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
0695         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
0696     {
0697         /*
0698          * Don't examine the children of the device only when the
0699          * device is neither present nor functional. See ACPI spec,
0700          * description of _STA for more information.
0701          */
0702         return (AE_CTRL_DEPTH);
0703     }
0704 
0705     /* Filter based on device HID & CID */
0706 
0707     if (Info->Hid != NULL)
0708     {
0709         Status = AcpiUtExecute_HID (Node, &Hid);
0710         if (Status == AE_NOT_FOUND)
0711         {
0712             return (AE_OK);
0713         }
0714         else if (ACPI_FAILURE (Status))
0715         {
0716             return (AE_CTRL_DEPTH);
0717         }
0718 
0719         Match = ACPI_STRCMP (Hid->String, Info->Hid);
0720         ACPI_FREE (Hid);
0721 
0722         if (!Match)
0723         {
0724             /*
0725              * HID does not match, attempt match within the
0726              * list of Compatible IDs (CIDs)
0727              */
0728             Status = AcpiUtExecute_CID (Node, &Cid);
0729             if (Status == AE_NOT_FOUND)
0730             {
0731                 return (AE_OK);
0732             }
0733             else if (ACPI_FAILURE (Status))
0734             {
0735                 return (AE_CTRL_DEPTH);
0736             }
0737 
0738             /* Walk the CID list */
0739 
0740             Found = FALSE;
0741             for (i = 0; i < Cid->Count; i++)
0742             {
0743                 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
0744                 {
0745                     /* Found a matching CID */
0746 
0747                     Found = TRUE;
0748                     break;
0749                 }
0750             }
0751 
0752             ACPI_FREE (Cid);
0753             if (!Found)
0754             {
0755                 return (AE_OK);
0756             }
0757         }
0758     }
0759 
0760     /* We have a valid device, invoke the user function */
0761 
0762     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
0763                 ReturnValue);
0764     return (Status);
0765 }
0766 
0767 
0768 /*******************************************************************************
0769  *
0770  * FUNCTION:    AcpiGetDevices
0771  *
0772  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
0773  *              UserFunction        - Called when a matching object is found
0774  *              Context             - Passed to user function
0775  *              ReturnValue         - Location where return value of
0776  *                                    UserFunction is put if terminated early
0777  *
0778  * RETURNS      Return value from the UserFunction if terminated early.
0779  *              Otherwise, returns NULL.
0780  *
0781  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
0782  *              starting (and ending) at the object specified by StartHandle.
0783  *              The UserFunction is called whenever an object of type
0784  *              Device is found.  If the user function returns
0785  *              a non-zero value, the search is terminated immediately and this
0786  *              value is returned to the caller.
0787  *
0788  *              This is a wrapper for WalkNamespace, but the callback performs
0789  *              additional filtering. Please see AcpiNsGetDeviceCallback.
0790  *
0791  ******************************************************************************/
0792 
0793 ACPI_STATUS
0794 AcpiGetDevices (
0795     char                    *HID,
0796     ACPI_WALK_CALLBACK      UserFunction,
0797     void                    *Context,
0798     void                    **ReturnValue)
0799 {
0800     ACPI_STATUS             Status;
0801     ACPI_GET_DEVICES_INFO   Info;
0802 
0803 
0804     ACPI_FUNCTION_TRACE (AcpiGetDevices);
0805 
0806 
0807     /* Parameter validation */
0808 
0809     if (!UserFunction)
0810     {
0811         return_ACPI_STATUS (AE_BAD_PARAMETER);
0812     }
0813 
0814     /*
0815      * We're going to call their callback from OUR callback, so we need
0816      * to know what it is, and their context parameter.
0817      */
0818     Info.Hid          = HID;
0819     Info.Context      = Context;
0820     Info.UserFunction = UserFunction;
0821 
0822     /*
0823      * Lock the namespace around the walk.
0824      * The namespace will be unlocked/locked around each call
0825      * to the user function - since this function
0826      * must be allowed to make Acpi calls itself.
0827      */
0828     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0829     if (ACPI_FAILURE (Status))
0830     {
0831         return_ACPI_STATUS (Status);
0832     }
0833 
0834     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
0835                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
0836                 AcpiNsGetDeviceCallback, &Info, ReturnValue);
0837 
0838     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0839     return_ACPI_STATUS (Status);
0840 }
0841 
0842 ACPI_EXPORT_SYMBOL (AcpiGetDevices)
0843 
0844 
0845 /*******************************************************************************
0846  *
0847  * FUNCTION:    AcpiAttachData
0848  *
0849  * PARAMETERS:  ObjHandle           - Namespace node
0850  *              Handler             - Handler for this attachment
0851  *              Data                - Pointer to data to be attached
0852  *
0853  * RETURN:      Status
0854  *
0855  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
0856  *
0857  ******************************************************************************/
0858 
0859 ACPI_STATUS
0860 AcpiAttachData (
0861     ACPI_HANDLE             ObjHandle,
0862     ACPI_OBJECT_HANDLER     Handler,
0863     void                    *Data)
0864 {
0865     ACPI_NAMESPACE_NODE     *Node;
0866     ACPI_STATUS             Status;
0867 
0868 
0869     /* Parameter validation */
0870 
0871     if (!ObjHandle  ||
0872         !Handler    ||
0873         !Data)
0874     {
0875         return (AE_BAD_PARAMETER);
0876     }
0877 
0878     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0879     if (ACPI_FAILURE (Status))
0880     {
0881         return (Status);
0882     }
0883 
0884     /* Convert and validate the handle */
0885 
0886     Node = AcpiNsMapHandleToNode (ObjHandle);
0887     if (!Node)
0888     {
0889         Status = AE_BAD_PARAMETER;
0890         goto UnlockAndExit;
0891     }
0892 
0893     Status = AcpiNsAttachData (Node, Handler, Data);
0894 
0895 UnlockAndExit:
0896     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0897     return (Status);
0898 }
0899 
0900 ACPI_EXPORT_SYMBOL (AcpiAttachData)
0901 
0902 
0903 /*******************************************************************************
0904  *
0905  * FUNCTION:    AcpiDetachData
0906  *
0907  * PARAMETERS:  ObjHandle           - Namespace node handle
0908  *              Handler             - Handler used in call to AcpiAttachData
0909  *
0910  * RETURN:      Status
0911  *
0912  * DESCRIPTION: Remove data that was previously attached to a node.
0913  *
0914  ******************************************************************************/
0915 
0916 ACPI_STATUS
0917 AcpiDetachData (
0918     ACPI_HANDLE             ObjHandle,
0919     ACPI_OBJECT_HANDLER     Handler)
0920 {
0921     ACPI_NAMESPACE_NODE     *Node;
0922     ACPI_STATUS             Status;
0923 
0924 
0925     /* Parameter validation */
0926 
0927     if (!ObjHandle  ||
0928         !Handler)
0929     {
0930         return (AE_BAD_PARAMETER);
0931     }
0932 
0933     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0934     if (ACPI_FAILURE (Status))
0935     {
0936         return (Status);
0937     }
0938 
0939     /* Convert and validate the handle */
0940 
0941     Node = AcpiNsMapHandleToNode (ObjHandle);
0942     if (!Node)
0943     {
0944         Status = AE_BAD_PARAMETER;
0945         goto UnlockAndExit;
0946     }
0947 
0948     Status = AcpiNsDetachData (Node, Handler);
0949 
0950 UnlockAndExit:
0951     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0952     return (Status);
0953 }
0954 
0955 ACPI_EXPORT_SYMBOL (AcpiDetachData)
0956 
0957 
0958 /*******************************************************************************
0959  *
0960  * FUNCTION:    AcpiGetData
0961  *
0962  * PARAMETERS:  ObjHandle           - Namespace node
0963  *              Handler             - Handler used in call to AttachData
0964  *              Data                - Where the data is returned
0965  *
0966  * RETURN:      Status
0967  *
0968  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
0969  *
0970  ******************************************************************************/
0971 
0972 ACPI_STATUS
0973 AcpiGetData (
0974     ACPI_HANDLE             ObjHandle,
0975     ACPI_OBJECT_HANDLER     Handler,
0976     void                    **Data)
0977 {
0978     ACPI_NAMESPACE_NODE     *Node;
0979     ACPI_STATUS             Status;
0980 
0981 
0982     /* Parameter validation */
0983 
0984     if (!ObjHandle  ||
0985         !Handler    ||
0986         !Data)
0987     {
0988         return (AE_BAD_PARAMETER);
0989     }
0990 
0991     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0992     if (ACPI_FAILURE (Status))
0993     {
0994         return (Status);
0995     }
0996 
0997     /* Convert and validate the handle */
0998 
0999     Node = AcpiNsMapHandleToNode (ObjHandle);
1000     if (!Node)
1001     {
1002         Status = AE_BAD_PARAMETER;
1003         goto UnlockAndExit;
1004     }
1005 
1006     Status = AcpiNsGetAttachedData (Node, Handler, Data);
1007 
1008 UnlockAndExit:
1009     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1010     return (Status);
1011 }
1012 
1013 ACPI_EXPORT_SYMBOL (AcpiGetData)
1014 
1015