Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*******************************************************************************
  2.  *
  3.  * Module Name: nsxfeval - Public interfaces to the ACPI subsystem
  4.  *                         ACPI Object evaluation interfaces
  5.  *
  6.  ******************************************************************************/
  7.  
  8. /******************************************************************************
  9.  *
  10.  * 1. Copyright Notice
  11.  *
  12.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  13.  * All rights reserved.
  14.  *
  15.  * 2. License
  16.  *
  17.  * 2.1. This is your license from Intel Corp. under its intellectual property
  18.  * rights.  You may have additional license terms from the party that provided
  19.  * you this software, covering your right to use that party's intellectual
  20.  * property rights.
  21.  *
  22.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  23.  * copy of the source code appearing in this file ("Covered Code") an
  24.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  25.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  26.  * make derivatives, distribute, use and display any portion of the Covered
  27.  * Code in any form, with the right to sublicense such rights; and
  28.  *
  29.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  30.  * license (with the right to sublicense), under only those claims of Intel
  31.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  32.  * offer to sell, and import the Covered Code and derivative works thereof
  33.  * solely to the minimum extent necessary to exercise the above copyright
  34.  * license, and in no event shall the patent license extend to any additions
  35.  * to or modifications of the Original Intel Code.  No other license or right
  36.  * is granted directly or by implication, estoppel or otherwise;
  37.  *
  38.  * The above copyright and patent license is granted only if the following
  39.  * conditions are met:
  40.  *
  41.  * 3. Conditions
  42.  *
  43.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  44.  * Redistribution of source code of any substantial portion of the Covered
  45.  * Code or modification with rights to further distribute source must include
  46.  * the above Copyright Notice, the above License, this list of Conditions,
  47.  * and the following Disclaimer and Export Compliance provision.  In addition,
  48.  * Licensee must cause all Covered Code to which Licensee contributes to
  49.  * contain a file documenting the changes Licensee made to create that Covered
  50.  * Code and the date of any change.  Licensee must include in that file the
  51.  * documentation of any changes made by any predecessor Licensee.  Licensee
  52.  * must include a prominent statement that the modification is derived,
  53.  * directly or indirectly, from Original Intel Code.
  54.  *
  55.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  56.  * Redistribution of source code of any substantial portion of the Covered
  57.  * Code or modification without rights to further distribute source must
  58.  * include the following Disclaimer and Export Compliance provision in the
  59.  * documentation and/or other materials provided with distribution.  In
  60.  * addition, Licensee may not authorize further sublicense of source of any
  61.  * portion of the Covered Code, and must include terms to the effect that the
  62.  * license from Licensee to its licensee is limited to the intellectual
  63.  * property embodied in the software Licensee provides to its licensee, and
  64.  * not to intellectual property embodied in modifications its licensee may
  65.  * make.
  66.  *
  67.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  68.  * substantial portion of the Covered Code or modification must reproduce the
  69.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  70.  * provision in the documentation and/or other materials provided with the
  71.  * distribution.
  72.  *
  73.  * 3.4. Intel retains all right, title, and interest in and to the Original
  74.  * Intel Code.
  75.  *
  76.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  77.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  78.  * other dealings in products derived from or relating to the Covered Code
  79.  * without prior written authorization from Intel.
  80.  *
  81.  * 4. Disclaimer and Export Compliance
  82.  *
  83.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  84.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  85.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  86.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  87.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  88.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  89.  * PARTICULAR PURPOSE.
  90.  *
  91.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  92.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  93.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  94.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  95.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  96.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  97.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  98.  * LIMITED REMEDY.
  99.  *
  100.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  101.  * software or system incorporating such software without first obtaining any
  102.  * required license or other approval from the U. S. Department of Commerce or
  103.  * any other agency or department of the United States Government.  In the
  104.  * event Licensee exports any such software from the United States or
  105.  * re-exports any such software from a foreign destination, Licensee shall
  106.  * ensure that the distribution and export/re-export of the software is in
  107.  * compliance with all laws, regulations, orders, or other restrictions of the
  108.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  109.  * any of its subsidiaries will export/re-export any technical data, process,
  110.  * software, or service, directly or indirectly, to any country for which the
  111.  * United States government or any agency thereof requires an export license,
  112.  * other governmental approval, or letter of assurance, without first obtaining
  113.  * such license, approval or letter.
  114.  *
  115.  *****************************************************************************/
  116.  
  117.  
  118. #define __NSXFEVAL_C__
  119.  
  120. #include "acpi.h"
  121. #include "accommon.h"
  122. #include "acnamesp.h"
  123. #include "acinterp.h"
  124.  
  125.  
  126. #define _COMPONENT          ACPI_NAMESPACE
  127.         ACPI_MODULE_NAME    ("nsxfeval")
  128.  
  129. /* Local prototypes */
  130.  
  131. static void
  132. AcpiNsResolveReferences (
  133.     ACPI_EVALUATE_INFO      *Info);
  134.  
  135.  
  136. /*******************************************************************************
  137.  *
  138.  * FUNCTION:    AcpiEvaluateObjectTyped
  139.  *
  140.  * PARAMETERS:  Handle              - Object handle (optional)
  141.  *              Pathname            - Object pathname (optional)
  142.  *              ExternalParams      - List of parameters to pass to method,
  143.  *                                    terminated by NULL.  May be NULL
  144.  *                                    if no parameters are being passed.
  145.  *              ReturnBuffer        - Where to put method's return value (if
  146.  *                                    any).  If NULL, no value is returned.
  147.  *              ReturnType          - Expected type of return object
  148.  *
  149.  * RETURN:      Status
  150.  *
  151.  * DESCRIPTION: Find and evaluate the given object, passing the given
  152.  *              parameters if necessary.  One of "Handle" or "Pathname" must
  153.  *              be valid (non-null)
  154.  *
  155.  ******************************************************************************/
  156.  
  157. ACPI_STATUS
  158. AcpiEvaluateObjectTyped (
  159.     ACPI_HANDLE             Handle,
  160.     ACPI_STRING             Pathname,
  161.     ACPI_OBJECT_LIST        *ExternalParams,
  162.     ACPI_BUFFER             *ReturnBuffer,
  163.     ACPI_OBJECT_TYPE        ReturnType)
  164. {
  165.     ACPI_STATUS             Status;
  166.     BOOLEAN                 MustFree = FALSE;
  167.  
  168.  
  169.     ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
  170.  
  171.  
  172.     /* Return buffer must be valid */
  173.  
  174.     if (!ReturnBuffer)
  175.     {
  176.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  177.     }
  178.  
  179.     if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
  180.     {
  181.         MustFree = TRUE;
  182.     }
  183.  
  184.     /* Evaluate the object */
  185.  
  186.     Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
  187.     if (ACPI_FAILURE (Status))
  188.     {
  189.         return_ACPI_STATUS (Status);
  190.     }
  191.  
  192.     /* Type ANY means "don't care" */
  193.  
  194.     if (ReturnType == ACPI_TYPE_ANY)
  195.     {
  196.         return_ACPI_STATUS (AE_OK);
  197.     }
  198.  
  199.     if (ReturnBuffer->Length == 0)
  200.     {
  201.         /* Error because caller specifically asked for a return value */
  202.  
  203.         ACPI_ERROR ((AE_INFO, "No return value"));
  204.         return_ACPI_STATUS (AE_NULL_OBJECT);
  205.     }
  206.  
  207.     /* Examine the object type returned from EvaluateObject */
  208.  
  209.     if (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type == ReturnType)
  210.     {
  211.         return_ACPI_STATUS (AE_OK);
  212.     }
  213.  
  214.     /* Return object type does not match requested type */
  215.  
  216.     ACPI_ERROR ((AE_INFO,
  217.         "Incorrect return type [%s] requested [%s]",
  218.         AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
  219.         AcpiUtGetTypeName (ReturnType)));
  220.  
  221.     if (MustFree)
  222.     {
  223.         /* Caller used ACPI_ALLOCATE_BUFFER, free the return buffer */
  224.  
  225.         AcpiOsFree (ReturnBuffer->Pointer);
  226.         ReturnBuffer->Pointer = NULL;
  227.     }
  228.  
  229.     ReturnBuffer->Length = 0;
  230.     return_ACPI_STATUS (AE_TYPE);
  231. }
  232.  
  233. ACPI_EXPORT_SYMBOL (AcpiEvaluateObjectTyped)
  234.  
  235.  
  236. /*******************************************************************************
  237.  *
  238.  * FUNCTION:    AcpiEvaluateObject
  239.  *
  240.  * PARAMETERS:  Handle              - Object handle (optional)
  241.  *              Pathname            - Object pathname (optional)
  242.  *              ExternalParams      - List of parameters to pass to method,
  243.  *                                    terminated by NULL.  May be NULL
  244.  *                                    if no parameters are being passed.
  245.  *              ReturnBuffer        - Where to put method's return value (if
  246.  *                                    any).  If NULL, no value is returned.
  247.  *
  248.  * RETURN:      Status
  249.  *
  250.  * DESCRIPTION: Find and evaluate the given object, passing the given
  251.  *              parameters if necessary.  One of "Handle" or "Pathname" must
  252.  *              be valid (non-null)
  253.  *
  254.  ******************************************************************************/
  255.  
  256. ACPI_STATUS
  257. AcpiEvaluateObject (
  258.     ACPI_HANDLE             Handle,
  259.     ACPI_STRING             Pathname,
  260.     ACPI_OBJECT_LIST        *ExternalParams,
  261.     ACPI_BUFFER             *ReturnBuffer)
  262. {
  263.     ACPI_STATUS             Status;
  264.     ACPI_EVALUATE_INFO      *Info;
  265.     ACPI_SIZE               BufferSpaceNeeded;
  266.     UINT32                  i;
  267.  
  268.  
  269.     ACPI_FUNCTION_TRACE (AcpiEvaluateObject);
  270.  
  271.  
  272.     /* Allocate and initialize the evaluation information block */
  273.  
  274.     Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
  275.     if (!Info)
  276.     {
  277.         return_ACPI_STATUS (AE_NO_MEMORY);
  278.     }
  279.  
  280.     Info->Pathname = Pathname;
  281.  
  282.     /* Convert and validate the device handle */
  283.  
  284.     Info->PrefixNode = AcpiNsValidateHandle (Handle);
  285.     if (!Info->PrefixNode)
  286.     {
  287.         Status = AE_BAD_PARAMETER;
  288.         goto Cleanup;
  289.     }
  290.  
  291.     /*
  292.      * If there are parameters to be passed to a control method, the external
  293.      * objects must all be converted to internal objects
  294.      */
  295.     if (ExternalParams && ExternalParams->Count)
  296.     {
  297.         /*
  298.          * Allocate a new parameter block for the internal objects
  299.          * Add 1 to count to allow for null terminated internal list
  300.          */
  301.         Info->Parameters = ACPI_ALLOCATE_ZEROED (
  302.             ((ACPI_SIZE) ExternalParams->Count + 1) * sizeof (void *));
  303.         if (!Info->Parameters)
  304.         {
  305.             Status = AE_NO_MEMORY;
  306.             goto Cleanup;
  307.         }
  308.  
  309.         /* Convert each external object in the list to an internal object */
  310.  
  311.         for (i = 0; i < ExternalParams->Count; i++)
  312.         {
  313.             Status = AcpiUtCopyEobjectToIobject (
  314.                         &ExternalParams->Pointer[i], &Info->Parameters[i]);
  315.             if (ACPI_FAILURE (Status))
  316.             {
  317.                 goto Cleanup;
  318.             }
  319.         }
  320.         Info->Parameters[ExternalParams->Count] = NULL;
  321.     }
  322.  
  323.     /*
  324.      * Three major cases:
  325.      * 1) Fully qualified pathname
  326.      * 2) No handle, not fully qualified pathname (error)
  327.      * 3) Valid handle
  328.      */
  329.     if ((Pathname) &&
  330.         (AcpiNsValidRootPrefix (Pathname[0])))
  331.     {
  332.         /* The path is fully qualified, just evaluate by name */
  333.  
  334.         Info->PrefixNode = NULL;
  335.         Status = AcpiNsEvaluate (Info);
  336.     }
  337.     else if (!Handle)
  338.     {
  339.         /*
  340.          * A handle is optional iff a fully qualified pathname is specified.
  341.          * Since we've already handled fully qualified names above, this is
  342.          * an error
  343.          */
  344.         if (!Pathname)
  345.         {
  346.             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  347.                 "Both Handle and Pathname are NULL"));
  348.         }
  349.         else
  350.         {
  351.             ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  352.                 "Null Handle with relative pathname [%s]", Pathname));
  353.         }
  354.  
  355.         Status = AE_BAD_PARAMETER;
  356.     }
  357.     else
  358.     {
  359.         /* We have a namespace a node and a possible relative path */
  360.  
  361.         Status = AcpiNsEvaluate (Info);
  362.     }
  363.  
  364.     /*
  365.      * If we are expecting a return value, and all went well above,
  366.      * copy the return value to an external object.
  367.      */
  368.     if (ReturnBuffer)
  369.     {
  370.         if (!Info->ReturnObject)
  371.         {
  372.             ReturnBuffer->Length = 0;
  373.         }
  374.         else
  375.         {
  376.             if (ACPI_GET_DESCRIPTOR_TYPE (Info->ReturnObject) ==
  377.                 ACPI_DESC_TYPE_NAMED)
  378.             {
  379.                 /*
  380.                  * If we received a NS Node as a return object, this means that
  381.                  * the object we are evaluating has nothing interesting to
  382.                  * return (such as a mutex, etc.)  We return an error because
  383.                  * these types are essentially unsupported by this interface.
  384.                  * We don't check up front because this makes it easier to add
  385.                  * support for various types at a later date if necessary.
  386.                  */
  387.                 Status = AE_TYPE;
  388.                 Info->ReturnObject = NULL;   /* No need to delete a NS Node */
  389.                 ReturnBuffer->Length = 0;
  390.             }
  391.  
  392.             if (ACPI_SUCCESS (Status))
  393.             {
  394.                 /* Dereference Index and RefOf references */
  395.  
  396.                 AcpiNsResolveReferences (Info);
  397.  
  398.                 /* Get the size of the returned object */
  399.  
  400.                 Status = AcpiUtGetObjectSize (Info->ReturnObject,
  401.                             &BufferSpaceNeeded);
  402.                 if (ACPI_SUCCESS (Status))
  403.                 {
  404.                     /* Validate/Allocate/Clear caller buffer */
  405.  
  406.                     Status = AcpiUtInitializeBuffer (ReturnBuffer,
  407.                                 BufferSpaceNeeded);
  408.                     if (ACPI_FAILURE (Status))
  409.                     {
  410.                         /*
  411.                          * Caller's buffer is too small or a new one can't
  412.                          * be allocated
  413.                          */
  414.                         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  415.                             "Needed buffer size %X, %s\n",
  416.                             (UINT32) BufferSpaceNeeded,
  417.                             AcpiFormatException (Status)));
  418.                     }
  419.                     else
  420.                     {
  421.                         /* We have enough space for the object, build it */
  422.  
  423.                         Status = AcpiUtCopyIobjectToEobject (Info->ReturnObject,
  424.                                     ReturnBuffer);
  425.                     }
  426.                 }
  427.             }
  428.         }
  429.     }
  430.  
  431.     if (Info->ReturnObject)
  432.     {
  433.         /*
  434.          * Delete the internal return object. NOTE: Interpreter must be
  435.          * locked to avoid race condition.
  436.          */
  437.         AcpiExEnterInterpreter ();
  438.  
  439.         /* Remove one reference on the return object (should delete it) */
  440.  
  441.         AcpiUtRemoveReference (Info->ReturnObject);
  442.         AcpiExExitInterpreter ();
  443.     }
  444.  
  445.  
  446. Cleanup:
  447.  
  448.     /* Free the input parameter list (if we created one) */
  449.  
  450.     if (Info->Parameters)
  451.     {
  452.         /* Free the allocated parameter block */
  453.  
  454.         AcpiUtDeleteInternalObjectList (Info->Parameters);
  455.     }
  456.  
  457.     ACPI_FREE (Info);
  458.     return_ACPI_STATUS (Status);
  459. }
  460.  
  461. ACPI_EXPORT_SYMBOL (AcpiEvaluateObject)
  462.  
  463.  
  464. /*******************************************************************************
  465.  *
  466.  * FUNCTION:    AcpiNsResolveReferences
  467.  *
  468.  * PARAMETERS:  Info                    - Evaluation info block
  469.  *
  470.  * RETURN:      Info->ReturnObject is replaced with the dereferenced object
  471.  *
  472.  * DESCRIPTION: Dereference certain reference objects. Called before an
  473.  *              internal return object is converted to an external ACPI_OBJECT.
  474.  *
  475.  * Performs an automatic dereference of Index and RefOf reference objects.
  476.  * These reference objects are not supported by the ACPI_OBJECT, so this is a
  477.  * last resort effort to return something useful. Also, provides compatibility
  478.  * with other ACPI implementations.
  479.  *
  480.  * NOTE: does not handle references within returned package objects or nested
  481.  * references, but this support could be added later if found to be necessary.
  482.  *
  483.  ******************************************************************************/
  484.  
  485. static void
  486. AcpiNsResolveReferences (
  487.     ACPI_EVALUATE_INFO      *Info)
  488. {
  489.     ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
  490.     ACPI_NAMESPACE_NODE     *Node;
  491.  
  492.  
  493.     /* We are interested in reference objects only */
  494.  
  495.     if ((Info->ReturnObject)->Common.Type != ACPI_TYPE_LOCAL_REFERENCE)
  496.     {
  497.         return;
  498.     }
  499.  
  500.     /*
  501.      * Two types of references are supported - those created by Index and
  502.      * RefOf operators. A name reference (AML_NAMEPATH_OP) can be converted
  503.      * to an ACPI_OBJECT, so it is not dereferenced here. A DdbHandle
  504.      * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
  505.      * an ACPI_OBJECT.
  506.      */
  507.     switch (Info->ReturnObject->Reference.Class)
  508.     {
  509.     case ACPI_REFCLASS_INDEX:
  510.  
  511.         ObjDesc = *(Info->ReturnObject->Reference.Where);
  512.         break;
  513.  
  514.     case ACPI_REFCLASS_REFOF:
  515.  
  516.         Node = Info->ReturnObject->Reference.Object;
  517.         if (Node)
  518.         {
  519.             ObjDesc = Node->Object;
  520.         }
  521.         break;
  522.  
  523.     default:
  524.         return;
  525.     }
  526.  
  527.     /* Replace the existing reference object */
  528.  
  529.     if (ObjDesc)
  530.     {
  531.         AcpiUtAddReference (ObjDesc);
  532.         AcpiUtRemoveReference (Info->ReturnObject);
  533.         Info->ReturnObject = ObjDesc;
  534.     }
  535.  
  536.     return;
  537. }
  538.  
  539.  
  540. /*******************************************************************************
  541.  *
  542.  * FUNCTION:    AcpiWalkNamespace
  543.  *
  544.  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
  545.  *              StartObject         - Handle in namespace where search begins
  546.  *              MaxDepth            - Depth to which search is to reach
  547.  *              PreOrderVisit       - Called during tree pre-order visit
  548.  *                                    when an object of "Type" is found
  549.  *              PostOrderVisit      - Called during tree post-order visit
  550.  *                                    when an object of "Type" is found
  551.  *              Context             - Passed to user function(s) above
  552.  *              ReturnValue         - Location where return value of
  553.  *                                    UserFunction is put if terminated early
  554.  *
  555.  * RETURNS      Return value from the UserFunction if terminated early.
  556.  *              Otherwise, returns NULL.
  557.  *
  558.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  559.  *              starting (and ending) at the object specified by StartHandle.
  560.  *              The callback function is called whenever an object that matches
  561.  *              the type parameter is found. If the callback function returns
  562.  *              a non-zero value, the search is terminated immediately and this
  563.  *              value is returned to the caller.
  564.  *
  565.  *              The point of this procedure is to provide a generic namespace
  566.  *              walk routine that can be called from multiple places to
  567.  *              provide multiple services; the callback function(s) can be
  568.  *              tailored to each task, whether it is a print function,
  569.  *              a compare function, etc.
  570.  *
  571.  ******************************************************************************/
  572.  
  573. ACPI_STATUS
  574. AcpiWalkNamespace (
  575.     ACPI_OBJECT_TYPE        Type,
  576.     ACPI_HANDLE             StartObject,
  577.     UINT32                  MaxDepth,
  578.     ACPI_WALK_CALLBACK      PreOrderVisit,
  579.     ACPI_WALK_CALLBACK      PostOrderVisit,
  580.     void                    *Context,
  581.     void                    **ReturnValue)
  582. {
  583.     ACPI_STATUS             Status;
  584.  
  585.  
  586.     ACPI_FUNCTION_TRACE (AcpiWalkNamespace);
  587.  
  588.  
  589.     /* Parameter validation */
  590.  
  591.     if ((Type > ACPI_TYPE_LOCAL_MAX) ||
  592.         (!MaxDepth)                  ||
  593.         (!PreOrderVisit && !PostOrderVisit))
  594.     {
  595.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  596.     }
  597.  
  598.     /*
  599.      * Need to acquire the namespace reader lock to prevent interference
  600.      * with any concurrent table unloads (which causes the deletion of
  601.      * namespace objects). We cannot allow the deletion of a namespace node
  602.      * while the user function is using it. The exception to this are the
  603.      * nodes created and deleted during control method execution -- these
  604.      * nodes are marked as temporary nodes and are ignored by the namespace
  605.      * walk. Thus, control methods can be executed while holding the
  606.      * namespace deletion lock (and the user function can execute control
  607.      * methods.)
  608.      */
  609.     Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
  610.     if (ACPI_FAILURE (Status))
  611.     {
  612.         return (Status);
  613.     }
  614.  
  615.     /*
  616.      * Lock the namespace around the walk. The namespace will be
  617.      * unlocked/locked around each call to the user function - since the user
  618.      * function must be allowed to make ACPICA calls itself (for example, it
  619.      * will typically execute control methods during device enumeration.)
  620.      */
  621.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  622.     if (ACPI_FAILURE (Status))
  623.     {
  624.         goto UnlockAndExit;
  625.     }
  626.  
  627.     Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
  628.                 ACPI_NS_WALK_UNLOCK, PreOrderVisit,
  629.                 PostOrderVisit, Context, ReturnValue);
  630.  
  631.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  632.  
  633. UnlockAndExit:
  634.     (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
  635.     return_ACPI_STATUS (Status);
  636. }
  637.  
  638. ACPI_EXPORT_SYMBOL (AcpiWalkNamespace)
  639.  
  640.  
  641. /*******************************************************************************
  642.  *
  643.  * FUNCTION:    AcpiNsGetDeviceCallback
  644.  *
  645.  * PARAMETERS:  Callback from AcpiGetDevice
  646.  *
  647.  * RETURN:      Status
  648.  *
  649.  * DESCRIPTION: Takes callbacks from WalkNamespace and filters out all non-
  650.  *              present devices, or if they specified a HID, it filters based
  651.  *              on that.
  652.  *
  653.  ******************************************************************************/
  654.  
  655. static ACPI_STATUS
  656. AcpiNsGetDeviceCallback (
  657.     ACPI_HANDLE             ObjHandle,
  658.     UINT32                  NestingLevel,
  659.     void                    *Context,
  660.     void                    **ReturnValue)
  661. {
  662.     ACPI_GET_DEVICES_INFO   *Info = Context;
  663.     ACPI_STATUS             Status;
  664.     ACPI_NAMESPACE_NODE     *Node;
  665.     UINT32                  Flags;
  666.     ACPI_DEVICE_ID          *Hid;
  667.     ACPI_DEVICE_ID_LIST     *Cid;
  668.     UINT32                  i;
  669.     BOOLEAN                 Found;
  670.     int                     NoMatch;
  671.  
  672.  
  673.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  674.     if (ACPI_FAILURE (Status))
  675.     {
  676.         return (Status);
  677.     }
  678.  
  679.     Node = AcpiNsValidateHandle (ObjHandle);
  680.     Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  681.     if (ACPI_FAILURE (Status))
  682.     {
  683.         return (Status);
  684.     }
  685.  
  686.     if (!Node)
  687.     {
  688.         return (AE_BAD_PARAMETER);
  689.     }
  690.  
  691.     /*
  692.      * First, filter based on the device HID and CID.
  693.      *
  694.      * 01/2010: For this case where a specific HID is requested, we don't
  695.      * want to run _STA until we have an actual HID match. Thus, we will
  696.      * not unnecessarily execute _STA on devices for which the caller
  697.      * doesn't care about. Previously, _STA was executed unconditionally
  698.      * on all devices found here.
  699.      *
  700.      * A side-effect of this change is that now we will continue to search
  701.      * for a matching HID even under device trees where the parent device
  702.      * would have returned a _STA that indicates it is not present or
  703.      * not functioning (thus aborting the search on that branch).
  704.      */
  705.     if (Info->Hid != NULL)
  706.     {
  707.         Status = AcpiUtExecute_HID (Node, &Hid);
  708.         if (Status == AE_NOT_FOUND)
  709.         {
  710.             return (AE_OK);
  711.         }
  712.         else if (ACPI_FAILURE (Status))
  713.         {
  714.             return (AE_CTRL_DEPTH);
  715.         }
  716.  
  717.         NoMatch = ACPI_STRCMP (Hid->String, Info->Hid);
  718.         ACPI_FREE (Hid);
  719.  
  720.         if (NoMatch)
  721.         {
  722.             /*
  723.              * HID does not match, attempt match within the
  724.              * list of Compatible IDs (CIDs)
  725.              */
  726.             Status = AcpiUtExecute_CID (Node, &Cid);
  727.             if (Status == AE_NOT_FOUND)
  728.             {
  729.                 return (AE_OK);
  730.             }
  731.             else if (ACPI_FAILURE (Status))
  732.             {
  733.                 return (AE_CTRL_DEPTH);
  734.             }
  735.  
  736.             /* Walk the CID list */
  737.  
  738.             Found = FALSE;
  739.             for (i = 0; i < Cid->Count; i++)
  740.             {
  741.                 if (ACPI_STRCMP (Cid->Ids[i].String, Info->Hid) == 0)
  742.                 {
  743.                     /* Found a matching CID */
  744.  
  745.                     Found = TRUE;
  746.                     break;
  747.                 }
  748.             }
  749.  
  750.             ACPI_FREE (Cid);
  751.             if (!Found)
  752.             {
  753.                 return (AE_OK);
  754.             }
  755.         }
  756.     }
  757.  
  758.     /* Run _STA to determine if device is present */
  759.  
  760.     Status = AcpiUtExecute_STA (Node, &Flags);
  761.     if (ACPI_FAILURE (Status))
  762.     {
  763.         return (AE_CTRL_DEPTH);
  764.     }
  765.  
  766.     if (!(Flags & ACPI_STA_DEVICE_PRESENT) &&
  767.         !(Flags & ACPI_STA_DEVICE_FUNCTIONING))
  768.     {
  769.         /*
  770.          * Don't examine the children of the device only when the
  771.          * device is neither present nor functional. See ACPI spec,
  772.          * description of _STA for more information.
  773.          */
  774.         return (AE_CTRL_DEPTH);
  775.     }
  776.  
  777.     /* We have a valid device, invoke the user function */
  778.  
  779.     Status = Info->UserFunction (ObjHandle, NestingLevel, Info->Context,
  780.                 ReturnValue);
  781.     return (Status);
  782. }
  783.  
  784.  
  785. /*******************************************************************************
  786.  *
  787.  * FUNCTION:    AcpiGetDevices
  788.  *
  789.  * PARAMETERS:  HID                 - HID to search for. Can be NULL.
  790.  *              UserFunction        - Called when a matching object is found
  791.  *              Context             - Passed to user function
  792.  *              ReturnValue         - Location where return value of
  793.  *                                    UserFunction is put if terminated early
  794.  *
  795.  * RETURNS      Return value from the UserFunction if terminated early.
  796.  *              Otherwise, returns NULL.
  797.  *
  798.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  799.  *              starting (and ending) at the object specified by StartHandle.
  800.  *              The UserFunction is called whenever an object of type
  801.  *              Device is found.  If the user function returns
  802.  *              a non-zero value, the search is terminated immediately and this
  803.  *              value is returned to the caller.
  804.  *
  805.  *              This is a wrapper for WalkNamespace, but the callback performs
  806.  *              additional filtering. Please see AcpiNsGetDeviceCallback.
  807.  *
  808.  ******************************************************************************/
  809.  
  810. ACPI_STATUS
  811. AcpiGetDevices (
  812.     char                    *HID,
  813.     ACPI_WALK_CALLBACK      UserFunction,
  814.     void                    *Context,
  815.     void                    **ReturnValue)
  816. {
  817.     ACPI_STATUS             Status;
  818.     ACPI_GET_DEVICES_INFO   Info;
  819.  
  820.  
  821.     ACPI_FUNCTION_TRACE (AcpiGetDevices);
  822.  
  823.  
  824.     /* Parameter validation */
  825.  
  826.     if (!UserFunction)
  827.     {
  828.         return_ACPI_STATUS (AE_BAD_PARAMETER);
  829.     }
  830.  
  831.     /*
  832.      * We're going to call their callback from OUR callback, so we need
  833.      * to know what it is, and their context parameter.
  834.      */
  835.     Info.Hid          = HID;
  836.     Info.Context      = Context;
  837.     Info.UserFunction = UserFunction;
  838.  
  839.     /*
  840.      * Lock the namespace around the walk.
  841.      * The namespace will be unlocked/locked around each call
  842.      * to the user function - since this function
  843.      * must be allowed to make Acpi calls itself.
  844.      */
  845.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  846.     if (ACPI_FAILURE (Status))
  847.     {
  848.         return_ACPI_STATUS (Status);
  849.     }
  850.  
  851.     Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
  852.                 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
  853.                 AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);
  854.  
  855.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  856.     return_ACPI_STATUS (Status);
  857. }
  858.  
  859. ACPI_EXPORT_SYMBOL (AcpiGetDevices)
  860.  
  861.  
  862. /*******************************************************************************
  863.  *
  864.  * FUNCTION:    AcpiAttachData
  865.  *
  866.  * PARAMETERS:  ObjHandle           - Namespace node
  867.  *              Handler             - Handler for this attachment
  868.  *              Data                - Pointer to data to be attached
  869.  *
  870.  * RETURN:      Status
  871.  *
  872.  * DESCRIPTION: Attach arbitrary data and handler to a namespace node.
  873.  *
  874.  ******************************************************************************/
  875.  
  876. ACPI_STATUS
  877. AcpiAttachData (
  878.     ACPI_HANDLE             ObjHandle,
  879.     ACPI_OBJECT_HANDLER     Handler,
  880.     void                    *Data)
  881. {
  882.     ACPI_NAMESPACE_NODE     *Node;
  883.     ACPI_STATUS             Status;
  884.  
  885.  
  886.     /* Parameter validation */
  887.  
  888.     if (!ObjHandle  ||
  889.         !Handler    ||
  890.         !Data)
  891.     {
  892.         return (AE_BAD_PARAMETER);
  893.     }
  894.  
  895.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  896.     if (ACPI_FAILURE (Status))
  897.     {
  898.         return (Status);
  899.     }
  900.  
  901.     /* Convert and validate the handle */
  902.  
  903.     Node = AcpiNsValidateHandle (ObjHandle);
  904.     if (!Node)
  905.     {
  906.         Status = AE_BAD_PARAMETER;
  907.         goto UnlockAndExit;
  908.     }
  909.  
  910.     Status = AcpiNsAttachData (Node, Handler, Data);
  911.  
  912. UnlockAndExit:
  913.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  914.     return (Status);
  915. }
  916.  
  917. ACPI_EXPORT_SYMBOL (AcpiAttachData)
  918.  
  919.  
  920. /*******************************************************************************
  921.  *
  922.  * FUNCTION:    AcpiDetachData
  923.  *
  924.  * PARAMETERS:  ObjHandle           - Namespace node handle
  925.  *              Handler             - Handler used in call to AcpiAttachData
  926.  *
  927.  * RETURN:      Status
  928.  *
  929.  * DESCRIPTION: Remove data that was previously attached to a node.
  930.  *
  931.  ******************************************************************************/
  932.  
  933. ACPI_STATUS
  934. AcpiDetachData (
  935.     ACPI_HANDLE             ObjHandle,
  936.     ACPI_OBJECT_HANDLER     Handler)
  937. {
  938.     ACPI_NAMESPACE_NODE     *Node;
  939.     ACPI_STATUS             Status;
  940.  
  941.  
  942.     /* Parameter validation */
  943.  
  944.     if (!ObjHandle  ||
  945.         !Handler)
  946.     {
  947.         return (AE_BAD_PARAMETER);
  948.     }
  949.  
  950.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  951.     if (ACPI_FAILURE (Status))
  952.     {
  953.         return (Status);
  954.     }
  955.  
  956.     /* Convert and validate the handle */
  957.  
  958.     Node = AcpiNsValidateHandle (ObjHandle);
  959.     if (!Node)
  960.     {
  961.         Status = AE_BAD_PARAMETER;
  962.         goto UnlockAndExit;
  963.     }
  964.  
  965.     Status = AcpiNsDetachData (Node, Handler);
  966.  
  967. UnlockAndExit:
  968.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  969.     return (Status);
  970. }
  971.  
  972. ACPI_EXPORT_SYMBOL (AcpiDetachData)
  973.  
  974.  
  975. /*******************************************************************************
  976.  *
  977.  * FUNCTION:    AcpiGetData
  978.  *
  979.  * PARAMETERS:  ObjHandle           - Namespace node
  980.  *              Handler             - Handler used in call to AttachData
  981.  *              Data                - Where the data is returned
  982.  *
  983.  * RETURN:      Status
  984.  *
  985.  * DESCRIPTION: Retrieve data that was previously attached to a namespace node.
  986.  *
  987.  ******************************************************************************/
  988.  
  989. ACPI_STATUS
  990. AcpiGetData (
  991.     ACPI_HANDLE             ObjHandle,
  992.     ACPI_OBJECT_HANDLER     Handler,
  993.     void                    **Data)
  994. {
  995.     ACPI_NAMESPACE_NODE     *Node;
  996.     ACPI_STATUS             Status;
  997.  
  998.  
  999.     /* Parameter validation */
  1000.  
  1001.     if (!ObjHandle  ||
  1002.         !Handler    ||
  1003.         !Data)
  1004.     {
  1005.         return (AE_BAD_PARAMETER);
  1006.     }
  1007.  
  1008.     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  1009.     if (ACPI_FAILURE (Status))
  1010.     {
  1011.         return (Status);
  1012.     }
  1013.  
  1014.     /* Convert and validate the handle */
  1015.  
  1016.     Node = AcpiNsValidateHandle (ObjHandle);
  1017.     if (!Node)
  1018.     {
  1019.         Status = AE_BAD_PARAMETER;
  1020.         goto UnlockAndExit;
  1021.     }
  1022.  
  1023.     Status = AcpiNsGetAttachedData (Node, Handler, Data);
  1024.  
  1025. UnlockAndExit:
  1026.     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  1027.     return (Status);
  1028. }
  1029.  
  1030. ACPI_EXPORT_SYMBOL (AcpiGetData)
  1031.  
  1032.  
  1033.