Back to home page

Quest Cross Reference

 
 

    


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

0001 /******************************************************************************
0002  *
0003  * Module Name: nswalk - Functions for walking the ACPI namespace
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights.  You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code.  No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision.  In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change.  Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee.  Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution.  In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government.  In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************/
0115 
0116 
0117 #define __NSWALK_C__
0118 
0119 #include "acpi.h"
0120 #include "accommon.h"
0121 #include "acnamesp.h"
0122 
0123 
0124 #define _COMPONENT          ACPI_NAMESPACE
0125         ACPI_MODULE_NAME    ("nswalk")
0126 
0127 
0128 /*******************************************************************************
0129  *
0130  * FUNCTION:    AcpiNsGetNextNode
0131  *
0132  * PARAMETERS:  ParentNode          - Parent node whose children we are
0133  *                                    getting
0134  *              ChildNode           - Previous child that was found.
0135  *                                    The NEXT child will be returned
0136  *
0137  * RETURN:      ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
0138  *                                    none is found.
0139  *
0140  * DESCRIPTION: Return the next peer node within the namespace.  If Handle
0141  *              is valid, Scope is ignored.  Otherwise, the first node
0142  *              within Scope is returned.
0143  *
0144  ******************************************************************************/
0145 
0146 ACPI_NAMESPACE_NODE *
0147 AcpiNsGetNextNode (
0148     ACPI_NAMESPACE_NODE     *ParentNode,
0149     ACPI_NAMESPACE_NODE     *ChildNode)
0150 {
0151     ACPI_FUNCTION_ENTRY ();
0152 
0153 
0154     if (!ChildNode)
0155     {
0156         /* It's really the parent's _scope_ that we want */
0157 
0158         return (ParentNode->Child);
0159     }
0160 
0161     /*
0162      * Get the next node.
0163      *
0164      * If we are at the end of this peer list, return NULL
0165      */
0166     if (ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)
0167     {
0168         return NULL;
0169     }
0170 
0171     /* Otherwise just return the next peer */
0172 
0173     return (ChildNode->Peer);
0174 }
0175 
0176 
0177 /*******************************************************************************
0178  *
0179  * FUNCTION:    AcpiNsGetNextNodeTyped
0180  *
0181  * PARAMETERS:  Type                - Type of node to be searched for
0182  *              ParentNode          - Parent node whose children we are
0183  *                                    getting
0184  *              ChildNode           - Previous child that was found.
0185  *                                    The NEXT child will be returned
0186  *
0187  * RETURN:      ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if
0188  *                                    none is found.
0189  *
0190  * DESCRIPTION: Return the next peer node within the namespace.  If Handle
0191  *              is valid, Scope is ignored.  Otherwise, the first node
0192  *              within Scope is returned.
0193  *
0194  ******************************************************************************/
0195 
0196 ACPI_NAMESPACE_NODE *
0197 AcpiNsGetNextNodeTyped (
0198     ACPI_OBJECT_TYPE        Type,
0199     ACPI_NAMESPACE_NODE     *ParentNode,
0200     ACPI_NAMESPACE_NODE     *ChildNode)
0201 {
0202     ACPI_NAMESPACE_NODE     *NextNode = NULL;
0203 
0204 
0205     ACPI_FUNCTION_ENTRY ();
0206 
0207 
0208     NextNode = AcpiNsGetNextNode (ParentNode, ChildNode);
0209 
0210     /* If any type is OK, we are done */
0211 
0212     if (Type == ACPI_TYPE_ANY)
0213     {
0214         /* NextNode is NULL if we are at the end-of-list */
0215 
0216         return (NextNode);
0217     }
0218 
0219     /* Must search for the node -- but within this scope only */
0220 
0221     while (NextNode)
0222     {
0223         /* If type matches, we are done */
0224 
0225         if (NextNode->Type == Type)
0226         {
0227             return (NextNode);
0228         }
0229 
0230         /* Otherwise, move on to the next node */
0231 
0232         NextNode = AcpiNsGetNextValidNode (NextNode);
0233     }
0234 
0235     /* Not found */
0236 
0237     return (NULL);
0238 }
0239 
0240 
0241 /*******************************************************************************
0242  *
0243  * FUNCTION:    AcpiNsWalkNamespace
0244  *
0245  * PARAMETERS:  Type                - ACPI_OBJECT_TYPE to search for
0246  *              StartNode           - Handle in namespace where search begins
0247  *              MaxDepth            - Depth to which search is to reach
0248  *              Flags               - Whether to unlock the NS before invoking
0249  *                                    the callback routine
0250  *              UserFunction        - Called when an object of "Type" is found
0251  *              Context             - Passed to user function
0252  *              ReturnValue         - from the UserFunction if terminated early.
0253  *                                    Otherwise, returns NULL.
0254  * RETURNS:     Status
0255  *
0256  * DESCRIPTION: Performs a modified depth-first walk of the namespace tree,
0257  *              starting (and ending) at the node specified by StartHandle.
0258  *              The UserFunction is called whenever a node that matches
0259  *              the type parameter is found.  If the user function returns
0260  *              a non-zero value, the search is terminated immediately and
0261  *              this value is returned to the caller.
0262  *
0263  *              The point of this procedure is to provide a generic namespace
0264  *              walk routine that can be called from multiple places to
0265  *              provide multiple services;  the User Function can be tailored
0266  *              to each task, whether it is a print function, a compare
0267  *              function, etc.
0268  *
0269  ******************************************************************************/
0270 
0271 ACPI_STATUS
0272 AcpiNsWalkNamespace (
0273     ACPI_OBJECT_TYPE        Type,
0274     ACPI_HANDLE             StartNode,
0275     UINT32                  MaxDepth,
0276     UINT32                  Flags,
0277     ACPI_WALK_CALLBACK      UserFunction,
0278     void                    *Context,
0279     void                    **ReturnValue)
0280 {
0281     ACPI_STATUS             Status;
0282     ACPI_STATUS             MutexStatus;
0283     ACPI_NAMESPACE_NODE     *ChildNode;
0284     ACPI_NAMESPACE_NODE     *ParentNode;
0285     ACPI_OBJECT_TYPE        ChildType;
0286     UINT32                  Level;
0287 
0288 
0289     ACPI_FUNCTION_TRACE (NsWalkNamespace);
0290 
0291 
0292     /* Special case for the namespace Root Node */
0293 
0294     if (StartNode == ACPI_ROOT_OBJECT)
0295     {
0296         StartNode = AcpiGbl_RootNode;
0297     }
0298 
0299     /* Null child means "get first node" */
0300 
0301     ParentNode  = StartNode;
0302     ChildNode   = NULL;
0303     ChildType   = ACPI_TYPE_ANY;
0304     Level       = 1;
0305 
0306     /*
0307      * Traverse the tree of nodes until we bubble back up to where we
0308      * started. When Level is zero, the loop is done because we have
0309      * bubbled up to (and passed) the original parent handle (StartEntry)
0310      */
0311     while (Level > 0)
0312     {
0313         /* Get the next node in this scope.  Null if not found */
0314 
0315         Status = AE_OK;
0316         ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
0317         if (ChildNode)
0318         {
0319             /* Found next child, get the type if we are not searching for ANY */
0320 
0321             if (Type != ACPI_TYPE_ANY)
0322             {
0323                 ChildType = ChildNode->Type;
0324             }
0325 
0326             /*
0327              * Ignore all temporary namespace nodes (created during control
0328              * method execution) unless told otherwise. These temporary nodes
0329              * can cause a race condition because they can be deleted during
0330              * the execution of the user function (if the namespace is
0331              * unlocked before invocation of the user function.) Only the
0332              * debugger namespace dump will examine the temporary nodes.
0333              */
0334             if ((ChildNode->Flags & ANOBJ_TEMPORARY) &&
0335                 !(Flags & ACPI_NS_WALK_TEMP_NODES))
0336             {
0337                 Status = AE_CTRL_DEPTH;
0338             }
0339 
0340             /* Type must match requested type */
0341 
0342             else if (ChildType == Type)
0343             {
0344                 /*
0345                  * Found a matching node, invoke the user callback function.
0346                  * Unlock the namespace if flag is set.
0347                  */
0348                 if (Flags & ACPI_NS_WALK_UNLOCK)
0349                 {
0350                     MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
0351                     if (ACPI_FAILURE (MutexStatus))
0352                     {
0353                         return_ACPI_STATUS (MutexStatus);
0354                     }
0355                 }
0356 
0357                 Status = UserFunction (ChildNode, Level, Context, ReturnValue);
0358 
0359                 if (Flags & ACPI_NS_WALK_UNLOCK)
0360                 {
0361                     MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
0362                     if (ACPI_FAILURE (MutexStatus))
0363                     {
0364                         return_ACPI_STATUS (MutexStatus);
0365                     }
0366                 }
0367 
0368                 switch (Status)
0369                 {
0370                 case AE_OK:
0371                 case AE_CTRL_DEPTH:
0372 
0373                     /* Just keep going */
0374                     break;
0375 
0376                 case AE_CTRL_TERMINATE:
0377 
0378                     /* Exit now, with OK status */
0379 
0380                     return_ACPI_STATUS (AE_OK);
0381 
0382                 default:
0383 
0384                     /* All others are valid exceptions */
0385 
0386                     return_ACPI_STATUS (Status);
0387                 }
0388             }
0389 
0390             /*
0391              * Depth first search: Attempt to go down another level in the
0392              * namespace if we are allowed to.  Don't go any further if we have
0393              * reached the caller specified maximum depth or if the user
0394              * function has specified that the maximum depth has been reached.
0395              */
0396             if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH))
0397             {
0398                 if (ChildNode->Child)
0399                 {
0400                     /* There is at least one child of this node, visit it */
0401 
0402                     Level++;
0403                     ParentNode = ChildNode;
0404                     ChildNode = NULL;
0405                 }
0406             }
0407         }
0408         else
0409         {
0410             /*
0411              * No more children of this node (AcpiNsGetNextNode failed), go
0412              * back upwards in the namespace tree to the node's parent.
0413              */
0414             Level--;
0415             ChildNode = ParentNode;
0416             ParentNode = AcpiNsGetParentNode (ParentNode);
0417         }
0418     }
0419 
0420     /* Complete walk, not terminated by user function */
0421 
0422     return_ACPI_STATUS (AE_OK);
0423 }
0424 
0425