nswalk.c revision 85756
1275970Scy/****************************************************************************** 2275970Scy * 3275970Scy * Module Name: nswalk - Functions for walking the ACPI namespace 4275970Scy * $Revision: 26 $ 5275970Scy * 6275970Scy *****************************************************************************/ 7275970Scy 8275970Scy/****************************************************************************** 9275970Scy * 10275970Scy * 1. Copyright Notice 11275970Scy * 12275970Scy * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 13275970Scy * All rights reserved. 14275970Scy * 15275970Scy * 2. License 16275970Scy * 17275970Scy * 2.1. This is your license from Intel Corp. under its intellectual property 18275970Scy * rights. You may have additional license terms from the party that provided 19275970Scy * you this software, covering your right to use that party's intellectual 20275970Scy * property rights. 21275970Scy * 22275970Scy * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23275970Scy * copy of the source code appearing in this file ("Covered Code") an 24275970Scy * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25275970Scy * base code distributed originally by Intel ("Original Intel Code") to copy, 26275970Scy * make derivatives, distribute, use and display any portion of the Covered 27275970Scy * Code in any form, with the right to sublicense such rights; and 28275970Scy * 29275970Scy * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30282408Scy * license (with the right to sublicense), under only those claims of Intel 31275970Scy * patents that are infringed by the Original Intel Code, to make, use, sell, 32275970Scy * offer to sell, and import the Covered Code and derivative works thereof 33275970Scy * solely to the minimum extent necessary to exercise the above copyright 34275970Scy * license, and in no event shall the patent license extend to any additions 35275970Scy * to or modifications of the Original Intel Code. No other license or right 36275970Scy * is granted directly or by implication, estoppel or otherwise; 37275970Scy * 38275970Scy * The above copyright and patent license is granted only if the following 39275970Scy * conditions are met: 40275970Scy * 41275970Scy * 3. Conditions 42275970Scy * 43275970Scy * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44275970Scy * Redistribution of source code of any substantial portion of the Covered 45275970Scy * Code or modification with rights to further distribute source must include 46275970Scy * the above Copyright Notice, the above License, this list of Conditions, 47275970Scy * and the following Disclaimer and Export Compliance provision. In addition, 48275970Scy * Licensee must cause all Covered Code to which Licensee contributes to 49275970Scy * contain a file documenting the changes Licensee made to create that Covered 50275970Scy * Code and the date of any change. Licensee must include in that file the 51275970Scy * documentation of any changes made by any predecessor Licensee. Licensee 52275970Scy * must include a prominent statement that the modification is derived, 53275970Scy * directly or indirectly, from Original Intel Code. 54275970Scy * 55275970Scy * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56275970Scy * Redistribution of source code of any substantial portion of the Covered 57275970Scy * Code or modification without rights to further distribute source must 58275970Scy * include the following Disclaimer and Export Compliance provision in the 59275970Scy * documentation and/or other materials provided with distribution. In 60275970Scy * addition, Licensee may not authorize further sublicense of source of any 61275970Scy * portion of the Covered Code, and must include terms to the effect that the 62275970Scy * license from Licensee to its licensee is limited to the intellectual 63275970Scy * property embodied in the software Licensee provides to its licensee, and 64275970Scy * not to intellectual property embodied in modifications its licensee may 65275970Scy * make. 66275970Scy * 67275970Scy * 3.3. Redistribution of Executable. Redistribution in executable form of any 68275970Scy * substantial portion of the Covered Code or modification must reproduce the 69275970Scy * above Copyright Notice, and the following Disclaimer and Export Compliance 70275970Scy * provision in the documentation and/or other materials provided with the 71275970Scy * distribution. 72275970Scy * 73275970Scy * 3.4. Intel retains all right, title, and interest in and to the Original 74275970Scy * Intel Code. 75275970Scy * 76275970Scy * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77275970Scy * Intel shall be used in advertising or otherwise to promote the sale, use or 78275970Scy * other dealings in products derived from or relating to the Covered Code 79275970Scy * without prior written authorization from Intel. 80275970Scy * 81275970Scy * 4. Disclaimer and Export Compliance 82275970Scy * 83275970Scy * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84275970Scy * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85275970Scy * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86275970Scy * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87275970Scy * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88275970Scy * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89275970Scy * PARTICULAR PURPOSE. 90275970Scy * 91275970Scy * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92275970Scy * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93275970Scy * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94275970Scy * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95275970Scy * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96275970Scy * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97275970Scy * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98275970Scy * LIMITED REMEDY. 99275970Scy * 100275970Scy * 4.3. Licensee shall not export, either directly or indirectly, any of this 101275970Scy * software or system incorporating such software without first obtaining any 102275970Scy * required license or other approval from the U. S. Department of Commerce or 103275970Scy * any other agency or department of the United States Government. In the 104275970Scy * event Licensee exports any such software from the United States or 105275970Scy * re-exports any such software from a foreign destination, Licensee shall 106275970Scy * ensure that the distribution and export/re-export of the software is in 107275970Scy * compliance with all laws, regulations, orders, or other restrictions of the 108275970Scy * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109275970Scy * any of its subsidiaries will export/re-export any technical data, process, 110275970Scy * software, or service, directly or indirectly, to any country for which the 111275970Scy * United States government or any agency thereof requires an export license, 112275970Scy * other governmental approval, or letter of assurance, without first obtaining 113275970Scy * such license, approval or letter. 114275970Scy * 115275970Scy *****************************************************************************/ 116275970Scy 117275970Scy 118275970Scy#define __NSWALK_C__ 119275970Scy 120275970Scy#include "acpi.h" 121275970Scy#include "acinterp.h" 122275970Scy#include "acnamesp.h" 123275970Scy 124275970Scy 125275970Scy#define _COMPONENT ACPI_NAMESPACE 126275970Scy MODULE_NAME ("nswalk") 127275970Scy 128275970Scy 129275970Scy/******************************************************************************* 130275970Scy * 131275970Scy * FUNCTION: AcpiNsGetNextNode 132275970Scy * 133275970Scy * PARAMETERS: Type - Type of node to be searched for 134275970Scy * ParentNode - Parent node whose children we are 135275970Scy * getting 136275970Scy * ChildNode - Previous child that was found. 137275970Scy * The NEXT child will be returned 138275970Scy * 139275970Scy * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if 140275970Scy * none is found. 141275970Scy * 142275970Scy * DESCRIPTION: Return the next peer node within the namespace. If Handle 143275970Scy * is valid, Scope is ignored. Otherwise, the first node 144275970Scy * within Scope is returned. 145275970Scy * 146275970Scy ******************************************************************************/ 147275970Scy 148275970ScyACPI_NAMESPACE_NODE * 149275970ScyAcpiNsGetNextNode ( 150275970Scy ACPI_OBJECT_TYPE8 Type, 151275970Scy ACPI_NAMESPACE_NODE *ParentNode, 152275970Scy ACPI_NAMESPACE_NODE *ChildNode) 153275970Scy{ 154275970Scy ACPI_NAMESPACE_NODE *NextNode = NULL; 155275970Scy 156275970Scy 157275970Scy FUNCTION_ENTRY (); 158275970Scy 159275970Scy 160275970Scy if (!ChildNode) 161275970Scy { 162275970Scy /* It's really the parent's _scope_ that we want */ 163275970Scy 164275970Scy if (ParentNode->Child) 165275970Scy { 166275970Scy NextNode = ParentNode->Child; 167275970Scy } 168275970Scy } 169275970Scy 170275970Scy else 171275970Scy { 172275970Scy /* Start search at the NEXT node */ 173275970Scy 174275970Scy NextNode = AcpiNsGetNextValidNode (ChildNode); 175275970Scy } 176275970Scy 177275970Scy /* If any type is OK, we are done */ 178275970Scy 179275970Scy if (Type == ACPI_TYPE_ANY) 180275970Scy { 181275970Scy /* NextNode is NULL if we are at the end-of-list */ 182275970Scy 183275970Scy return (NextNode); 184275970Scy } 185275970Scy 186275970Scy /* Must search for the node -- but within this scope only */ 187275970Scy 188275970Scy while (NextNode) 189275970Scy { 190275970Scy /* If type matches, we are done */ 191275970Scy 192275970Scy if (NextNode->Type == Type) 193275970Scy { 194275970Scy return (NextNode); 195275970Scy } 196275970Scy 197275970Scy /* Otherwise, move on to the next node */ 198275970Scy 199275970Scy NextNode = AcpiNsGetNextValidNode (NextNode); 200275970Scy } 201275970Scy 202275970Scy /* Not found */ 203275970Scy 204275970Scy return (NULL); 205275970Scy} 206 207 208/******************************************************************************* 209 * 210 * FUNCTION: AcpiNsWalkNamespace 211 * 212 * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 213 * StartNode - Handle in namespace where search begins 214 * MaxDepth - Depth to which search is to reach 215 * UnlockBeforeCallback- Whether to unlock the NS before invoking 216 * the callback routine 217 * UserFunction - Called when an object of "Type" is found 218 * Context - Passed to user function 219 * ReturnValue - from the UserFunction if terminated early. 220 * Otherwise, returns NULL. 221 * RETURNS: Status 222 * 223 * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 224 * starting (and ending) at the node specified by StartHandle. 225 * The UserFunction is called whenever a node that matches 226 * the type parameter is found. If the user function returns 227 * a non-zero value, the search is terminated immediately and this 228 * value is returned to the caller. 229 * 230 * The point of this procedure is to provide a generic namespace 231 * walk routine that can be called from multiple places to 232 * provide multiple services; the User Function can be tailored 233 * to each task, whether it is a print function, a compare 234 * function, etc. 235 * 236 ******************************************************************************/ 237 238ACPI_STATUS 239AcpiNsWalkNamespace ( 240 ACPI_OBJECT_TYPE8 Type, 241 ACPI_HANDLE StartNode, 242 UINT32 MaxDepth, 243 BOOLEAN UnlockBeforeCallback, 244 ACPI_WALK_CALLBACK UserFunction, 245 void *Context, 246 void **ReturnValue) 247{ 248 ACPI_STATUS Status; 249 ACPI_NAMESPACE_NODE *ChildNode; 250 ACPI_NAMESPACE_NODE *ParentNode; 251 ACPI_OBJECT_TYPE8 ChildType; 252 UINT32 Level; 253 254 255 FUNCTION_TRACE ("NsWalkNamespace"); 256 257 258 /* Special case for the namespace Root Node */ 259 260 if (StartNode == ACPI_ROOT_OBJECT) 261 { 262 StartNode = AcpiGbl_RootNode; 263 } 264 265 /* Null child means "get first node" */ 266 267 ParentNode = StartNode; 268 ChildNode = 0; 269 ChildType = ACPI_TYPE_ANY; 270 Level = 1; 271 272 /* 273 * Traverse the tree of nodes until we bubble back up to where we 274 * started. When Level is zero, the loop is done because we have 275 * bubbled up to (and passed) the original parent handle (StartEntry) 276 */ 277 while (Level > 0) 278 { 279 /* Get the next node in this scope. Null if not found */ 280 281 Status = AE_OK; 282 ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 283 if (ChildNode) 284 { 285 /* 286 * Found node, Get the type if we are not 287 * searching for ANY 288 */ 289 if (Type != ACPI_TYPE_ANY) 290 { 291 ChildType = ChildNode->Type; 292 } 293 294 if (ChildType == Type) 295 { 296 /* 297 * Found a matching node, invoke the user 298 * callback function 299 */ 300 if (UnlockBeforeCallback) 301 { 302 AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 303 } 304 305 Status = UserFunction (ChildNode, Level, 306 Context, ReturnValue); 307 308 if (UnlockBeforeCallback) 309 { 310 AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 311 } 312 313 switch (Status) 314 { 315 case AE_OK: 316 case AE_CTRL_DEPTH: 317 318 /* Just keep going */ 319 break; 320 321 case AE_CTRL_TERMINATE: 322 323 /* Exit now, with OK status */ 324 325 return_ACPI_STATUS (AE_OK); 326 break; 327 328 default: 329 330 /* All others are valid exceptions */ 331 332 return_ACPI_STATUS (Status); 333 break; 334 } 335 } 336 337 /* 338 * Depth first search: 339 * Attempt to go down another level in the namespace 340 * if we are allowed to. Don't go any further if we 341 * have reached the caller specified maximum depth 342 * or if the user function has specified that the 343 * maximum depth has been reached. 344 */ 345 if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) 346 { 347 if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0)) 348 { 349 /* 350 * There is at least one child of this 351 * node, visit the onde 352 */ 353 Level++; 354 ParentNode = ChildNode; 355 ChildNode = 0; 356 } 357 } 358 } 359 360 else 361 { 362 /* 363 * No more children of this node (AcpiNsGetNextNode 364 * failed), go back upwards in the namespace tree to 365 * the node's parent. 366 */ 367 Level--; 368 ChildNode = ParentNode; 369 ParentNode = AcpiNsGetParentObject (ParentNode); 370 } 371 } 372 373 /* Complete walk, not terminated by user function */ 374 375 return_ACPI_STATUS (AE_OK); 376} 377 378 379