Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nswalk - Functions for walking the ACPI namespace
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116.  
  117. #define __NSWALK_C__
  118.  
  119. #include "acpi.h"
  120. #include "accommon.h"
  121. #include "acnamesp.h"
  122.  
  123.  
  124. #define _COMPONENT          ACPI_NAMESPACE
  125.         ACPI_MODULE_NAME    ("nswalk")
  126.  
  127.  
  128. /*******************************************************************************
  129.  *
  130.  * FUNCTION:    AcpiNsGetNextNode
  131.  *
  132.  * PARAMETERS:  ParentNode          - Parent node whose children we are
  133.  *                                    getting
  134.  *              ChildNode           - Previous child that was found.
  135.  *                                    The NEXT child will be returned
  136.  *
  137.  * RETURN:      ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
  138.  *                                    none is found.
  139.  *
  140.  * DESCRIPTION: Return the next peer node within the namespace.  If Handle
  141.  *              is valid, Scope is ignored.  Otherwise, the first node
  142.  *              within Scope is returned.
  143.  *
  144.  ******************************************************************************/
  145.  
  146. ACPI_NAMESPACE_NODE *
  147. AcpiNsGetNextNode (
  148.     ACPI_NAMESPACE_NODE     *ParentNode,
  149.     ACPI_NAMESPACE_NODE     *ChildNode)
  150. {
  151.     ACPI_FUNCTION_ENTRY ();
  152.  
  153.  
  154.     if (!ChildNode)
  155.     {
  156.         /* It's really the parent's _scope_ that we want */
  157.  
  158.         return (ParentNode->Child);
  159.     }
  160.  
  161.     /* Otherwise just return the next peer */
  162.  
  163.     return (ChildNode->Peer);
  164. }
  165.  
  166.  
  167. /*******************************************************************************
  168.  *
  169.  * FUNCTION:    AcpiNsGetNextNodeTyped
  170.  *
  171.  * PARAMETERS:  Type                - Type of node to be searched for
  172.  *              ParentNode          - Parent node whose children we are
  173.  *                                    getting
  174.  *              ChildNode           - Previous child that was found.
  175.  *                                    The NEXT child will be returned
  176.  *
  177.  * RETURN:      ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
  178.  *                                    none is found.
  179.  *
  180.  * DESCRIPTION: Return the next peer node within the namespace.  If Handle
  181.  *              is valid, Scope is ignored.  Otherwise, the first node
  182.  *              within Scope is returned.
  183.  *
  184.  ******************************************************************************/
  185.  
  186. ACPI_NAMESPACE_NODE *
  187. AcpiNsGetNextNodeTyped (
  188.     ACPI_OBJECT_TYPE        Type,
  189.     ACPI_NAMESPACE_NODE     *ParentNode,
  190.     ACPI_NAMESPACE_NODE     *ChildNode)
  191. {
  192.     ACPI_NAMESPACE_NODE     *NextNode = NULL;
  193.  
  194.  
  195.     ACPI_FUNCTION_ENTRY ();
  196.  
  197.  
  198.     NextNode = AcpiNsGetNextNode (ParentNode, ChildNode);
  199.  
  200.     /* If any type is OK, we are done */
  201.  
  202.     if (Type == ACPI_TYPE_ANY)
  203.     {
  204.         /* NextNode is NULL if we are at the end-of-list */
  205.  
  206.         return (NextNode);
  207.     }
  208.  
  209.     /* Must search for the node -- but within this scope only */
  210.  
  211.     while (NextNode)
  212.     {
  213.         /* If type matches, we are done */
  214.  
  215.         if (NextNode->Type == Type)
  216.         {
  217.             return (NextNode);
  218.         }
  219.  
  220.         /* Otherwise, move on to the next peer node */
  221.  
  222.         NextNode = NextNode->Peer;
  223.     }
  224.  
  225.     /* Not found */
  226.  
  227.     return (NULL);
  228. }
  229.  
  230.  
  231. /*******************************************************************************
  232.  *
  233.  * FUNCTION:    AcpiNsWalkNamespace
  234.  *
  235.  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
  236.  *              StartNode           - Handle in namespace where search begins
  237.  *              MaxDepth            - Depth to which search is to reach
  238.  *              Flags               - Whether to unlock the NS before invoking
  239.  *                                    the callback routine
  240.  *              PreOrderVisit       - Called during tree pre-order visit
  241.  *                                    when an object of "Type" is found
  242.  *              PostOrderVisit      - Called during tree post-order visit
  243.  *                                    when an object of "Type" is found
  244.  *              Context             - Passed to user function(s) above
  245.  *              ReturnValue         - from the UserFunction if terminated
  246.  *                                    early. Otherwise, returns NULL.
  247.  * RETURNS:     Status
  248.  *
  249.  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
  250.  *              starting (and ending) at the node specified by StartHandle.
  251.  *              The callback function is called whenever a node that matches
  252.  *              the type parameter is found. If the callback function returns
  253.  *              a non-zero value, the search is terminated immediately and
  254.  *              this value is returned to the caller.
  255.  *
  256.  *              The point of this procedure is to provide a generic namespace
  257.  *              walk routine that can be called from multiple places to
  258.  *              provide multiple services; the callback function(s) can be
  259.  *              tailored to each task, whether it is a print function,
  260.  *              a compare function, etc.
  261.  *
  262.  ******************************************************************************/
  263.  
  264. ACPI_STATUS
  265. AcpiNsWalkNamespace (
  266.     ACPI_OBJECT_TYPE        Type,
  267.     ACPI_HANDLE             StartNode,
  268.     UINT32                  MaxDepth,
  269.     UINT32                  Flags,
  270.     ACPI_WALK_CALLBACK      PreOrderVisit,
  271.     ACPI_WALK_CALLBACK      PostOrderVisit,
  272.     void                    *Context,
  273.     void                    **ReturnValue)
  274. {
  275.     ACPI_STATUS             Status;
  276.     ACPI_STATUS             MutexStatus;
  277.     ACPI_NAMESPACE_NODE     *ChildNode;
  278.     ACPI_NAMESPACE_NODE     *ParentNode;
  279.     ACPI_OBJECT_TYPE        ChildType;
  280.     UINT32                  Level;
  281.     BOOLEAN                 NodePreviouslyVisited = FALSE;
  282.  
  283.  
  284.     ACPI_FUNCTION_TRACE (NsWalkNamespace);
  285.  
  286.  
  287.     /* Special case for the namespace Root Node */
  288.  
  289.     if (StartNode == ACPI_ROOT_OBJECT)
  290.     {
  291.         StartNode = AcpiGbl_RootNode;
  292.     }
  293.  
  294.     /* Null child means "get first node" */
  295.  
  296.     ParentNode  = StartNode;
  297.     ChildNode   = AcpiNsGetNextNode (ParentNode, NULL);
  298.     ChildType   = ACPI_TYPE_ANY;
  299.     Level       = 1;
  300.  
  301.     /*
  302.      * Traverse the tree of nodes until we bubble back up to where we
  303.      * started. When Level is zero, the loop is done because we have
  304.      * bubbled up to (and passed) the original parent handle (StartEntry)
  305.      */
  306.     while (Level > 0 && ChildNode)
  307.     {
  308.         Status = AE_OK;
  309.  
  310.         /* Found next child, get the type if we are not searching for ANY */
  311.  
  312.         if (Type != ACPI_TYPE_ANY)
  313.         {
  314.             ChildType = ChildNode->Type;
  315.         }
  316.  
  317.         /*
  318.          * Ignore all temporary namespace nodes (created during control
  319.          * method execution) unless told otherwise. These temporary nodes
  320.          * can cause a race condition because they can be deleted during
  321.          * the execution of the user function (if the namespace is
  322.          * unlocked before invocation of the user function.) Only the
  323.          * debugger namespace dump will examine the temporary nodes.
  324.          */
  325.         if ((ChildNode->Flags & ANOBJ_TEMPORARY) &&
  326.             !(Flags & ACPI_NS_WALK_TEMP_NODES))
  327.         {
  328.             Status = AE_CTRL_DEPTH;
  329.         }
  330.  
  331.         /* Type must match requested type */
  332.  
  333.         else if (ChildType == Type)
  334.         {
  335.             /*
  336.              * Found a matching node, invoke the user callback function.
  337.              * Unlock the namespace if flag is set.
  338.              */
  339.             if (Flags & ACPI_NS_WALK_UNLOCK)
  340.             {
  341.                 MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
  342.                 if (ACPI_FAILURE (MutexStatus))
  343.                 {
  344.                     return_ACPI_STATUS (MutexStatus);
  345.                 }
  346.             }
  347.  
  348.             /*
  349.              * Invoke the user function, either pre-order or post-order
  350.              * or both.
  351.              */
  352.             if (!NodePreviouslyVisited)
  353.             {
  354.                 if (PreOrderVisit)
  355.                 {
  356.                     Status = PreOrderVisit (ChildNode, Level,
  357.                                 Context, ReturnValue);
  358.                 }
  359.             }
  360.             else
  361.             {
  362.                 if (PostOrderVisit)
  363.                 {
  364.                     Status = PostOrderVisit (ChildNode, Level,
  365.                                 Context, ReturnValue);
  366.                 }
  367.             }
  368.  
  369.             if (Flags & ACPI_NS_WALK_UNLOCK)
  370.             {
  371.                 MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
  372.                 if (ACPI_FAILURE (MutexStatus))
  373.                 {
  374.                     return_ACPI_STATUS (MutexStatus);
  375.                 }
  376.             }
  377.  
  378.             switch (Status)
  379.             {
  380.             case AE_OK:
  381.             case AE_CTRL_DEPTH:
  382.  
  383.                 /* Just keep going */
  384.                 break;
  385.  
  386.             case AE_CTRL_TERMINATE:
  387.  
  388.                 /* Exit now, with OK status */
  389.  
  390.                 return_ACPI_STATUS (AE_OK);
  391.  
  392.             default:
  393.  
  394.                 /* All others are valid exceptions */
  395.  
  396.                 return_ACPI_STATUS (Status);
  397.             }
  398.         }
  399.  
  400.         /*
  401.          * Depth first search: Attempt to go down another level in the
  402.          * namespace if we are allowed to.  Don't go any further if we have
  403.          * reached the caller specified maximum depth or if the user
  404.          * function has specified that the maximum depth has been reached.
  405.          */
  406.         if (!NodePreviouslyVisited &&
  407.             (Level < MaxDepth) &&
  408.             (Status != AE_CTRL_DEPTH))
  409.         {
  410.             if (ChildNode->Child)
  411.             {
  412.                 /* There is at least one child of this node, visit it */
  413.  
  414.                 Level++;
  415.                 ParentNode = ChildNode;
  416.                 ChildNode = AcpiNsGetNextNode (ParentNode, NULL);
  417.                 continue;
  418.             }
  419.         }
  420.  
  421.         /* No more children, re-visit this node */
  422.  
  423.         if (!NodePreviouslyVisited)
  424.         {
  425.             NodePreviouslyVisited = TRUE;
  426.             continue;
  427.         }
  428.  
  429.         /* No more children, visit peers */
  430.  
  431.         ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
  432.         if (ChildNode)
  433.         {
  434.             NodePreviouslyVisited = FALSE;
  435.         }
  436.  
  437.         /* No peers, re-visit parent */
  438.  
  439.         else
  440.         {
  441.             /*
  442.              * No more children of this node (AcpiNsGetNextNode failed), go
  443.              * back upwards in the namespace tree to the node's parent.
  444.              */
  445.             Level--;
  446.             ChildNode = ParentNode;
  447.             ParentNode = ParentNode->Parent;
  448.  
  449.             NodePreviouslyVisited = TRUE;
  450.         }
  451.     }
  452.  
  453.     /* Complete walk, not terminated by user function */
  454.  
  455.     return_ACPI_STATUS (AE_OK);
  456. }
  457.  
  458.  
  459.