nswalk.c revision 193267
1139823Simp/****************************************************************************** 21541Srgrimes * 31541Srgrimes * Module Name: nswalk - Functions for walking the ACPI namespace 4137668Smlaier * 51541Srgrimes *****************************************************************************/ 61541Srgrimes 71541Srgrimes/****************************************************************************** 81541Srgrimes * 91541Srgrimes * 1. Copyright Notice 101541Srgrimes * 111541Srgrimes * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 121541Srgrimes * All rights reserved. 131541Srgrimes * 141541Srgrimes * 2. License 151541Srgrimes * 161541Srgrimes * 2.1. This is your license from Intel Corp. under its intellectual property 171541Srgrimes * rights. You may have additional license terms from the party that provided 181541Srgrimes * you this software, covering your right to use that party's intellectual 191541Srgrimes * property rights. 201541Srgrimes * 211541Srgrimes * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 221541Srgrimes * copy of the source code appearing in this file ("Covered Code") an 231541Srgrimes * irrevocable, perpetual, worldwide license under Intel's copyrights in the 241541Srgrimes * base code distributed originally by Intel ("Original Intel Code") to copy, 251541Srgrimes * make derivatives, distribute, use and display any portion of the Covered 261541Srgrimes * Code in any form, with the right to sublicense such rights; and 271541Srgrimes * 281541Srgrimes * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 291541Srgrimes * license (with the right to sublicense), under only those claims of Intel 3010939Swollman * patents that are infringed by the Original Intel Code, to make, use, sell, 311541Srgrimes * offer to sell, and import the Covered Code and derivative works thereof 321541Srgrimes * solely to the minimum extent necessary to exercise the above copyright 33172467Ssilby * license, and in no event shall the patent license extend to any additions 34172467Ssilby * to or modifications of the Original Intel Code. No other license or right 35172467Ssilby * is granted directly or by implication, estoppel or otherwise; 36204902Sqingli * 37143868Sglebius * The above copyright and patent license is granted only if the following 381541Srgrimes * conditions are met: 391549Srgrimes * 4024204Sbde * 3. Conditions 411541Srgrimes * 42164033Srwatson * 3.1. Redistribution of Source with Rights to Further Distribute Source. 431541Srgrimes * Redistribution of source code of any substantial portion of the Covered 44186948Sbz * Code or modification with rights to further distribute source must include 4512704Sphk * the above Copyright Notice, the above License, this list of Conditions, 46186948Sbz * and the following Disclaimer and Export Compliance provision. In addition, 4712704Sphk * Licensee must cause all Covered Code to which Licensee contributes to 48192011Sqingli * contain a file documenting the changes Licensee made to create that Covered 491541Srgrimes * Code and the date of any change. Licensee must include in that file the 501541Srgrimes * documentation of any changes made by any predecessor Licensee. Licensee 51195914Sqingli * must include a prominent statement that the modification is derived, 52215207Sgnn * directly or indirectly, from Original Intel Code. 53192011Sqingli * 54186119Sqingli * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5555009Sshin * Redistribution of source code of any substantial portion of the Covered 561541Srgrimes * Code or modification without rights to further distribute source must 57192011Sqingli * include the following Disclaimer and Export Compliance provision in the 581541Srgrimes * documentation and/or other materials provided with distribution. In 591541Srgrimes * addition, Licensee may not authorize further sublicense of source of any 601541Srgrimes * portion of the Covered Code, and must include terms to the effect that the 6181127Sume * license from Licensee to its licensee is limited to the intellectual 62170613Sbms * property embodied in the software Licensee provides to its licensee, and 63189592Sbms * not to intellectual property embodied in modifications its licensee may 64195699Srwatson * make. 65195699Srwatson * 661541Srgrimes * 3.3. Redistribution of Executable. Redistribution in executable form of any 6792723Salfred * substantial portion of the Covered Code or modification must reproduce the 6892723Salfred * above Copyright Notice, and the following Disclaimer and Export Compliance 6992723Salfred * provision in the documentation and/or other materials provided with the 7092723Salfred * distribution. 7155009Sshin * 72137628Smlaier * 3.4. Intel retains all right, title, and interest in and to the Original 73222143Sqingli * Intel Code. 7492723Salfred * 7592723Salfred * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76228313Sglebius * Intel shall be used in advertising or otherwise to promote the sale, use or 77167729Sbms * other dealings in products derived from or relating to the Covered Code 781541Srgrimes * without prior written authorization from Intel. 79215701Sdim * 80207369Sbz * 4. Disclaimer and Export Compliance 81195699Srwatson * 82195699Srwatson * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83149221Sglebius * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8421666Swollman * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85207369Sbz * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86207369Sbz * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87207369Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88215207Sgnn * PARTICULAR PURPOSE. 89215207Sgnn * 90215207Sgnn * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 911541Srgrimes * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 921541Srgrimes * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93226401Sglebius * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 941541Srgrimes * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 951549Srgrimes * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96169454Srwatson * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 971541Srgrimes * LIMITED REMEDY. 981541Srgrimes * 991541Srgrimes * 4.3. Licensee shall not export, either directly or indirectly, any of this 1001541Srgrimes * software or system incorporating such software without first obtaining any 101194951Srwatson * required license or other approval from the U. S. Department of Commerce or 102226401Sglebius * any other agency or department of the United States Government. In the 103226401Sglebius * event Licensee exports any such software from the United States or 104226401Sglebius * re-exports any such software from a foreign destination, Licensee shall 105226401Sglebius * ensure that the distribution and export/re-export of the software is in 106194951Srwatson * compliance with all laws, regulations, orders, or other restrictions of the 1071541Srgrimes * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108194951Srwatson * any of its subsidiaries will export/re-export any technical data, process, 1091541Srgrimes * software, or service, directly or indirectly, to any country for which the 1101541Srgrimes * United States government or any agency thereof requires an export license, 1111541Srgrimes * other governmental approval, or letter of assurance, without first obtaining 1121541Srgrimes * such license, approval or letter. 113133486Sandre * 114133486Sandre *****************************************************************************/ 115133486Sandre 116133486Sandre 117169454Srwatson#define __NSWALK_C__ 118133486Sandre 119133486Sandre#include "acpi.h" 120133486Sandre#include "accommon.h" 121194951Srwatson#include "acnamesp.h" 122133486Sandre 123194951Srwatson 124194951Srwatson#define _COMPONENT ACPI_NAMESPACE 125184295Sbz ACPI_MODULE_NAME ("nswalk") 126194951Srwatson 127133486Sandre 128194951Srwatson/******************************************************************************* 129184295Sbz * 130133486Sandre * FUNCTION: AcpiNsGetNextNode 131133486Sandre * 132133486Sandre * PARAMETERS: ParentNode - Parent node whose children we are 1331541Srgrimes * getting 1341541Srgrimes * ChildNode - Previous child that was found. 1351541Srgrimes * The NEXT child will be returned 1361541Srgrimes * 1371549Srgrimes * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if 138169454Srwatson * none is found. 1391541Srgrimes * 1401541Srgrimes * DESCRIPTION: Return the next peer node within the namespace. If Handle 1411541Srgrimes * is valid, Scope is ignored. Otherwise, the first node 1421541Srgrimes * within Scope is returned. 143166450Sbms * 1441541Srgrimes ******************************************************************************/ 1451541Srgrimes 1461541SrgrimesACPI_NAMESPACE_NODE * 1471541SrgrimesAcpiNsGetNextNode ( 1481541Srgrimes ACPI_NAMESPACE_NODE *ParentNode, 1491541Srgrimes ACPI_NAMESPACE_NODE *ChildNode) 1501541Srgrimes{ 1511541Srgrimes ACPI_FUNCTION_ENTRY (); 1521541Srgrimes 1531541Srgrimes 1541541Srgrimes if (!ChildNode) 1551541Srgrimes { 15612296Sphk /* It's really the parent's _scope_ that we want */ 157169454Srwatson 1581541Srgrimes return (ParentNode->Child); 1591541Srgrimes } 1601541Srgrimes 1611541Srgrimes /* 1621541Srgrimes * Get the next node. 1634127Swollman * 164133874Srwatson * If we are at the end of this peer list, return NULL 1651541Srgrimes */ 1661541Srgrimes if (ChildNode->Flags & ANOBJ_END_OF_PEER_LIST) 1671541Srgrimes { 1681541Srgrimes return NULL; 1691541Srgrimes } 17055009Sshin 17155009Sshin /* Otherwise just return the next peer */ 17255009Sshin 17355009Sshin return (ChildNode->Peer); 17455009Sshin} 17555009Sshin 17655009Sshin 17755009Sshin/******************************************************************************* 17855009Sshin * 17955009Sshin * FUNCTION: AcpiNsGetNextNodeTyped 18055009Sshin * 18155009Sshin * PARAMETERS: Type - Type of node to be searched for 18255009Sshin * ParentNode - Parent node whose children we are 18355009Sshin * getting 18455009Sshin * ChildNode - Previous child that was found. 18555009Sshin * The NEXT child will be returned 18655009Sshin * 18755009Sshin * RETURN: ACPI_NAMESPACE_NODE - Pointer to the NEXT child or NULL if 18855009Sshin * none is found. 189184295Sbz * 19055009Sshin * DESCRIPTION: Return the next peer node within the namespace. If Handle 19155009Sshin * is valid, Scope is ignored. Otherwise, the first node 19255009Sshin * within Scope is returned. 193169454Srwatson * 19455009Sshin ******************************************************************************/ 19555009Sshin 19655009SshinACPI_NAMESPACE_NODE * 19755009SshinAcpiNsGetNextNodeTyped ( 19855009Sshin ACPI_OBJECT_TYPE Type, 19955009Sshin ACPI_NAMESPACE_NODE *ParentNode, 20055009Sshin ACPI_NAMESPACE_NODE *ChildNode) 20155009Sshin{ 20255009Sshin ACPI_NAMESPACE_NODE *NextNode = NULL; 20355009Sshin 20455009Sshin 20555009Sshin ACPI_FUNCTION_ENTRY (); 2061541Srgrimes 2071541Srgrimes 208191443Srwatson NextNode = AcpiNsGetNextNode (ParentNode, ChildNode); 209191443Srwatson 2101541Srgrimes /* If any type is OK, we are done */ 2111541Srgrimes 2121549Srgrimes if (Type == ACPI_TYPE_ANY) 213169454Srwatson { 214169454Srwatson /* NextNode is NULL if we are at the end-of-list */ 2151541Srgrimes 2161541Srgrimes return (NextNode); 217184295Sbz } 2181541Srgrimes 219168032Sbms /* Must search for the node -- but within this scope only */ 22084102Sjlemon 221189592Sbms while (NextNode) 2221541Srgrimes { 2231541Srgrimes /* If type matches, we are done */ 224194951Srwatson 225168032Sbms if (NextNode->Type == Type) 2261541Srgrimes { 227184295Sbz return (NextNode); 228168032Sbms } 22987124Sbrian 230168032Sbms /* Otherwise, move on to the next node */ 23187124Sbrian 232191443Srwatson NextNode = AcpiNsGetNextValidNode (NextNode); 233191443Srwatson } 234191443Srwatson 235191443Srwatson /* Not found */ 23655009Sshin 237191443Srwatson return (NULL); 238191443Srwatson} 239191443Srwatson 240191443Srwatson 241227791Sglebius/******************************************************************************* 242227791Sglebius * 243227791Sglebius * FUNCTION: AcpiNsWalkNamespace 244227791Sglebius * 245227791Sglebius * PARAMETERS: Type - ACPI_OBJECT_TYPE to search for 246227791Sglebius * StartNode - Handle in namespace where search begins 247227791Sglebius * MaxDepth - Depth to which search is to reach 248227791Sglebius * Flags - Whether to unlock the NS before invoking 249227791Sglebius * the callback routine 250227791Sglebius * UserFunction - Called when an object of "Type" is found 251227791Sglebius * Context - Passed to user function 252227831Sglebius * ReturnValue - from the UserFunction if terminated early. 253227831Sglebius * Otherwise, returns NULL. 254227791Sglebius * RETURNS: Status 255227791Sglebius * 256227791Sglebius * DESCRIPTION: Performs a modified depth-first walk of the namespace tree, 257227791Sglebius * starting (and ending) at the node specified by StartHandle. 258227791Sglebius * The UserFunction is called whenever a node that matches 259227791Sglebius * the type parameter is found. If the user function returns 260227791Sglebius * a non-zero value, the search is terminated immediately and 261227791Sglebius * this value is returned to the caller. 262227791Sglebius * 263227791Sglebius * The point of this procedure is to provide a generic namespace 264227791Sglebius * walk routine that can be called from multiple places to 265227791Sglebius * provide multiple services; the User Function can be tailored 266227791Sglebius * to each task, whether it is a print function, a compare 267191443Srwatson * function, etc. 268191443Srwatson * 269191443Srwatson ******************************************************************************/ 270191443Srwatson 271227791SglebiusACPI_STATUS 272227791SglebiusAcpiNsWalkNamespace ( 273227791Sglebius ACPI_OBJECT_TYPE Type, 274191443Srwatson ACPI_HANDLE StartNode, 275191443Srwatson UINT32 MaxDepth, 27655009Sshin UINT32 Flags, 277164033Srwatson ACPI_WALK_CALLBACK UserFunction, 278164033Srwatson void *Context, 279164033Srwatson void **ReturnValue) 280164033Srwatson{ 281164033Srwatson ACPI_STATUS Status; 282184295Sbz ACPI_STATUS MutexStatus; 283184295Sbz ACPI_NAMESPACE_NODE *ChildNode; 284164033Srwatson ACPI_NAMESPACE_NODE *ParentNode; 285164033Srwatson ACPI_OBJECT_TYPE ChildType; 28655009Sshin UINT32 Level; 287164033Srwatson 288164033Srwatson 289164033Srwatson ACPI_FUNCTION_TRACE (NsWalkNamespace); 290164033Srwatson 291164033Srwatson 292184295Sbz /* Special case for the namespace Root Node */ 293184295Sbz 294164033Srwatson if (StartNode == ACPI_ROOT_OBJECT) 295164033Srwatson { 29655009Sshin StartNode = AcpiGbl_RootNode; 297184295Sbz } 298184295Sbz 29983366Sjulian /* Null child means "get first node" */ 300191443Srwatson 301191443Srwatson ParentNode = StartNode; 302191443Srwatson ChildNode = NULL; 303191443Srwatson ChildType = ACPI_TYPE_ANY; 304191443Srwatson Level = 1; 30555009Sshin 30655009Sshin /* 307191443Srwatson * Traverse the tree of nodes until we bubble back up to where we 308191443Srwatson * started. When Level is zero, the loop is done because we have 309191443Srwatson * bubbled up to (and passed) the original parent handle (StartEntry) 3101541Srgrimes */ 311191456Srwatson while (Level > 0) 312191456Srwatson { 313191456Srwatson /* Get the next node in this scope. Null if not found */ 314191456Srwatson 315191456Srwatson Status = AE_OK; 316191456Srwatson ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); 317191456Srwatson if (ChildNode) 318191456Srwatson { 319191456Srwatson /* Found next child, get the type if we are not searching for ANY */ 320191456Srwatson 321191456Srwatson if (Type != ACPI_TYPE_ANY) 322191456Srwatson { 323191456Srwatson ChildType = ChildNode->Type; 324191456Srwatson } 325191456Srwatson 326191456Srwatson /* 327191456Srwatson * Ignore all temporary namespace nodes (created during control 328191456Srwatson * method execution) unless told otherwise. These temporary nodes 329191456Srwatson * can cause a race condition because they can be deleted during 330191456Srwatson * the execution of the user function (if the namespace is 331191456Srwatson * unlocked before invocation of the user function.) Only the 332191456Srwatson * debugger namespace dump will examine the temporary nodes. 333191456Srwatson */ 334191456Srwatson if ((ChildNode->Flags & ANOBJ_TEMPORARY) && 335191456Srwatson !(Flags & ACPI_NS_WALK_TEMP_NODES)) 3361541Srgrimes { 33714632Sfenner Status = AE_CTRL_DEPTH; 338191443Srwatson } 339191443Srwatson 3401541Srgrimes /* Type must match requested type */ 341191443Srwatson 342194951Srwatson else if (ChildType == Type) 343191443Srwatson { 344191443Srwatson /* 345191443Srwatson * Found a matching node, invoke the user callback function. 346191443Srwatson * Unlock the namespace if flag is set. 347191443Srwatson */ 348191443Srwatson if (Flags & ACPI_NS_WALK_UNLOCK) 349191443Srwatson { 350191443Srwatson MutexStatus = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 351191443Srwatson if (ACPI_FAILURE (MutexStatus)) 352194760Srwatson { 353194760Srwatson return_ACPI_STATUS (MutexStatus); 354194951Srwatson } 355191443Srwatson } 356194760Srwatson 357191443Srwatson Status = UserFunction (ChildNode, Level, Context, ReturnValue); 358191443Srwatson 359191443Srwatson if (Flags & ACPI_NS_WALK_UNLOCK) 360191443Srwatson { 361191443Srwatson MutexStatus = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 362191443Srwatson if (ACPI_FAILURE (MutexStatus)) 363191443Srwatson { 364191443Srwatson return_ACPI_STATUS (MutexStatus); 36584102Sjlemon } 36684102Sjlemon } 367191443Srwatson 368194760Srwatson switch (Status) 369194760Srwatson { 370194760Srwatson case AE_OK: 37184102Sjlemon case AE_CTRL_DEPTH: 372191443Srwatson 373191443Srwatson /* Just keep going */ 3741541Srgrimes break; 375191500Srwatson 3761541Srgrimes case AE_CTRL_TERMINATE: 3771541Srgrimes 3781541Srgrimes /* Exit now, with OK status */ 379227958Sglebius 380194760Srwatson return_ACPI_STATUS (AE_OK); 381194760Srwatson 382194951Srwatson default: 38371999Sphk 3848071Swollman /* All others are valid exceptions */ 3858071Swollman 3868071Swollman return_ACPI_STATUS (Status); 3878071Swollman } 3888071Swollman } 389194760Srwatson 390194760Srwatson /* 391194760Srwatson * Depth first search: Attempt to go down another level in the 392194760Srwatson * namespace if we are allowed to. Don't go any further if we have 393194951Srwatson * reached the caller specified maximum depth or if the user 3948876Srgrimes * function has specified that the maximum depth has been reached. 3958071Swollman */ 3968071Swollman if ((Level < MaxDepth) && (Status != AE_CTRL_DEPTH)) 3978071Swollman { 398191500Srwatson if (ChildNode->Child) 399194760Srwatson { 4008071Swollman /* There is at least one child of this node, visit it */ 4011541Srgrimes 402191500Srwatson Level++; 403191500Srwatson ParentNode = ChildNode; 404194760Srwatson ChildNode = NULL; 405191500Srwatson } 4061541Srgrimes } 4071541Srgrimes } 4081541Srgrimes else 4091541Srgrimes { 410184295Sbz /* 41120407Swollman * No more children of this node (AcpiNsGetNextNode failed), go 412191500Srwatson * back upwards in the namespace tree to the node's parent. 413191500Srwatson */ 414191500Srwatson Level--; 415191500Srwatson ChildNode = ParentNode; 416194760Srwatson ParentNode = AcpiNsGetParentNode (ParentNode); 417191500Srwatson } 418191500Srwatson } 41920407Swollman 420194602Srwatson /* Complete walk, not terminated by user function */ 42120407Swollman 42220407Swollman return_ACPI_STATUS (AE_OK); 42320407Swollman} 424108033Shsu 4251541Srgrimes 42685740Sdes