13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: nsalloc - Namespace allocation and deletion utilities 4*7851SDana.Myers@Sun.COM * $Revision: 1.109 $ 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 __NSALLOC_C__ 1193446Smrj 1203446Smrj #include "acpi.h" 1213446Smrj #include "acnamesp.h" 1223446Smrj 1233446Smrj 1243446Smrj #define _COMPONENT ACPI_NAMESPACE 1253446Smrj ACPI_MODULE_NAME ("nsalloc") 1263446Smrj 1273446Smrj 1283446Smrj /******************************************************************************* 1293446Smrj * 1303446Smrj * FUNCTION: AcpiNsCreateNode 1313446Smrj * 1323446Smrj * PARAMETERS: Name - Name of the new node (4 char ACPI name) 1333446Smrj * 1343446Smrj * RETURN: New namespace node (Null on failure) 1353446Smrj * 1363446Smrj * DESCRIPTION: Create a namespace node 1373446Smrj * 1383446Smrj ******************************************************************************/ 1393446Smrj 1403446Smrj ACPI_NAMESPACE_NODE * 1413446Smrj AcpiNsCreateNode ( 1423446Smrj UINT32 Name) 1433446Smrj { 1443446Smrj ACPI_NAMESPACE_NODE *Node; 145*7851SDana.Myers@Sun.COM #ifdef ACPI_DBG_TRACK_ALLOCATIONS 146*7851SDana.Myers@Sun.COM UINT32 Temp; 147*7851SDana.Myers@Sun.COM #endif 1483446Smrj 1493446Smrj 1503446Smrj ACPI_FUNCTION_TRACE (NsCreateNode); 1513446Smrj 1523446Smrj 1533446Smrj Node = AcpiOsAcquireObject (AcpiGbl_NamespaceCache); 1543446Smrj if (!Node) 1553446Smrj { 1563446Smrj return_PTR (NULL); 1573446Smrj } 1583446Smrj 1593446Smrj ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalAllocated++); 1603446Smrj 161*7851SDana.Myers@Sun.COM #ifdef ACPI_DBG_TRACK_ALLOCATIONS 162*7851SDana.Myers@Sun.COM Temp = AcpiGbl_NsNodeList->TotalAllocated - AcpiGbl_NsNodeList->TotalFreed; 163*7851SDana.Myers@Sun.COM if (Temp > AcpiGbl_NsNodeList->MaxOccupied) 164*7851SDana.Myers@Sun.COM { 165*7851SDana.Myers@Sun.COM AcpiGbl_NsNodeList->MaxOccupied = Temp; 166*7851SDana.Myers@Sun.COM } 167*7851SDana.Myers@Sun.COM #endif 168*7851SDana.Myers@Sun.COM 1693446Smrj Node->Name.Integer = Name; 1703446Smrj ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 1713446Smrj return_PTR (Node); 1723446Smrj } 1733446Smrj 1743446Smrj 1753446Smrj /******************************************************************************* 1763446Smrj * 1773446Smrj * FUNCTION: AcpiNsDeleteNode 1783446Smrj * 1793446Smrj * PARAMETERS: Node - Node to be deleted 1803446Smrj * 1813446Smrj * RETURN: None 1823446Smrj * 1833446Smrj * DESCRIPTION: Delete a namespace node 1843446Smrj * 1853446Smrj ******************************************************************************/ 1863446Smrj 1873446Smrj void 1883446Smrj AcpiNsDeleteNode ( 1893446Smrj ACPI_NAMESPACE_NODE *Node) 1903446Smrj { 1913446Smrj ACPI_NAMESPACE_NODE *ParentNode; 1923446Smrj ACPI_NAMESPACE_NODE *PrevNode; 1933446Smrj ACPI_NAMESPACE_NODE *NextNode; 1943446Smrj 1953446Smrj 1963446Smrj ACPI_FUNCTION_TRACE_PTR (NsDeleteNode, Node); 1973446Smrj 1983446Smrj 1993446Smrj ParentNode = AcpiNsGetParentNode (Node); 2003446Smrj 2013446Smrj PrevNode = NULL; 2023446Smrj NextNode = ParentNode->Child; 2033446Smrj 2043446Smrj /* Find the node that is the previous peer in the parent's child list */ 2053446Smrj 2063446Smrj while (NextNode != Node) 2073446Smrj { 2083446Smrj PrevNode = NextNode; 2093446Smrj NextNode = PrevNode->Peer; 2103446Smrj } 2113446Smrj 2123446Smrj if (PrevNode) 2133446Smrj { 2143446Smrj /* Node is not first child, unlink it */ 2153446Smrj 2163446Smrj PrevNode->Peer = NextNode->Peer; 2173446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2183446Smrj { 2193446Smrj PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 2203446Smrj } 2213446Smrj } 2223446Smrj else 2233446Smrj { 2243446Smrj /* Node is first child (has no previous peer) */ 2253446Smrj 2263446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2273446Smrj { 2283446Smrj /* No peers at all */ 2293446Smrj 2303446Smrj ParentNode->Child = NULL; 2313446Smrj } 2323446Smrj else 2333446Smrj { /* Link peer list to parent */ 2343446Smrj 2353446Smrj ParentNode->Child = NextNode->Peer; 2363446Smrj } 2373446Smrj } 2383446Smrj 2393446Smrj ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 2403446Smrj 2413446Smrj /* 2423446Smrj * Detach an object if there is one, then delete the node 2433446Smrj */ 2443446Smrj AcpiNsDetachObject (Node); 2453446Smrj (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node); 2463446Smrj return_VOID; 2473446Smrj } 2483446Smrj 2493446Smrj 2503446Smrj /******************************************************************************* 2513446Smrj * 2523446Smrj * FUNCTION: AcpiNsInstallNode 2533446Smrj * 2543446Smrj * PARAMETERS: WalkState - Current state of the walk 2553446Smrj * ParentNode - The parent of the new Node 2563446Smrj * Node - The new Node to install 2573446Smrj * Type - ACPI object type of the new Node 2583446Smrj * 2593446Smrj * RETURN: None 2603446Smrj * 2613446Smrj * DESCRIPTION: Initialize a new namespace node and install it amongst 2623446Smrj * its peers. 2633446Smrj * 2643446Smrj * Note: Current namespace lookup is linear search. This appears 2653446Smrj * to be sufficient as namespace searches consume only a small 2663446Smrj * fraction of the execution time of the ACPI subsystem. 2673446Smrj * 2683446Smrj ******************************************************************************/ 2693446Smrj 2703446Smrj void 2713446Smrj AcpiNsInstallNode ( 2723446Smrj ACPI_WALK_STATE *WalkState, 2733446Smrj ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 2743446Smrj ACPI_NAMESPACE_NODE *Node, /* New Child*/ 2753446Smrj ACPI_OBJECT_TYPE Type) 2763446Smrj { 2773446Smrj ACPI_OWNER_ID OwnerId = 0; 2783446Smrj ACPI_NAMESPACE_NODE *ChildNode; 2793446Smrj 2803446Smrj 2813446Smrj ACPI_FUNCTION_TRACE (NsInstallNode); 2823446Smrj 2833446Smrj 2843446Smrj /* 2853446Smrj * Get the owner ID from the Walk state 2863446Smrj * The owner ID is used to track table deletion and 2873446Smrj * deletion of objects created by methods 2883446Smrj */ 2893446Smrj if (WalkState) 2903446Smrj { 2913446Smrj OwnerId = WalkState->OwnerId; 2923446Smrj } 2933446Smrj 2943446Smrj /* Link the new entry into the parent and existing children */ 2953446Smrj 2963446Smrj ChildNode = ParentNode->Child; 2973446Smrj if (!ChildNode) 2983446Smrj { 2993446Smrj ParentNode->Child = Node; 3003446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3013446Smrj Node->Peer = ParentNode; 3023446Smrj } 3033446Smrj else 3043446Smrj { 3053446Smrj while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 3063446Smrj { 3073446Smrj ChildNode = ChildNode->Peer; 3083446Smrj } 3093446Smrj 3103446Smrj ChildNode->Peer = Node; 3113446Smrj 3123446Smrj /* Clear end-of-list flag */ 3133446Smrj 3143446Smrj ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 3153446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3163446Smrj Node->Peer = ParentNode; 3173446Smrj } 3183446Smrj 3193446Smrj /* Init the new entry */ 3203446Smrj 3213446Smrj Node->OwnerId = OwnerId; 3223446Smrj Node->Type = (UINT8) Type; 3233446Smrj 3243446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 3253446Smrj "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 3263446Smrj AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, 3273446Smrj AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), 3283446Smrj ParentNode)); 3293446Smrj 3303446Smrj return_VOID; 3313446Smrj } 3323446Smrj 3333446Smrj 3343446Smrj /******************************************************************************* 3353446Smrj * 3363446Smrj * FUNCTION: AcpiNsDeleteChildren 3373446Smrj * 3383446Smrj * PARAMETERS: ParentNode - Delete this objects children 3393446Smrj * 3403446Smrj * RETURN: None. 3413446Smrj * 3423446Smrj * DESCRIPTION: Delete all children of the parent object. In other words, 3433446Smrj * deletes a "scope". 3443446Smrj * 3453446Smrj ******************************************************************************/ 3463446Smrj 3473446Smrj void 3483446Smrj AcpiNsDeleteChildren ( 3493446Smrj ACPI_NAMESPACE_NODE *ParentNode) 3503446Smrj { 3513446Smrj ACPI_NAMESPACE_NODE *ChildNode; 3523446Smrj ACPI_NAMESPACE_NODE *NextNode; 3533446Smrj UINT8 Flags; 3543446Smrj 3553446Smrj 3563446Smrj ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode); 3573446Smrj 3583446Smrj 3593446Smrj if (!ParentNode) 3603446Smrj { 3613446Smrj return_VOID; 3623446Smrj } 3633446Smrj 3643446Smrj /* If no children, all done! */ 3653446Smrj 3663446Smrj ChildNode = ParentNode->Child; 3673446Smrj if (!ChildNode) 3683446Smrj { 3693446Smrj return_VOID; 3703446Smrj } 3713446Smrj 3723446Smrj /* 3733446Smrj * Deallocate all children at this level 3743446Smrj */ 3753446Smrj do 3763446Smrj { 3773446Smrj /* Get the things we need */ 3783446Smrj 3793446Smrj NextNode = ChildNode->Peer; 3803446Smrj Flags = ChildNode->Flags; 3813446Smrj 3823446Smrj /* Grandchildren should have all been deleted already */ 3833446Smrj 3843446Smrj if (ChildNode->Child) 3853446Smrj { 3863446Smrj ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p", 3873446Smrj ParentNode, ChildNode)); 3883446Smrj } 3893446Smrj 3903446Smrj /* Now we can free this child object */ 3913446Smrj 3923446Smrj ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 3933446Smrj 3943446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 3953446Smrj ChildNode, AcpiGbl_CurrentNodeCount)); 3963446Smrj 3973446Smrj /* 3983446Smrj * Detach an object if there is one, then free the child node 3993446Smrj */ 4003446Smrj AcpiNsDetachObject (ChildNode); 4013446Smrj 4023446Smrj /* Now we can delete the node */ 4033446Smrj 4043446Smrj (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, ChildNode); 4053446Smrj 4063446Smrj /* And move on to the next child in the list */ 4073446Smrj 4083446Smrj ChildNode = NextNode; 4093446Smrj 4103446Smrj } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 4113446Smrj 4123446Smrj 4133446Smrj /* Clear the parent's child pointer */ 4143446Smrj 4153446Smrj ParentNode->Child = NULL; 4163446Smrj 4173446Smrj return_VOID; 4183446Smrj } 4193446Smrj 4203446Smrj 4213446Smrj /******************************************************************************* 4223446Smrj * 4233446Smrj * FUNCTION: AcpiNsDeleteNamespaceSubtree 4243446Smrj * 4253446Smrj * PARAMETERS: ParentNode - Root of the subtree to be deleted 4263446Smrj * 4273446Smrj * RETURN: None. 4283446Smrj * 4293446Smrj * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 4303446Smrj * stored within the subtree. 4313446Smrj * 4323446Smrj ******************************************************************************/ 4333446Smrj 4343446Smrj void 4353446Smrj AcpiNsDeleteNamespaceSubtree ( 4363446Smrj ACPI_NAMESPACE_NODE *ParentNode) 4373446Smrj { 4383446Smrj ACPI_NAMESPACE_NODE *ChildNode = NULL; 4393446Smrj UINT32 Level = 1; 4403446Smrj 4413446Smrj 4423446Smrj ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree); 4433446Smrj 4443446Smrj 4453446Smrj if (!ParentNode) 4463446Smrj { 4473446Smrj return_VOID; 4483446Smrj } 4493446Smrj 4503446Smrj /* 4513446Smrj * Traverse the tree of objects until we bubble back up 4523446Smrj * to where we started. 4533446Smrj */ 4543446Smrj while (Level > 0) 4553446Smrj { 4563446Smrj /* Get the next node in this scope (NULL if none) */ 4573446Smrj 4583446Smrj ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 4593446Smrj if (ChildNode) 4603446Smrj { 4613446Smrj /* Found a child node - detach any attached object */ 4623446Smrj 4633446Smrj AcpiNsDetachObject (ChildNode); 4643446Smrj 4653446Smrj /* Check if this node has any children */ 4663446Smrj 4673446Smrj if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 4683446Smrj { 4693446Smrj /* 4703446Smrj * There is at least one child of this node, 4713446Smrj * visit the node 4723446Smrj */ 4733446Smrj Level++; 4743446Smrj ParentNode = ChildNode; 4753446Smrj ChildNode = NULL; 4763446Smrj } 4773446Smrj } 4783446Smrj else 4793446Smrj { 4803446Smrj /* 4813446Smrj * No more children of this parent node. 4823446Smrj * Move up to the grandparent. 4833446Smrj */ 4843446Smrj Level--; 4853446Smrj 4863446Smrj /* 4873446Smrj * Now delete all of the children of this parent 4883446Smrj * all at the same time. 4893446Smrj */ 4903446Smrj AcpiNsDeleteChildren (ParentNode); 4913446Smrj 4923446Smrj /* New "last child" is this parent node */ 4933446Smrj 4943446Smrj ChildNode = ParentNode; 4953446Smrj 4963446Smrj /* Move up the tree to the grandparent */ 4973446Smrj 4983446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 4993446Smrj } 5003446Smrj } 5013446Smrj 5023446Smrj return_VOID; 5033446Smrj } 5043446Smrj 5053446Smrj 5063446Smrj /******************************************************************************* 5073446Smrj * 5083446Smrj * FUNCTION: AcpiNsDeleteNamespaceByOwner 5093446Smrj * 5103446Smrj * PARAMETERS: OwnerId - All nodes with this owner will be deleted 5113446Smrj * 5123446Smrj * RETURN: Status 5133446Smrj * 5143446Smrj * DESCRIPTION: Delete entries within the namespace that are owned by a 5153446Smrj * specific ID. Used to delete entire ACPI tables. All 5163446Smrj * reference counts are updated. 5173446Smrj * 5183446Smrj * MUTEX: Locks namespace during deletion walk. 5193446Smrj * 5203446Smrj ******************************************************************************/ 5213446Smrj 5223446Smrj void 5233446Smrj AcpiNsDeleteNamespaceByOwner ( 5243446Smrj ACPI_OWNER_ID OwnerId) 5253446Smrj { 5263446Smrj ACPI_NAMESPACE_NODE *ChildNode; 5273446Smrj ACPI_NAMESPACE_NODE *DeletionNode; 5283446Smrj ACPI_NAMESPACE_NODE *ParentNode; 5293446Smrj UINT32 Level; 5303446Smrj ACPI_STATUS Status; 5313446Smrj 5323446Smrj 5333446Smrj ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId); 5343446Smrj 5353446Smrj 5363446Smrj if (OwnerId == 0) 5373446Smrj { 5383446Smrj return_VOID; 5393446Smrj } 5403446Smrj 5413446Smrj /* Lock namespace for possible update */ 5423446Smrj 5433446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 5443446Smrj if (ACPI_FAILURE (Status)) 5453446Smrj { 5463446Smrj return_VOID; 5473446Smrj } 5483446Smrj 5493446Smrj DeletionNode = NULL; 5503446Smrj ParentNode = AcpiGbl_RootNode; 5513446Smrj ChildNode = NULL; 5523446Smrj Level = 1; 5533446Smrj 5543446Smrj /* 5553446Smrj * Traverse the tree of nodes until we bubble back up 5563446Smrj * to where we started. 5573446Smrj */ 5583446Smrj while (Level > 0) 5593446Smrj { 5603446Smrj /* 5613446Smrj * Get the next child of this parent node. When ChildNode is NULL, 5623446Smrj * the first child of the parent is returned 5633446Smrj */ 5643446Smrj ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 5653446Smrj 5663446Smrj if (DeletionNode) 5673446Smrj { 5683446Smrj AcpiNsDeleteChildren (DeletionNode); 5693446Smrj AcpiNsDeleteNode (DeletionNode); 5703446Smrj DeletionNode = NULL; 5713446Smrj } 5723446Smrj 5733446Smrj if (ChildNode) 5743446Smrj { 5753446Smrj if (ChildNode->OwnerId == OwnerId) 5763446Smrj { 5773446Smrj /* Found a matching child node - detach any attached object */ 5783446Smrj 5793446Smrj AcpiNsDetachObject (ChildNode); 5803446Smrj } 5813446Smrj 5823446Smrj /* Check if this node has any children */ 5833446Smrj 5843446Smrj if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 5853446Smrj { 5863446Smrj /* 5873446Smrj * There is at least one child of this node, 5883446Smrj * visit the node 5893446Smrj */ 5903446Smrj Level++; 5913446Smrj ParentNode = ChildNode; 5923446Smrj ChildNode = NULL; 5933446Smrj } 5943446Smrj else if (ChildNode->OwnerId == OwnerId) 5953446Smrj { 5963446Smrj DeletionNode = ChildNode; 5973446Smrj } 5983446Smrj } 5993446Smrj else 6003446Smrj { 6013446Smrj /* 6023446Smrj * No more children of this parent node. 6033446Smrj * Move up to the grandparent. 6043446Smrj */ 6053446Smrj Level--; 6063446Smrj if (Level != 0) 6073446Smrj { 6083446Smrj if (ParentNode->OwnerId == OwnerId) 6093446Smrj { 6103446Smrj DeletionNode = ParentNode; 6113446Smrj } 6123446Smrj } 6133446Smrj 6143446Smrj /* New "last child" is this parent node */ 6153446Smrj 6163446Smrj ChildNode = ParentNode; 6173446Smrj 6183446Smrj /* Move up the tree to the grandparent */ 6193446Smrj 6203446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 6213446Smrj } 6223446Smrj } 6233446Smrj 6243446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 6253446Smrj return_VOID; 6263446Smrj } 6273446Smrj 6283446Smrj 629