13446Smrj /****************************************************************************** 23446Smrj * 33446Smrj * Module Name: nswalk - Functions for walking the ACPI namespace 4*7851SDana.Myers@Sun.COM * $Revision: 1.47 $ 53446Smrj * 63446Smrj *****************************************************************************/ 73446Smrj 83446Smrj /****************************************************************************** 93446Smrj * 103446Smrj * 1. Copyright Notice 113446Smrj * 12*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 133446Smrj * All rights reserved. 143446Smrj * 153446Smrj * 2. License 163446Smrj * 173446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 183446Smrj * rights. You may have additional license terms from the party that provided 193446Smrj * you this software, covering your right to use that party's intellectual 203446Smrj * property rights. 213446Smrj * 223446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 233446Smrj * copy of the source code appearing in this file ("Covered Code") an 243446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 253446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 263446Smrj * make derivatives, distribute, use and display any portion of the Covered 273446Smrj * Code in any form, with the right to sublicense such rights; and 283446Smrj * 293446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 303446Smrj * license (with the right to sublicense), under only those claims of Intel 313446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 323446Smrj * offer to sell, and import the Covered Code and derivative works thereof 333446Smrj * solely to the minimum extent necessary to exercise the above copyright 343446Smrj * license, and in no event shall the patent license extend to any additions 353446Smrj * to or modifications of the Original Intel Code. No other license or right 363446Smrj * is granted directly or by implication, estoppel or otherwise; 373446Smrj * 383446Smrj * The above copyright and patent license is granted only if the following 393446Smrj * conditions are met: 403446Smrj * 413446Smrj * 3. Conditions 423446Smrj * 433446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 443446Smrj * Redistribution of source code of any substantial portion of the Covered 453446Smrj * Code or modification with rights to further distribute source must include 463446Smrj * the above Copyright Notice, the above License, this list of Conditions, 473446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 483446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 493446Smrj * contain a file documenting the changes Licensee made to create that Covered 503446Smrj * Code and the date of any change. Licensee must include in that file the 513446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 523446Smrj * must include a prominent statement that the modification is derived, 533446Smrj * directly or indirectly, from Original Intel Code. 543446Smrj * 553446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 563446Smrj * Redistribution of source code of any substantial portion of the Covered 573446Smrj * Code or modification without rights to further distribute source must 583446Smrj * include the following Disclaimer and Export Compliance provision in the 593446Smrj * documentation and/or other materials provided with distribution. In 603446Smrj * addition, Licensee may not authorize further sublicense of source of any 613446Smrj * portion of the Covered Code, and must include terms to the effect that the 623446Smrj * license from Licensee to its licensee is limited to the intellectual 633446Smrj * property embodied in the software Licensee provides to its licensee, and 643446Smrj * not to intellectual property embodied in modifications its licensee may 653446Smrj * make. 663446Smrj * 673446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 683446Smrj * substantial portion of the Covered Code or modification must reproduce the 693446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 703446Smrj * provision in the documentation and/or other materials provided with the 713446Smrj * distribution. 723446Smrj * 733446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 743446Smrj * Intel Code. 753446Smrj * 763446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 773446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 783446Smrj * other dealings in products derived from or relating to the Covered Code 793446Smrj * without prior written authorization from Intel. 803446Smrj * 813446Smrj * 4. Disclaimer and Export Compliance 823446Smrj * 833446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 843446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 853446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 863446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 873446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 883446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 893446Smrj * PARTICULAR PURPOSE. 903446Smrj * 913446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 923446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 933446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 943446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 953446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 963446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 973446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 983446Smrj * LIMITED REMEDY. 993446Smrj * 1003446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1013446Smrj * software or system incorporating such software without first obtaining any 1023446Smrj * required license or other approval from the U. S. Department of Commerce or 1033446Smrj * any other agency or department of the United States Government. In the 1043446Smrj * event Licensee exports any such software from the United States or 1053446Smrj * re-exports any such software from a foreign destination, Licensee shall 1063446Smrj * ensure that the distribution and export/re-export of the software is in 1073446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1083446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1093446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1103446Smrj * software, or service, directly or indirectly, to any country for which the 1113446Smrj * United States government or any agency thereof requires an export license, 1123446Smrj * other governmental approval, or letter of assurance, without first obtaining 1133446Smrj * such license, approval or letter. 1143446Smrj * 1153446Smrj *****************************************************************************/ 1163446Smrj 1173446Smrj 1183446Smrj #define __NSWALK_C__ 1193446Smrj 1203446Smrj #include "acpi.h" 1213446Smrj #include "acnamesp.h" 1223446Smrj 1233446Smrj 1243446Smrj #define _COMPONENT ACPI_NAMESPACE 1253446Smrj ACPI_MODULE_NAME ("nswalk") 1263446Smrj 1273446Smrj 1283446Smrj /******************************************************************************* 1293446Smrj * 1303446Smrj * FUNCTION: AcpiNsGetNextNode 1313446Smrj * 1323446Smrj * PARAMETERS: Type - Type of node to be searched for 1333446Smrj * ParentNode - Parent node whose children we are 1343446Smrj * getting 1353446Smrj * ChildNode - Previous child that was found. 1363446Smrj * The NEXT child will be returned 1373446Smrj * 1383446Smrj * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if 1393446Smrj * none is found. 1403446Smrj * 1413446Smrj * DESCRIPTION: Return the next peer node within the namespace. If Handle 1423446Smrj * is valid, Scope is ignored. Otherwise, the first node 1433446Smrj * within Scope is returned. 1443446Smrj * 1453446Smrj ******************************************************************************/ 1463446Smrj 1473446Smrj ACPI_NAMESPACE_NODE * 1483446Smrj AcpiNsGetNextNode ( 1493446Smrj ACPI_OBJECT_TYPE Type, 1503446Smrj ACPI_NAMESPACE_NODE *ParentNode, 1513446Smrj ACPI_NAMESPACE_NODE *ChildNode) 1523446Smrj { 1533446Smrj ACPI_NAMESPACE_NODE *NextNode = NULL; 1543446Smrj 1553446Smrj 1563446Smrj ACPI_FUNCTION_ENTRY (); 1573446Smrj 1583446Smrj 1593446Smrj if (!ChildNode) 1603446Smrj { 1613446Smrj /* It's really the parent's _scope_ that we want */ 1623446Smrj 163*7851SDana.Myers@Sun.COM NextNode = ParentNode->Child; 1643446Smrj } 1653446Smrj 1663446Smrj else 1673446Smrj { 1683446Smrj /* Start search at the NEXT node */ 1693446Smrj 1703446Smrj NextNode = AcpiNsGetNextValidNode (ChildNode); 1713446Smrj } 1723446Smrj 1733446Smrj /* If any type is OK, we are done */ 1743446Smrj 1753446Smrj if (Type == ACPI_TYPE_ANY) 1763446Smrj { 1773446Smrj /* NextNode is NULL if we are at the end-of-list */ 1783446Smrj 1793446Smrj return (NextNode); 1803446Smrj } 1813446Smrj 1823446Smrj /* Must search for the node -- but within this scope only */ 1833446Smrj 1843446Smrj while (NextNode) 1853446Smrj { 1863446Smrj /* If type matches, we are done */ 1873446Smrj 1883446Smrj if (NextNode->Type == Type) 1893446Smrj { 1903446Smrj return (NextNode); 1913446Smrj } 1923446Smrj 1933446Smrj /* Otherwise, move on to the next node */ 1943446Smrj 1953446Smrj NextNode = AcpiNsGetNextValidNode (NextNode); 1963446Smrj } 1973446Smrj 1983446Smrj /* Not found */ 1993446Smrj 2003446Smrj return (NULL); 2013446Smrj } 2023446Smrj 2033446Smrj 2043446Smrj /******************************************************************************* 2053446Smrj * 2063446Smrj * FUNCTION: AcpiNsWalkNamespace 2073446Smrj * 2083446Smrj * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 2093446Smrj * StartNode - Handle in namespace where search begins 2103446Smrj * MaxDepth - Depth to which search is to reach 211*7851SDana.Myers@Sun.COM * Flags - Whether to unlock the NS before invoking 2123446Smrj * the callback routine 2133446Smrj * UserFunction - Called when an object of "Type" is found 2143446Smrj * Context - Passed to user function 2153446Smrj * ReturnValue - from the UserFunction if terminated early. 2163446Smrj * Otherwise, returns NULL. 2173446Smrj * RETURNS: Status 2183446Smrj * 2193446Smrj * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 2203446Smrj * starting (and ending) at the node specified by StartHandle. 2213446Smrj * The UserFunction is called whenever a node that matches 2223446Smrj * the type parameter is found. If the user function returns 2233446Smrj * a non-zero value, the search is terminated immediately and this 2243446Smrj * value is returned to the caller. 2253446Smrj * 2263446Smrj * The point of this procedure is to provide a generic namespace 2273446Smrj * walk routine that can be called from multiple places to 2283446Smrj * provide multiple services; the User Function can be tailored 2293446Smrj * to each task, whether it is a print function, a compare 2303446Smrj * function, etc. 2313446Smrj * 2323446Smrj ******************************************************************************/ 2333446Smrj 2343446Smrj ACPI_STATUS 2353446Smrj AcpiNsWalkNamespace ( 2363446Smrj ACPI_OBJECT_TYPE Type, 2373446Smrj ACPI_HANDLE StartNode, 2383446Smrj UINT32 MaxDepth, 239*7851SDana.Myers@Sun.COM UINT32 Flags, 2403446Smrj ACPI_WALK_CALLBACK UserFunction, 2413446Smrj void *Context, 2423446Smrj void **ReturnValue) 2433446Smrj { 2443446Smrj ACPI_STATUS Status; 2453446Smrj ACPI_STATUS MutexStatus; 2463446Smrj ACPI_NAMESPACE_NODE *ChildNode; 2473446Smrj ACPI_NAMESPACE_NODE *ParentNode; 2483446Smrj ACPI_OBJECT_TYPE ChildType; 2493446Smrj UINT32 Level; 2503446Smrj 2513446Smrj 2523446Smrj ACPI_FUNCTION_TRACE (NsWalkNamespace); 2533446Smrj 2543446Smrj 2553446Smrj /* Special case for the namespace Root Node */ 2563446Smrj 2573446Smrj if (StartNode == ACPI_ROOT_OBJECT) 2583446Smrj { 2593446Smrj StartNode = AcpiGbl_RootNode; 2603446Smrj } 2613446Smrj 2623446Smrj /* Null child means "get first node" */ 2633446Smrj 2643446Smrj ParentNode = StartNode; 2653446Smrj ChildNode = NULL; 2663446Smrj ChildType = ACPI_TYPE_ANY; 2673446Smrj Level = 1; 2683446Smrj 2693446Smrj /* 2703446Smrj * Traverse the tree of nodes until we bubble back up to where we 2713446Smrj * started. When Level is zero, the loop is done because we have 2723446Smrj * bubbled up to (and passed) the original parent handle (StartEntry) 2733446Smrj */ 2743446Smrj while (Level > 0) 2753446Smrj { 2763446Smrj /* Get the next node in this scope. Null if not found */ 2773446Smrj 2783446Smrj Status = AE_OK; 2793446Smrj ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 2803446Smrj if (ChildNode) 2813446Smrj { 282*7851SDana.Myers@Sun.COM /* Found next child, get the type if we are not searching for ANY */ 283*7851SDana.Myers@Sun.COM 2843446Smrj if (Type != ACPI_TYPE_ANY) 2853446Smrj { 2863446Smrj ChildType = ChildNode->Type; 2873446Smrj } 2883446Smrj 289*7851SDana.Myers@Sun.COM /* 290*7851SDana.Myers@Sun.COM * Ignore all temporary namespace nodes (created during control 291*7851SDana.Myers@Sun.COM * method execution) unless told otherwise. These temporary nodes 292*7851SDana.Myers@Sun.COM * can cause a race condition because they can be deleted during the 293*7851SDana.Myers@Sun.COM * execution of the user function (if the namespace is unlocked before 294*7851SDana.Myers@Sun.COM * invocation of the user function.) Only the debugger namespace dump 295*7851SDana.Myers@Sun.COM * will examine the temporary nodes. 296*7851SDana.Myers@Sun.COM */ 297*7851SDana.Myers@Sun.COM if ((ChildNode->Flags & ANOBJ_TEMPORARY) && 298*7851SDana.Myers@Sun.COM !(Flags & ACPI_NS_WALK_TEMP_NODES)) 299*7851SDana.Myers@Sun.COM { 300*7851SDana.Myers@Sun.COM Status = AE_CTRL_DEPTH; 301*7851SDana.Myers@Sun.COM } 302*7851SDana.Myers@Sun.COM 303*7851SDana.Myers@Sun.COM /* Type must match requested type */ 304*7851SDana.Myers@Sun.COM 305*7851SDana.Myers@Sun.COM else if (ChildType == Type) 3063446Smrj { 3073446Smrj /* 308*7851SDana.Myers@Sun.COM * Found a matching node, invoke the user callback function. 309*7851SDana.Myers@Sun.COM * Unlock the namespace if flag is set. 3103446Smrj */ 311*7851SDana.Myers@Sun.COM if (Flags & ACPI_NS_WALK_UNLOCK) 3123446Smrj { 3133446Smrj MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 3143446Smrj if (ACPI_FAILURE (MutexStatus)) 3153446Smrj { 3163446Smrj return_ACPI_STATUS (MutexStatus); 3173446Smrj } 3183446Smrj } 3193446Smrj 320*7851SDana.Myers@Sun.COM Status = UserFunction (ChildNode, Level, Context, ReturnValue); 3213446Smrj 322*7851SDana.Myers@Sun.COM if (Flags & ACPI_NS_WALK_UNLOCK) 3233446Smrj { 3243446Smrj MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 3253446Smrj if (ACPI_FAILURE (MutexStatus)) 3263446Smrj { 3273446Smrj return_ACPI_STATUS (MutexStatus); 3283446Smrj } 3293446Smrj } 3303446Smrj 3313446Smrj switch (Status) 3323446Smrj { 3333446Smrj case AE_OK: 3343446Smrj case AE_CTRL_DEPTH: 3353446Smrj 3363446Smrj /* Just keep going */ 3373446Smrj break; 3383446Smrj 3393446Smrj case AE_CTRL_TERMINATE: 3403446Smrj 3413446Smrj /* Exit now, with OK status */ 3423446Smrj 3433446Smrj return_ACPI_STATUS (AE_OK); 3443446Smrj 3453446Smrj default: 3463446Smrj 3473446Smrj /* All others are valid exceptions */ 3483446Smrj 3493446Smrj return_ACPI_STATUS (Status); 3503446Smrj } 3513446Smrj } 3523446Smrj 3533446Smrj /* 354*7851SDana.Myers@Sun.COM * Depth first search: Attempt to go down another level in the 355*7851SDana.Myers@Sun.COM * namespace if we are allowed to. Don't go any further if we have 356*7851SDana.Myers@Sun.COM * reached the caller specified maximum depth or if the user 357*7851SDana.Myers@Sun.COM * function has specified that the maximum depth has been reached. 3583446Smrj */ 3593446Smrj if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) 3603446Smrj { 3613446Smrj if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 3623446Smrj { 363*7851SDana.Myers@Sun.COM /* There is at least one child of this node, visit it */ 364*7851SDana.Myers@Sun.COM 3653446Smrj Level++; 3663446Smrj ParentNode = ChildNode; 367*7851SDana.Myers@Sun.COM ChildNode = NULL; 3683446Smrj } 3693446Smrj } 3703446Smrj } 3713446Smrj else 3723446Smrj { 3733446Smrj /* 374*7851SDana.Myers@Sun.COM * No more children of this node (AcpiNsGetNextNode failed), go 375*7851SDana.Myers@Sun.COM * back upwards in the namespace tree to the node's parent. 3763446Smrj */ 3773446Smrj Level--; 3783446Smrj ChildNode = ParentNode; 3793446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 3803446Smrj } 3813446Smrj } 3823446Smrj 3833446Smrj /* Complete walk, not terminated by user function */ 3843446Smrj 3853446Smrj return_ACPI_STATUS (AE_OK); 3863446Smrj } 3873446Smrj 3883446Smrj 389