nswalk.c revision 99679
1214640Sdim/****************************************************************************** 2214640Sdim * 3214640Sdim * Module Name: nswalk - Functions for walking the ACPI namespace 4214640Sdim * $Revision: 33 $ 5214640Sdim * 6214640Sdim *****************************************************************************/ 7214640Sdim 8214640Sdim/****************************************************************************** 9214640Sdim * 10214640Sdim * 1. Copyright Notice 11214640Sdim * 12214640Sdim * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 13214640Sdim * All rights reserved. 14214640Sdim * 15214640Sdim * 2. License 16214640Sdim * 17214640Sdim * 2.1. This is your license from Intel Corp. under its intellectual property 18214640Sdim * rights. You may have additional license terms from the party that provided 19214640Sdim * you this software, covering your right to use that party's intellectual 20214640Sdim * property rights. 21214640Sdim * 22214640Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23214640Sdim * copy of the source code appearing in this file ("Covered Code") an 24214640Sdim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25214640Sdim * base code distributed originally by Intel ("Original Intel Code") to copy, 26214640Sdim * make derivatives, distribute, use and display any portion of the Covered 27214640Sdim * Code in any form, with the right to sublicense such rights; and 28214640Sdim * 29214640Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30214640Sdim * license (with the right to sublicense), under only those claims of Intel 31214640Sdim * patents that are infringed by the Original Intel Code, to make, use, sell, 32214640Sdim * offer to sell, and import the Covered Code and derivative works thereof 33214640Sdim * solely to the minimum extent necessary to exercise the above copyright 34214640Sdim * license, and in no event shall the patent license extend to any additions 35214640Sdim * to or modifications of the Original Intel Code. No other license or right 36214640Sdim * is granted directly or by implication, estoppel or otherwise; 37214640Sdim * 38214640Sdim * The above copyright and patent license is granted only if the following 39214640Sdim * conditions are met: 40214640Sdim * 41214640Sdim * 3. Conditions 42214640Sdim * 43214640Sdim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44214640Sdim * Redistribution of source code of any substantial portion of the Covered 45214640Sdim * Code or modification with rights to further distribute source must include 46214640Sdim * the above Copyright Notice, the above License, this list of Conditions, 47214640Sdim * and the following Disclaimer and Export Compliance provision. In addition, 48214640Sdim * Licensee must cause all Covered Code to which Licensee contributes to 49214640Sdim * contain a file documenting the changes Licensee made to create that Covered 50214640Sdim * Code and the date of any change. Licensee must include in that file the 51214640Sdim * documentation of any changes made by any predecessor Licensee. Licensee 52214640Sdim * must include a prominent statement that the modification is derived, 53214640Sdim * directly or indirectly, from Original Intel Code. 54214640Sdim * 55214640Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56214640Sdim * Redistribution of source code of any substantial portion of the Covered 57214640Sdim * Code or modification without rights to further distribute source must 58214640Sdim * include the following Disclaimer and Export Compliance provision in the 59214640Sdim * documentation and/or other materials provided with distribution. In 60214640Sdim * addition, Licensee may not authorize further sublicense of source of any 61214640Sdim * portion of the Covered Code, and must include terms to the effect that the 62214640Sdim * license from Licensee to its licensee is limited to the intellectual 63214640Sdim * property embodied in the software Licensee provides to its licensee, and 64214640Sdim * not to intellectual property embodied in modifications its licensee may 65214640Sdim * make. 66214640Sdim * 67214640Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any 68214640Sdim * substantial portion of the Covered Code or modification must reproduce the 69214640Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance 70214640Sdim * provision in the documentation and/or other materials provided with the 71214640Sdim * distribution. 72214640Sdim * 73214640Sdim * 3.4. Intel retains all right, title, and interest in and to the Original 74214640Sdim * Intel Code. 75214640Sdim * 76214640Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77214640Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or 78214640Sdim * other dealings in products derived from or relating to the Covered Code 79214640Sdim * without prior written authorization from Intel. 80214640Sdim * 81214640Sdim * 4. Disclaimer and Export Compliance 82214640Sdim * 83214640Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84214640Sdim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85214640Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86214640Sdim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87214640Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88214640Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89214640Sdim * PARTICULAR PURPOSE. 90214640Sdim * 91214640Sdim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92214640Sdim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93214640Sdim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94214640Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95214640Sdim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96214640Sdim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97214640Sdim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98214640Sdim * LIMITED REMEDY. 99214640Sdim * 100214640Sdim * 4.3. Licensee shall not export, either directly or indirectly, any of this 101214640Sdim * software or system incorporating such software without first obtaining any 102214640Sdim * required license or other approval from the U. S. Department of Commerce or 103214640Sdim * any other agency or department of the United States Government. In the 104214640Sdim * event Licensee exports any such software from the United States or 105214640Sdim * re-exports any such software from a foreign destination, Licensee shall 106214640Sdim * ensure that the distribution and export/re-export of the software is in 107214640Sdim * compliance with all laws, regulations, orders, or other restrictions of the 108214640Sdim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109214640Sdim * any of its subsidiaries will export/re-export any technical data, process, 110214640Sdim * software, or service, directly or indirectly, to any country for which the 111214640Sdim * United States government or any agency thereof requires an export license, 112214640Sdim * other governmental approval, or letter of assurance, without first obtaining 113214640Sdim * such license, approval or letter. 114214640Sdim * 115214640Sdim *****************************************************************************/ 116214640Sdim 117214640Sdim 118214640Sdim#define __NSWALK_C__ 119214640Sdim 120214640Sdim#include "acpi.h" 121214640Sdim#include "acnamesp.h" 122214640Sdim 123214640Sdim 124214640Sdim#define _COMPONENT ACPI_NAMESPACE 125214640Sdim ACPI_MODULE_NAME ("nswalk") 126214640Sdim 127214640Sdim 128214640Sdim/******************************************************************************* 129214640Sdim * 130214640Sdim * FUNCTION: AcpiNsGetNextNode 131214640Sdim * 132214640Sdim * PARAMETERS: Type - Type of node to be searched for 133214640Sdim * ParentNode - Parent node whose children we are 134235211Sgjb * getting 135214640Sdim * ChildNode - Previous child that was found. 136214640Sdim * The NEXT child will be returned 137214640Sdim * 138214640Sdim * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if 139214640Sdim * none is found. 140214640Sdim * 141214640Sdim * DESCRIPTION: Return the next peer node within the namespace. If Handle 142214640Sdim * is valid, Scope is ignored. Otherwise, the first node 143214640Sdim * within Scope is returned. 144214640Sdim * 145214640Sdim ******************************************************************************/ 146214640Sdim 147214640SdimACPI_NAMESPACE_NODE * 148214640SdimAcpiNsGetNextNode ( 149214640Sdim ACPI_OBJECT_TYPE Type, 150214640Sdim ACPI_NAMESPACE_NODE *ParentNode, 151214640Sdim ACPI_NAMESPACE_NODE *ChildNode) 152214640Sdim{ 153214640Sdim ACPI_NAMESPACE_NODE *NextNode = NULL; 154214640Sdim 155214640Sdim 156214640Sdim ACPI_FUNCTION_ENTRY (); 157214640Sdim 158214640Sdim 159214640Sdim if (!ChildNode) 160214640Sdim { 161214640Sdim /* It's really the parent's _scope_ that we want */ 162214640Sdim 163214640Sdim if (ParentNode->Child) 164214640Sdim { 165214640Sdim NextNode = ParentNode->Child; 166214640Sdim } 167214640Sdim } 168214640Sdim 169214640Sdim else 170214640Sdim { 171214640Sdim /* Start search at the NEXT node */ 172214640Sdim 173214640Sdim NextNode = AcpiNsGetNextValidNode (ChildNode); 174214640Sdim } 175214640Sdim 176214640Sdim /* If any type is OK, we are done */ 177214640Sdim 178214640Sdim if (Type == ACPI_TYPE_ANY) 179214640Sdim { 180214640Sdim /* NextNode is NULL if we are at the end-of-list */ 181214640Sdim 182214640Sdim return (NextNode); 183214640Sdim } 184214640Sdim 185214640Sdim /* Must search for the node -- but within this scope only */ 186214640Sdim 187214640Sdim while (NextNode) 188214640Sdim { 189214640Sdim /* If type matches, we are done */ 190214640Sdim 191214640Sdim if (NextNode->Type == Type) 192214640Sdim { 193214640Sdim return (NextNode); 194214640Sdim } 195214640Sdim 196214640Sdim /* Otherwise, move on to the next node */ 197214640Sdim 198214640Sdim NextNode = AcpiNsGetNextValidNode (NextNode); 199214640Sdim } 200214640Sdim 201214640Sdim /* Not found */ 202214640Sdim 203214640Sdim return (NULL); 204214640Sdim} 205214640Sdim 206214640Sdim 207214640Sdim/******************************************************************************* 208214640Sdim * 209214640Sdim * FUNCTION: AcpiNsWalkNamespace 210214640Sdim * 211214640Sdim * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 212214640Sdim * StartNode - Handle in namespace where search begins 213214640Sdim * MaxDepth - Depth to which search is to reach 214214640Sdim * UnlockBeforeCallback- Whether to unlock the NS before invoking 215214640Sdim * the callback routine 216214640Sdim * UserFunction - Called when an object of "Type" is found 217214640Sdim * Context - Passed to user function 218214640Sdim * ReturnValue - from the UserFunction if terminated early. 219214640Sdim * Otherwise, returns NULL. 220214640Sdim * RETURNS: Status 221214640Sdim * 222214640Sdim * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 223214640Sdim * starting (and ending) at the node specified by StartHandle. 224214640Sdim * The UserFunction is called whenever a node that matches 225214640Sdim * the type parameter is found. If the user function returns 226214640Sdim * a non-zero value, the search is terminated immediately and this 227214640Sdim * value is returned to the caller. 228214640Sdim * 229214640Sdim * The point of this procedure is to provide a generic namespace 230214640Sdim * walk routine that can be called from multiple places to 231214640Sdim * provide multiple services; the User Function can be tailored 232214640Sdim * to each task, whether it is a print function, a compare 233214640Sdim * function, etc. 234214640Sdim * 235214640Sdim ******************************************************************************/ 236214640Sdim 237214640SdimACPI_STATUS 238214640SdimAcpiNsWalkNamespace ( 239214640Sdim ACPI_OBJECT_TYPE Type, 240214640Sdim ACPI_HANDLE StartNode, 241214640Sdim UINT32 MaxDepth, 242214640Sdim BOOLEAN UnlockBeforeCallback, 243214640Sdim ACPI_WALK_CALLBACK UserFunction, 244214640Sdim void *Context, 245214640Sdim void **ReturnValue) 246214640Sdim{ 247214640Sdim ACPI_STATUS Status; 248214640Sdim ACPI_NAMESPACE_NODE *ChildNode; 249214640Sdim ACPI_NAMESPACE_NODE *ParentNode; 250214640Sdim ACPI_OBJECT_TYPE ChildType; 251214640Sdim UINT32 Level; 252214640Sdim 253214640Sdim 254214640Sdim ACPI_FUNCTION_TRACE ("NsWalkNamespace"); 255214640Sdim 256214640Sdim 257214640Sdim /* Special case for the namespace Root Node */ 258214640Sdim 259214640Sdim if (StartNode == ACPI_ROOT_OBJECT) 260214640Sdim { 261214640Sdim StartNode = AcpiGbl_RootNode; 262214640Sdim } 263214640Sdim 264214640Sdim /* Null child means "get first node" */ 265214640Sdim 266214640Sdim ParentNode = StartNode; 267214640Sdim ChildNode = 0; 268214640Sdim ChildType = ACPI_TYPE_ANY; 269214640Sdim Level = 1; 270214640Sdim 271214640Sdim /* 272214640Sdim * Traverse the tree of nodes until we bubble back up to where we 273214640Sdim * started. When Level is zero, the loop is done because we have 274214640Sdim * bubbled up to (and passed) the original parent handle (StartEntry) 275214640Sdim */ 276214640Sdim while (Level > 0) 277214640Sdim { 278214640Sdim /* Get the next node in this scope. Null if not found */ 279214640Sdim 280214640Sdim Status = AE_OK; 281214640Sdim ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 282214640Sdim if (ChildNode) 283214640Sdim { 284214640Sdim /* 285214640Sdim * Found node, Get the type if we are not 286214640Sdim * searching for ANY 287214640Sdim */ 288214640Sdim if (Type != ACPI_TYPE_ANY) 289214640Sdim { 290214640Sdim ChildType = ChildNode->Type; 291214640Sdim } 292214640Sdim 293214640Sdim if (ChildType == Type) 294214640Sdim { 295214640Sdim /* 296214640Sdim * Found a matching node, invoke the user 297214640Sdim * callback function 298214640Sdim */ 299214640Sdim if (UnlockBeforeCallback) 300214640Sdim { 301214640Sdim Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 302214640Sdim if (ACPI_FAILURE (Status)) 303226436Seadler { 304226436Seadler return_ACPI_STATUS (Status); 305214640Sdim } 306214640Sdim } 307214640Sdim 308214640Sdim Status = UserFunction (ChildNode, Level, 309214640Sdim Context, ReturnValue); 310214640Sdim 311214640Sdim if (UnlockBeforeCallback) 312214640Sdim { 313214640Sdim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 314214640Sdim if (ACPI_FAILURE (Status)) 315214640Sdim { 316214640Sdim return_ACPI_STATUS (Status); 317214640Sdim } 318214640Sdim } 319214640Sdim 320214640Sdim switch (Status) 321214640Sdim { 322214640Sdim case AE_OK: 323214640Sdim case AE_CTRL_DEPTH: 324214640Sdim 325214640Sdim /* Just keep going */ 326214640Sdim break; 327214640Sdim 328214640Sdim case AE_CTRL_TERMINATE: 329214640Sdim 330214640Sdim /* Exit now, with OK status */ 331214640Sdim 332214640Sdim return_ACPI_STATUS (AE_OK); 333214640Sdim 334214640Sdim default: 335214640Sdim 336214640Sdim /* All others are valid exceptions */ 337214640Sdim 338214640Sdim return_ACPI_STATUS (Status); 339214640Sdim } 340214640Sdim } 341214640Sdim 342214640Sdim /* 343214640Sdim * Depth first search: 344214640Sdim * Attempt to go down another level in the namespace 345214640Sdim * if we are allowed to. Don't go any further if we 346214640Sdim * have reached the caller specified maximum depth 347214640Sdim * or if the user function has specified that the 348214640Sdim * maximum depth has been reached. 349214640Sdim */ 350214640Sdim if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) 351214640Sdim { 352214640Sdim if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0)) 353214640Sdim { 354214640Sdim /* 355214640Sdim * There is at least one child of this 356214640Sdim * node, visit the onde 357214640Sdim */ 358214640Sdim Level++; 359214640Sdim ParentNode = ChildNode; 360214640Sdim ChildNode = 0; 361214640Sdim } 362214640Sdim } 363214640Sdim } 364214640Sdim else 365214640Sdim { 366214640Sdim /* 367214640Sdim * No more children of this node (AcpiNsGetNextNode 368214640Sdim * failed), go back upwards in the namespace tree to 369214640Sdim * the node's parent. 370214640Sdim */ 371214640Sdim Level--; 372214640Sdim ChildNode = ParentNode; 373214640Sdim ParentNode = AcpiNsGetParentNode (ParentNode); 374214640Sdim } 375214640Sdim } 376214640Sdim 377214640Sdim /* Complete walk, not terminated by user function */ 378214640Sdim 379214640Sdim return_ACPI_STATUS (AE_OK); 380214640Sdim} 381214640Sdim 382214640Sdim 383214640Sdim