nsalloc.c revision 151937
1198090Srdivacky/******************************************************************************* 2198090Srdivacky * 3198090Srdivacky * Module Name: nsalloc - Namespace allocation and deletion utilities 4198090Srdivacky * $Revision: 1.97 $ 5198090Srdivacky * 6198090Srdivacky ******************************************************************************/ 7198090Srdivacky 8198090Srdivacky/****************************************************************************** 9198090Srdivacky * 10198090Srdivacky * 1. Copyright Notice 11198090Srdivacky * 12198090Srdivacky * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp. 13198090Srdivacky * All rights reserved. 14198090Srdivacky * 15198090Srdivacky * 2. License 16198090Srdivacky * 17198090Srdivacky * 2.1. This is your license from Intel Corp. under its intellectual property 18198090Srdivacky * rights. You may have additional license terms from the party that provided 19198090Srdivacky * you this software, covering your right to use that party's intellectual 20198090Srdivacky * property rights. 21198090Srdivacky * 22198090Srdivacky * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23198090Srdivacky * copy of the source code appearing in this file ("Covered Code") an 24198090Srdivacky * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25198090Srdivacky * base code distributed originally by Intel ("Original Intel Code") to copy, 26198090Srdivacky * make derivatives, distribute, use and display any portion of the Covered 27198090Srdivacky * Code in any form, with the right to sublicense such rights; and 28198090Srdivacky * 29198090Srdivacky * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30198090Srdivacky * license (with the right to sublicense), under only those claims of Intel 31198090Srdivacky * patents that are infringed by the Original Intel Code, to make, use, sell, 32198090Srdivacky * offer to sell, and import the Covered Code and derivative works thereof 33198090Srdivacky * solely to the minimum extent necessary to exercise the above copyright 34198090Srdivacky * license, and in no event shall the patent license extend to any additions 35198090Srdivacky * to or modifications of the Original Intel Code. No other license or right 36198090Srdivacky * is granted directly or by implication, estoppel or otherwise; 37198090Srdivacky * 38198090Srdivacky * The above copyright and patent license is granted only if the following 39198090Srdivacky * conditions are met: 40198090Srdivacky * 41198090Srdivacky * 3. Conditions 42198090Srdivacky * 43198090Srdivacky * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44198090Srdivacky * Redistribution of source code of any substantial portion of the Covered 45198090Srdivacky * Code or modification with rights to further distribute source must include 46198090Srdivacky * the above Copyright Notice, the above License, this list of Conditions, 47198090Srdivacky * and the following Disclaimer and Export Compliance provision. In addition, 48198090Srdivacky * Licensee must cause all Covered Code to which Licensee contributes to 49198090Srdivacky * contain a file documenting the changes Licensee made to create that Covered 50198090Srdivacky * Code and the date of any change. Licensee must include in that file the 51198090Srdivacky * documentation of any changes made by any predecessor Licensee. Licensee 52198090Srdivacky * must include a prominent statement that the modification is derived, 53198090Srdivacky * directly or indirectly, from Original Intel Code. 54198090Srdivacky * 55198090Srdivacky * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56198090Srdivacky * Redistribution of source code of any substantial portion of the Covered 57198090Srdivacky * Code or modification without rights to further distribute source must 58198090Srdivacky * include the following Disclaimer and Export Compliance provision in the 59198090Srdivacky * documentation and/or other materials provided with distribution. In 60198090Srdivacky * addition, Licensee may not authorize further sublicense of source of any 61198090Srdivacky * portion of the Covered Code, and must include terms to the effect that the 62198090Srdivacky * license from Licensee to its licensee is limited to the intellectual 63198090Srdivacky * property embodied in the software Licensee provides to its licensee, and 64198090Srdivacky * not to intellectual property embodied in modifications its licensee may 65198090Srdivacky * make. 66198090Srdivacky * 67198090Srdivacky * 3.3. Redistribution of Executable. Redistribution in executable form of any 68198090Srdivacky * substantial portion of the Covered Code or modification must reproduce the 69198090Srdivacky * above Copyright Notice, and the following Disclaimer and Export Compliance 70198090Srdivacky * provision in the documentation and/or other materials provided with the 71198090Srdivacky * distribution. 72198090Srdivacky * 73198090Srdivacky * 3.4. Intel retains all right, title, and interest in and to the Original 74198090Srdivacky * Intel Code. 75198090Srdivacky * 76198090Srdivacky * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77198090Srdivacky * Intel shall be used in advertising or otherwise to promote the sale, use or 78198090Srdivacky * other dealings in products derived from or relating to the Covered Code 79198090Srdivacky * without prior written authorization from Intel. 80198090Srdivacky * 81198090Srdivacky * 4. Disclaimer and Export Compliance 82198090Srdivacky * 83198090Srdivacky * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84198090Srdivacky * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85198090Srdivacky * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86198090Srdivacky * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87198090Srdivacky * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88198090Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89198090Srdivacky * PARTICULAR PURPOSE. 90198090Srdivacky * 91198090Srdivacky * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92198090Srdivacky * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93198090Srdivacky * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94198090Srdivacky * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95198090Srdivacky * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96198090Srdivacky * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97198090Srdivacky * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98198090Srdivacky * LIMITED REMEDY. 99198090Srdivacky * 100198090Srdivacky * 4.3. Licensee shall not export, either directly or indirectly, any of this 101198090Srdivacky * software or system incorporating such software without first obtaining any 102198090Srdivacky * required license or other approval from the U. S. Department of Commerce or 103198090Srdivacky * any other agency or department of the United States Government. In the 104198090Srdivacky * event Licensee exports any such software from the United States or 105198090Srdivacky * re-exports any such software from a foreign destination, Licensee shall 106198090Srdivacky * ensure that the distribution and export/re-export of the software is in 107198090Srdivacky * compliance with all laws, regulations, orders, or other restrictions of the 108198090Srdivacky * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109198090Srdivacky * any of its subsidiaries will export/re-export any technical data, process, 110198090Srdivacky * software, or service, directly or indirectly, to any country for which the 111198090Srdivacky * United States government or any agency thereof requires an export license, 112198090Srdivacky * other governmental approval, or letter of assurance, without first obtaining 113198090Srdivacky * such license, approval or letter. 114198090Srdivacky * 115198090Srdivacky *****************************************************************************/ 116198090Srdivacky 117198090Srdivacky 118198090Srdivacky#define __NSALLOC_C__ 119198090Srdivacky 120198090Srdivacky#include <contrib/dev/acpica/acpi.h> 121198090Srdivacky#include <contrib/dev/acpica/acnamesp.h> 122198090Srdivacky 123198090Srdivacky 124198090Srdivacky#define _COMPONENT ACPI_NAMESPACE 125198090Srdivacky ACPI_MODULE_NAME ("nsalloc") 126198090Srdivacky 127198090Srdivacky/* Local prototypes */ 128198090Srdivacky 129198090Srdivackystatic void 130198090SrdivackyAcpiNsRemoveReference ( 131198090Srdivacky ACPI_NAMESPACE_NODE *Node); 132198090Srdivacky 133198090Srdivacky 134198090Srdivacky/******************************************************************************* 135198090Srdivacky * 136198090Srdivacky * FUNCTION: AcpiNsCreateNode 137198090Srdivacky * 138198090Srdivacky * PARAMETERS: Name - Name of the new node (4 char ACPI name) 139198090Srdivacky * 140198090Srdivacky * RETURN: New namespace node (Null on failure) 141198090Srdivacky * 142198090Srdivacky * DESCRIPTION: Create a namespace node 143198090Srdivacky * 144198090Srdivacky ******************************************************************************/ 145198090Srdivacky 146198090SrdivackyACPI_NAMESPACE_NODE * 147198090SrdivackyAcpiNsCreateNode ( 148198090Srdivacky UINT32 Name) 149198090Srdivacky{ 150198090Srdivacky ACPI_NAMESPACE_NODE *Node; 151198090Srdivacky 152198090Srdivacky 153198090Srdivacky ACPI_FUNCTION_TRACE ("NsCreateNode"); 154198090Srdivacky 155198090Srdivacky 156198090Srdivacky Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); 157198090Srdivacky if (!Node) 158198090Srdivacky { 159198090Srdivacky return_PTR (NULL); 160198090Srdivacky } 161198090Srdivacky 162198090Srdivacky ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalAllocated++); 163198090Srdivacky 164198090Srdivacky Node->Name.Integer = Name; 165198090Srdivacky Node->ReferenceCount = 1; 166198090Srdivacky ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 167198090Srdivacky 168198090Srdivacky return_PTR (Node); 169198090Srdivacky} 170198090Srdivacky 171198090Srdivacky 172198090Srdivacky/******************************************************************************* 173198090Srdivacky * 174198090Srdivacky * FUNCTION: AcpiNsDeleteNode 175198090Srdivacky * 176198090Srdivacky * PARAMETERS: Node - Node to be deleted 177198090Srdivacky * 178198090Srdivacky * RETURN: None 179198090Srdivacky * 180198090Srdivacky * DESCRIPTION: Delete a namespace node 181198090Srdivacky * 182198090Srdivacky ******************************************************************************/ 183198090Srdivacky 184198090Srdivackyvoid 185198090SrdivackyAcpiNsDeleteNode ( 186198090Srdivacky ACPI_NAMESPACE_NODE *Node) 187198090Srdivacky{ 188198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode; 189198090Srdivacky ACPI_NAMESPACE_NODE *PrevNode; 190198090Srdivacky ACPI_NAMESPACE_NODE *NextNode; 191198090Srdivacky 192198090Srdivacky 193198090Srdivacky ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node); 194198090Srdivacky 195198090Srdivacky 196198090Srdivacky ParentNode = AcpiNsGetParentNode (Node); 197198090Srdivacky 198198090Srdivacky PrevNode = NULL; 199198090Srdivacky NextNode = ParentNode->Child; 200198090Srdivacky 201198090Srdivacky /* Find the node that is the previous peer in the parent's child list */ 202198090Srdivacky 203198090Srdivacky while (NextNode != Node) 204198090Srdivacky { 205198090Srdivacky PrevNode = NextNode; 206198090Srdivacky NextNode = PrevNode->Peer; 207198090Srdivacky } 208198090Srdivacky 209198090Srdivacky if (PrevNode) 210198090Srdivacky { 211198090Srdivacky /* Node is not first child, unlink it */ 212198090Srdivacky 213198090Srdivacky PrevNode->Peer = NextNode->Peer; 214198090Srdivacky if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 215198090Srdivacky { 216198090Srdivacky PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 217198090Srdivacky } 218198090Srdivacky } 219198090Srdivacky else 220198090Srdivacky { 221198090Srdivacky /* Node is first child (has no previous peer) */ 222198090Srdivacky 223198090Srdivacky if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 224198090Srdivacky { 225198090Srdivacky /* No peers at all */ 226198090Srdivacky 227198090Srdivacky ParentNode->Child = NULL; 228198090Srdivacky } 229198090Srdivacky else 230198090Srdivacky { /* Link peer list to parent */ 231198090Srdivacky 232198090Srdivacky ParentNode->Child = NextNode->Peer; 233198090Srdivacky } 234198090Srdivacky } 235198090Srdivacky 236198090Srdivacky ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 237198090Srdivacky 238198090Srdivacky /* 239198090Srdivacky * Detach an object if there is one then delete the node 240198090Srdivacky */ 241198090Srdivacky AcpiNsDetachObject (Node); 242198090Srdivacky ACPI_MEM_FREE (Node); 243198090Srdivacky return_VOID; 244198090Srdivacky} 245198090Srdivacky 246198090Srdivacky 247198090Srdivacky/******************************************************************************* 248198090Srdivacky * 249198090Srdivacky * FUNCTION: AcpiNsInstallNode 250198090Srdivacky * 251198090Srdivacky * PARAMETERS: WalkState - Current state of the walk 252198090Srdivacky * ParentNode - The parent of the new Node 253198090Srdivacky * Node - The new Node to install 254198090Srdivacky * Type - ACPI object type of the new Node 255198090Srdivacky * 256198090Srdivacky * RETURN: None 257198090Srdivacky * 258198090Srdivacky * DESCRIPTION: Initialize a new namespace node and install it amongst 259198090Srdivacky * its peers. 260198090Srdivacky * 261198090Srdivacky * Note: Current namespace lookup is linear search. This appears 262198090Srdivacky * to be sufficient as namespace searches consume only a small 263198090Srdivacky * fraction of the execution time of the ACPI subsystem. 264198090Srdivacky * 265198090Srdivacky ******************************************************************************/ 266198090Srdivacky 267198090Srdivackyvoid 268198090SrdivackyAcpiNsInstallNode ( 269198090Srdivacky ACPI_WALK_STATE *WalkState, 270198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 271198090Srdivacky ACPI_NAMESPACE_NODE *Node, /* New Child*/ 272198090Srdivacky ACPI_OBJECT_TYPE Type) 273198090Srdivacky{ 274198090Srdivacky ACPI_OWNER_ID OwnerId = 0; 275198090Srdivacky ACPI_NAMESPACE_NODE *ChildNode; 276198090Srdivacky 277198090Srdivacky 278198090Srdivacky ACPI_FUNCTION_TRACE ("NsInstallNode"); 279198090Srdivacky 280198090Srdivacky 281198090Srdivacky /* 282198090Srdivacky * Get the owner ID from the Walk state 283198090Srdivacky * The owner ID is used to track table deletion and 284198090Srdivacky * deletion of objects created by methods 285198090Srdivacky */ 286198090Srdivacky if (WalkState) 287198090Srdivacky { 288198090Srdivacky OwnerId = WalkState->OwnerId; 289198090Srdivacky } 290198090Srdivacky 291198090Srdivacky /* Link the new entry into the parent and existing children */ 292198090Srdivacky 293198090Srdivacky ChildNode = ParentNode->Child; 294198090Srdivacky if (!ChildNode) 295198090Srdivacky { 296198090Srdivacky ParentNode->Child = Node; 297198090Srdivacky Node->Flags |= ANOBJ_END_OF_PEER_LIST; 298198090Srdivacky Node->Peer = ParentNode; 299198090Srdivacky } 300198090Srdivacky else 301198090Srdivacky { 302198090Srdivacky while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 303198090Srdivacky { 304198090Srdivacky ChildNode = ChildNode->Peer; 305198090Srdivacky } 306252723Sdim 307198090Srdivacky ChildNode->Peer = Node; 308198090Srdivacky 309198090Srdivacky /* Clear end-of-list flag */ 310198090Srdivacky 311198090Srdivacky ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 312198090Srdivacky Node->Flags |= ANOBJ_END_OF_PEER_LIST; 313198090Srdivacky Node->Peer = ParentNode; 314198090Srdivacky } 315198090Srdivacky 316198090Srdivacky /* Init the new entry */ 317198090Srdivacky 318198090Srdivacky Node->OwnerId = OwnerId; 319198090Srdivacky Node->Type = (UINT8) Type; 320198090Srdivacky 321198090Srdivacky ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 322198090Srdivacky "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 323198090Srdivacky AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, 324198090Srdivacky AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), 325198090Srdivacky ParentNode)); 326198090Srdivacky 327198090Srdivacky /* 328198090Srdivacky * Increment the reference count(s) of all parents up to 329198090Srdivacky * the root! 330198090Srdivacky */ 331198090Srdivacky while ((Node = AcpiNsGetParentNode (Node)) != NULL) 332198090Srdivacky { 333198090Srdivacky Node->ReferenceCount++; 334198090Srdivacky } 335198090Srdivacky 336198090Srdivacky return_VOID; 337198090Srdivacky} 338198090Srdivacky 339198090Srdivacky 340198090Srdivacky/******************************************************************************* 341198090Srdivacky * 342198090Srdivacky * FUNCTION: AcpiNsDeleteChildren 343198090Srdivacky * 344198090Srdivacky * PARAMETERS: ParentNode - Delete this objects children 345198090Srdivacky * 346198090Srdivacky * RETURN: None. 347198090Srdivacky * 348198090Srdivacky * DESCRIPTION: Delete all children of the parent object. In other words, 349198090Srdivacky * deletes a "scope". 350198090Srdivacky * 351198090Srdivacky ******************************************************************************/ 352198090Srdivacky 353198090Srdivackyvoid 354198090SrdivackyAcpiNsDeleteChildren ( 355198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode) 356198090Srdivacky{ 357198090Srdivacky ACPI_NAMESPACE_NODE *ChildNode; 358198090Srdivacky ACPI_NAMESPACE_NODE *NextNode; 359198090Srdivacky ACPI_NAMESPACE_NODE *Node; 360198090Srdivacky UINT8 Flags; 361198090Srdivacky 362198090Srdivacky 363198090Srdivacky ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode); 364198090Srdivacky 365198090Srdivacky 366198090Srdivacky if (!ParentNode) 367198090Srdivacky { 368198090Srdivacky return_VOID; 369198090Srdivacky } 370198090Srdivacky 371198090Srdivacky /* If no children, all done! */ 372198090Srdivacky 373198090Srdivacky ChildNode = ParentNode->Child; 374252723Sdim if (!ChildNode) 375252723Sdim { 376252723Sdim return_VOID; 377252723Sdim } 378252723Sdim 379252723Sdim /* 380252723Sdim * Deallocate all children at this level 381252723Sdim */ 382252723Sdim do 383252723Sdim { 384252723Sdim /* Get the things we need */ 385252723Sdim 386252723Sdim NextNode = ChildNode->Peer; 387252723Sdim Flags = ChildNode->Flags; 388252723Sdim 389252723Sdim /* Grandchildren should have all been deleted already */ 390252723Sdim 391252723Sdim if (ChildNode->Child) 392252723Sdim { 393252723Sdim ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 394252723Sdim ParentNode, ChildNode)); 395252723Sdim } 396252723Sdim 397252723Sdim /* Now we can free this child object */ 398252723Sdim 399252723Sdim ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 400252723Sdim 401252723Sdim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 402198090Srdivacky ChildNode, AcpiGbl_CurrentNodeCount)); 403198090Srdivacky 404198090Srdivacky /* 405198090Srdivacky * Detach an object if there is one, then free the child node 406198090Srdivacky */ 407198090Srdivacky AcpiNsDetachObject (ChildNode); 408198090Srdivacky 409198090Srdivacky /* 410198090Srdivacky * Decrement the reference count(s) of all parents up to 411198090Srdivacky * the root! (counts were incremented when the node was created) 412198090Srdivacky */ 413198090Srdivacky Node = ChildNode; 414198090Srdivacky while ((Node = AcpiNsGetParentNode (Node)) != NULL) 415198090Srdivacky { 416198090Srdivacky Node->ReferenceCount--; 417198090Srdivacky } 418198090Srdivacky 419198090Srdivacky /* There should be only one reference remaining on this node */ 420198090Srdivacky 421198090Srdivacky if (ChildNode->ReferenceCount != 1) 422198090Srdivacky { 423198090Srdivacky ACPI_REPORT_WARNING (( 424198090Srdivacky "Existing references (%d) on node being deleted (%p)\n", 425198090Srdivacky ChildNode->ReferenceCount, ChildNode)); 426198090Srdivacky } 427198090Srdivacky 428198090Srdivacky /* Now we can delete the node */ 429198090Srdivacky 430198090Srdivacky ACPI_MEM_FREE (ChildNode); 431198090Srdivacky 432198090Srdivacky /* And move on to the next child in the list */ 433198090Srdivacky 434198090Srdivacky ChildNode = NextNode; 435198090Srdivacky 436198090Srdivacky } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 437198090Srdivacky 438198090Srdivacky 439198090Srdivacky /* Clear the parent's child pointer */ 440198090Srdivacky 441198090Srdivacky ParentNode->Child = NULL; 442198090Srdivacky 443198090Srdivacky return_VOID; 444198090Srdivacky} 445198090Srdivacky 446198090Srdivacky 447198090Srdivacky/******************************************************************************* 448198090Srdivacky * 449198090Srdivacky * FUNCTION: AcpiNsDeleteNamespaceSubtree 450198090Srdivacky * 451198090Srdivacky * PARAMETERS: ParentNode - Root of the subtree to be deleted 452198090Srdivacky * 453198090Srdivacky * RETURN: None. 454198090Srdivacky * 455198090Srdivacky * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 456198090Srdivacky * stored within the subtree. 457198090Srdivacky * 458198090Srdivacky ******************************************************************************/ 459198090Srdivacky 460198090Srdivackyvoid 461198090SrdivackyAcpiNsDeleteNamespaceSubtree ( 462198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode) 463198090Srdivacky{ 464198090Srdivacky ACPI_NAMESPACE_NODE *ChildNode = NULL; 465198090Srdivacky UINT32 Level = 1; 466198090Srdivacky 467198090Srdivacky 468198090Srdivacky ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree"); 469198090Srdivacky 470198090Srdivacky 471198090Srdivacky if (!ParentNode) 472198090Srdivacky { 473198090Srdivacky return_VOID; 474198090Srdivacky } 475198090Srdivacky 476198090Srdivacky /* 477198090Srdivacky * Traverse the tree of objects until we bubble back up 478198090Srdivacky * to where we started. 479198090Srdivacky */ 480198090Srdivacky while (Level > 0) 481198090Srdivacky { 482198090Srdivacky /* Get the next node in this scope (NULL if none) */ 483198090Srdivacky 484198090Srdivacky ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, 485198090Srdivacky ChildNode); 486198090Srdivacky if (ChildNode) 487198090Srdivacky { 488198090Srdivacky /* Found a child node - detach any attached object */ 489198090Srdivacky 490198090Srdivacky AcpiNsDetachObject (ChildNode); 491198090Srdivacky 492198090Srdivacky /* Check if this node has any children */ 493198090Srdivacky 494198090Srdivacky if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 495198090Srdivacky { 496198090Srdivacky /* 497198090Srdivacky * There is at least one child of this node, 498198090Srdivacky * visit the node 499198090Srdivacky */ 500198090Srdivacky Level++; 501198090Srdivacky ParentNode = ChildNode; 502198090Srdivacky ChildNode = NULL; 503198090Srdivacky } 504198090Srdivacky } 505198090Srdivacky else 506198090Srdivacky { 507198090Srdivacky /* 508198090Srdivacky * No more children of this parent node. 509198090Srdivacky * Move up to the grandparent. 510198090Srdivacky */ 511198090Srdivacky Level--; 512198090Srdivacky 513198090Srdivacky /* 514198090Srdivacky * Now delete all of the children of this parent 515198090Srdivacky * all at the same time. 516198090Srdivacky */ 517198090Srdivacky AcpiNsDeleteChildren (ParentNode); 518198090Srdivacky 519198090Srdivacky /* New "last child" is this parent node */ 520198090Srdivacky 521198090Srdivacky ChildNode = ParentNode; 522198090Srdivacky 523198090Srdivacky /* Move up the tree to the grandparent */ 524198090Srdivacky 525198090Srdivacky ParentNode = AcpiNsGetParentNode (ParentNode); 526198090Srdivacky } 527198090Srdivacky } 528198090Srdivacky 529198090Srdivacky return_VOID; 530198090Srdivacky} 531198090Srdivacky 532198090Srdivacky 533198090Srdivacky/******************************************************************************* 534198090Srdivacky * 535198090Srdivacky * FUNCTION: AcpiNsRemoveReference 536198090Srdivacky * 537198090Srdivacky * PARAMETERS: Node - Named node whose reference count is to be 538198090Srdivacky * decremented 539198090Srdivacky * 540198090Srdivacky * RETURN: None. 541198090Srdivacky * 542198090Srdivacky * DESCRIPTION: Remove a Node reference. Decrements the reference count 543198090Srdivacky * of all parent Nodes up to the root. Any node along 544198090Srdivacky * the way that reaches zero references is freed. 545198090Srdivacky * 546198090Srdivacky ******************************************************************************/ 547198090Srdivacky 548198090Srdivackystatic void 549198090SrdivackyAcpiNsRemoveReference ( 550198090Srdivacky ACPI_NAMESPACE_NODE *Node) 551198090Srdivacky{ 552198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode; 553198090Srdivacky ACPI_NAMESPACE_NODE *ThisNode; 554198090Srdivacky 555198090Srdivacky 556198090Srdivacky ACPI_FUNCTION_ENTRY (); 557198090Srdivacky 558198090Srdivacky 559198090Srdivacky /* 560198090Srdivacky * Decrement the reference count(s) of this node and all 561198090Srdivacky * nodes up to the root, Delete anything with zero remaining references. 562198090Srdivacky */ 563198090Srdivacky ThisNode = Node; 564198090Srdivacky while (ThisNode) 565198090Srdivacky { 566198090Srdivacky /* Prepare to move up to parent */ 567198090Srdivacky 568198090Srdivacky ParentNode = AcpiNsGetParentNode (ThisNode); 569198090Srdivacky 570198090Srdivacky /* Decrement the reference count on this node */ 571198090Srdivacky 572198090Srdivacky ThisNode->ReferenceCount--; 573198090Srdivacky 574198090Srdivacky /* Delete the node if no more references */ 575198090Srdivacky 576198090Srdivacky if (!ThisNode->ReferenceCount) 577198090Srdivacky { 578198090Srdivacky /* Delete all children and delete the node */ 579198090Srdivacky 580198090Srdivacky AcpiNsDeleteChildren (ThisNode); 581198090Srdivacky AcpiNsDeleteNode (ThisNode); 582198090Srdivacky } 583198090Srdivacky 584198090Srdivacky ThisNode = ParentNode; 585198090Srdivacky } 586198090Srdivacky} 587198090Srdivacky 588198090Srdivacky 589198090Srdivacky/******************************************************************************* 590198090Srdivacky * 591198090Srdivacky * FUNCTION: AcpiNsDeleteNamespaceByOwner 592198090Srdivacky * 593198090Srdivacky * PARAMETERS: OwnerId - All nodes with this owner will be deleted 594198090Srdivacky * 595198090Srdivacky * RETURN: Status 596198090Srdivacky * 597198090Srdivacky * DESCRIPTION: Delete entries within the namespace that are owned by a 598198090Srdivacky * specific ID. Used to delete entire ACPI tables. All 599198090Srdivacky * reference counts are updated. 600198090Srdivacky * 601198090Srdivacky ******************************************************************************/ 602198090Srdivacky 603198090Srdivackyvoid 604198090SrdivackyAcpiNsDeleteNamespaceByOwner ( 605198090Srdivacky ACPI_OWNER_ID OwnerId) 606198090Srdivacky{ 607198090Srdivacky ACPI_NAMESPACE_NODE *ChildNode; 608198090Srdivacky ACPI_NAMESPACE_NODE *DeletionNode; 609198090Srdivacky UINT32 Level; 610198090Srdivacky ACPI_NAMESPACE_NODE *ParentNode; 611198090Srdivacky 612198090Srdivacky 613198090Srdivacky ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId); 614198090Srdivacky 615198090Srdivacky 616198090Srdivacky if (OwnerId == 0) 617198090Srdivacky { 618198090Srdivacky return_VOID; 619198090Srdivacky } 620198090Srdivacky 621198090Srdivacky ParentNode = AcpiGbl_RootNode; 622198090Srdivacky ChildNode = NULL; 623198090Srdivacky DeletionNode = NULL; 624198090Srdivacky Level = 1; 625198090Srdivacky 626198090Srdivacky /* 627198090Srdivacky * Traverse the tree of nodes until we bubble back up 628198090Srdivacky * to where we started. 629198090Srdivacky */ 630198090Srdivacky while (Level > 0) 631198090Srdivacky { 632198090Srdivacky /* 633198090Srdivacky * Get the next child of this parent node. When ChildNode is NULL, 634198090Srdivacky * the first child of the parent is returned 635198090Srdivacky */ 636198090Srdivacky ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 637198090Srdivacky 638198090Srdivacky if (DeletionNode) 639198090Srdivacky { 640198090Srdivacky AcpiNsRemoveReference (DeletionNode); 641198090Srdivacky DeletionNode = NULL; 642198090Srdivacky } 643198090Srdivacky 644198090Srdivacky if (ChildNode) 645198090Srdivacky { 646198090Srdivacky if (ChildNode->OwnerId == OwnerId) 647198090Srdivacky { 648198090Srdivacky /* Found a matching child node - detach any attached object */ 649198090Srdivacky 650198090Srdivacky AcpiNsDetachObject (ChildNode); 651198090Srdivacky } 652198090Srdivacky 653198090Srdivacky /* Check if this node has any children */ 654198090Srdivacky 655198090Srdivacky if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 656198090Srdivacky { 657198090Srdivacky /* 658198090Srdivacky * There is at least one child of this node, 659198090Srdivacky * visit the node 660198090Srdivacky */ 661198090Srdivacky Level++; 662198090Srdivacky ParentNode = ChildNode; 663198090Srdivacky ChildNode = NULL; 664198090Srdivacky } 665198090Srdivacky else if (ChildNode->OwnerId == OwnerId) 666198090Srdivacky { 667198090Srdivacky DeletionNode = ChildNode; 668198090Srdivacky } 669198090Srdivacky } 670198090Srdivacky else 671198090Srdivacky { 672198090Srdivacky /* 673198090Srdivacky * No more children of this parent node. 674198090Srdivacky * Move up to the grandparent. 675198090Srdivacky */ 676198090Srdivacky Level--; 677198090Srdivacky if (Level != 0) 678198090Srdivacky { 679198090Srdivacky if (ParentNode->OwnerId == OwnerId) 680198090Srdivacky { 681198090Srdivacky DeletionNode = ParentNode; 682198090Srdivacky } 683198090Srdivacky } 684198090Srdivacky 685198090Srdivacky /* New "last child" is this parent node */ 686198090Srdivacky 687198090Srdivacky ChildNode = ParentNode; 688198090Srdivacky 689198090Srdivacky /* Move up the tree to the grandparent */ 690198090Srdivacky 691198090Srdivacky ParentNode = AcpiNsGetParentNode (ParentNode); 692198090Srdivacky } 693198090Srdivacky } 694198090Srdivacky 695198090Srdivacky return_VOID; 696198090Srdivacky} 697198090Srdivacky 698198090Srdivacky 699198090Srdivacky