13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: nsalloc - Namespace allocation and deletion utilities 43446Smrj * 53446Smrj ******************************************************************************/ 63446Smrj 73446Smrj /****************************************************************************** 83446Smrj * 93446Smrj * 1. Copyright Notice 103446Smrj * 11*9980SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 123446Smrj * All rights reserved. 133446Smrj * 143446Smrj * 2. License 153446Smrj * 163446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 173446Smrj * rights. You may have additional license terms from the party that provided 183446Smrj * you this software, covering your right to use that party's intellectual 193446Smrj * property rights. 203446Smrj * 213446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 223446Smrj * copy of the source code appearing in this file ("Covered Code") an 233446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 243446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 253446Smrj * make derivatives, distribute, use and display any portion of the Covered 263446Smrj * Code in any form, with the right to sublicense such rights; and 273446Smrj * 283446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 293446Smrj * license (with the right to sublicense), under only those claims of Intel 303446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 313446Smrj * offer to sell, and import the Covered Code and derivative works thereof 323446Smrj * solely to the minimum extent necessary to exercise the above copyright 333446Smrj * license, and in no event shall the patent license extend to any additions 343446Smrj * to or modifications of the Original Intel Code. No other license or right 353446Smrj * is granted directly or by implication, estoppel or otherwise; 363446Smrj * 373446Smrj * The above copyright and patent license is granted only if the following 383446Smrj * conditions are met: 393446Smrj * 403446Smrj * 3. Conditions 413446Smrj * 423446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 433446Smrj * Redistribution of source code of any substantial portion of the Covered 443446Smrj * Code or modification with rights to further distribute source must include 453446Smrj * the above Copyright Notice, the above License, this list of Conditions, 463446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 473446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 483446Smrj * contain a file documenting the changes Licensee made to create that Covered 493446Smrj * Code and the date of any change. Licensee must include in that file the 503446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 513446Smrj * must include a prominent statement that the modification is derived, 523446Smrj * directly or indirectly, from Original Intel Code. 533446Smrj * 543446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 553446Smrj * Redistribution of source code of any substantial portion of the Covered 563446Smrj * Code or modification without rights to further distribute source must 573446Smrj * include the following Disclaimer and Export Compliance provision in the 583446Smrj * documentation and/or other materials provided with distribution. In 593446Smrj * addition, Licensee may not authorize further sublicense of source of any 603446Smrj * portion of the Covered Code, and must include terms to the effect that the 613446Smrj * license from Licensee to its licensee is limited to the intellectual 623446Smrj * property embodied in the software Licensee provides to its licensee, and 633446Smrj * not to intellectual property embodied in modifications its licensee may 643446Smrj * make. 653446Smrj * 663446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 673446Smrj * substantial portion of the Covered Code or modification must reproduce the 683446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 693446Smrj * provision in the documentation and/or other materials provided with the 703446Smrj * distribution. 713446Smrj * 723446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 733446Smrj * Intel Code. 743446Smrj * 753446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 763446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 773446Smrj * other dealings in products derived from or relating to the Covered Code 783446Smrj * without prior written authorization from Intel. 793446Smrj * 803446Smrj * 4. Disclaimer and Export Compliance 813446Smrj * 823446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 833446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 843446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 853446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 863446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 873446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 883446Smrj * PARTICULAR PURPOSE. 893446Smrj * 903446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 913446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 923446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 933446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 943446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 953446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 963446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 973446Smrj * LIMITED REMEDY. 983446Smrj * 993446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1003446Smrj * software or system incorporating such software without first obtaining any 1013446Smrj * required license or other approval from the U. S. Department of Commerce or 1023446Smrj * any other agency or department of the United States Government. In the 1033446Smrj * event Licensee exports any such software from the United States or 1043446Smrj * re-exports any such software from a foreign destination, Licensee shall 1053446Smrj * ensure that the distribution and export/re-export of the software is in 1063446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1073446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1083446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1093446Smrj * software, or service, directly or indirectly, to any country for which the 1103446Smrj * United States government or any agency thereof requires an export license, 1113446Smrj * other governmental approval, or letter of assurance, without first obtaining 1123446Smrj * such license, approval or letter. 1133446Smrj * 1143446Smrj *****************************************************************************/ 1153446Smrj 1163446Smrj 1173446Smrj #define __NSALLOC_C__ 1183446Smrj 1193446Smrj #include "acpi.h" 120*9980SDana.Myers@Sun.COM #include "accommon.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; 1457851SDana.Myers@Sun.COM #ifdef ACPI_DBG_TRACK_ALLOCATIONS 1467851SDana.Myers@Sun.COM UINT32 Temp; 1477851SDana.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 1617851SDana.Myers@Sun.COM #ifdef ACPI_DBG_TRACK_ALLOCATIONS 162*9980SDana.Myers@Sun.COM Temp = AcpiGbl_NsNodeList->TotalAllocated - 163*9980SDana.Myers@Sun.COM AcpiGbl_NsNodeList->TotalFreed; 1647851SDana.Myers@Sun.COM if (Temp > AcpiGbl_NsNodeList->MaxOccupied) 1657851SDana.Myers@Sun.COM { 1667851SDana.Myers@Sun.COM AcpiGbl_NsNodeList->MaxOccupied = Temp; 1677851SDana.Myers@Sun.COM } 1687851SDana.Myers@Sun.COM #endif 1697851SDana.Myers@Sun.COM 1703446Smrj Node->Name.Integer = Name; 1713446Smrj ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 1723446Smrj return_PTR (Node); 1733446Smrj } 1743446Smrj 1753446Smrj 1763446Smrj /******************************************************************************* 1773446Smrj * 1783446Smrj * FUNCTION: AcpiNsDeleteNode 1793446Smrj * 1803446Smrj * PARAMETERS: Node - Node to be deleted 1813446Smrj * 1823446Smrj * RETURN: None 1833446Smrj * 1843446Smrj * DESCRIPTION: Delete a namespace node 1853446Smrj * 1863446Smrj ******************************************************************************/ 1873446Smrj 1883446Smrj void 1893446Smrj AcpiNsDeleteNode ( 1903446Smrj ACPI_NAMESPACE_NODE *Node) 1913446Smrj { 1923446Smrj ACPI_NAMESPACE_NODE *ParentNode; 1933446Smrj ACPI_NAMESPACE_NODE *PrevNode; 1943446Smrj ACPI_NAMESPACE_NODE *NextNode; 1953446Smrj 1963446Smrj 1973446Smrj ACPI_FUNCTION_TRACE_PTR (NsDeleteNode, Node); 1983446Smrj 1993446Smrj 2003446Smrj ParentNode = AcpiNsGetParentNode (Node); 2013446Smrj 2023446Smrj PrevNode = NULL; 2033446Smrj NextNode = ParentNode->Child; 2043446Smrj 2053446Smrj /* Find the node that is the previous peer in the parent's child list */ 2063446Smrj 2073446Smrj while (NextNode != Node) 2083446Smrj { 2093446Smrj PrevNode = NextNode; 2103446Smrj NextNode = PrevNode->Peer; 2113446Smrj } 2123446Smrj 2133446Smrj if (PrevNode) 2143446Smrj { 2153446Smrj /* Node is not first child, unlink it */ 2163446Smrj 2173446Smrj PrevNode->Peer = NextNode->Peer; 2183446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2193446Smrj { 2203446Smrj PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 2213446Smrj } 2223446Smrj } 2233446Smrj else 2243446Smrj { 2253446Smrj /* Node is first child (has no previous peer) */ 2263446Smrj 2273446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2283446Smrj { 2293446Smrj /* No peers at all */ 2303446Smrj 2313446Smrj ParentNode->Child = NULL; 2323446Smrj } 2333446Smrj else 2343446Smrj { /* Link peer list to parent */ 2353446Smrj 2363446Smrj ParentNode->Child = NextNode->Peer; 2373446Smrj } 2383446Smrj } 2393446Smrj 2403446Smrj ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 2413446Smrj 242*9980SDana.Myers@Sun.COM /* Detach an object if there is one, then delete the node */ 243*9980SDana.Myers@Sun.COM 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 /* 285*9980SDana.Myers@Sun.COM * Get the owner ID from the Walk state. The owner ID is used to track 286*9980SDana.Myers@Sun.COM * table deletion and deletion of objects created by methods. 2873446Smrj */ 2883446Smrj if (WalkState) 2893446Smrj { 2903446Smrj OwnerId = WalkState->OwnerId; 2913446Smrj } 2923446Smrj 2933446Smrj /* Link the new entry into the parent and existing children */ 2943446Smrj 2953446Smrj ChildNode = ParentNode->Child; 2963446Smrj if (!ChildNode) 2973446Smrj { 2983446Smrj ParentNode->Child = Node; 2993446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3003446Smrj Node->Peer = ParentNode; 3013446Smrj } 3023446Smrj else 3033446Smrj { 3043446Smrj while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 3053446Smrj { 3063446Smrj ChildNode = ChildNode->Peer; 3073446Smrj } 3083446Smrj 3093446Smrj ChildNode->Peer = Node; 3103446Smrj 3113446Smrj /* Clear end-of-list flag */ 3123446Smrj 3133446Smrj ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 3143446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3153446Smrj Node->Peer = ParentNode; 3163446Smrj } 3173446Smrj 3183446Smrj /* Init the new entry */ 3193446Smrj 3203446Smrj Node->OwnerId = OwnerId; 3213446Smrj Node->Type = (UINT8) Type; 3223446Smrj 3233446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 3243446Smrj "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 3253446Smrj AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, 3263446Smrj AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), 3273446Smrj ParentNode)); 3283446Smrj 3293446Smrj return_VOID; 3303446Smrj } 3313446Smrj 3323446Smrj 3333446Smrj /******************************************************************************* 3343446Smrj * 3353446Smrj * FUNCTION: AcpiNsDeleteChildren 3363446Smrj * 3373446Smrj * PARAMETERS: ParentNode - Delete this objects children 3383446Smrj * 3393446Smrj * RETURN: None. 3403446Smrj * 3413446Smrj * DESCRIPTION: Delete all children of the parent object. In other words, 3423446Smrj * deletes a "scope". 3433446Smrj * 3443446Smrj ******************************************************************************/ 3453446Smrj 3463446Smrj void 3473446Smrj AcpiNsDeleteChildren ( 3483446Smrj ACPI_NAMESPACE_NODE *ParentNode) 3493446Smrj { 3503446Smrj ACPI_NAMESPACE_NODE *ChildNode; 3513446Smrj ACPI_NAMESPACE_NODE *NextNode; 3523446Smrj UINT8 Flags; 3533446Smrj 3543446Smrj 3553446Smrj ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode); 3563446Smrj 3573446Smrj 3583446Smrj if (!ParentNode) 3593446Smrj { 3603446Smrj return_VOID; 3613446Smrj } 3623446Smrj 3633446Smrj /* If no children, all done! */ 3643446Smrj 3653446Smrj ChildNode = ParentNode->Child; 3663446Smrj if (!ChildNode) 3673446Smrj { 3683446Smrj return_VOID; 3693446Smrj } 3703446Smrj 371*9980SDana.Myers@Sun.COM /* Deallocate all children at this level */ 372*9980SDana.Myers@Sun.COM 3733446Smrj do 3743446Smrj { 3753446Smrj /* Get the things we need */ 3763446Smrj 3773446Smrj NextNode = ChildNode->Peer; 3783446Smrj Flags = ChildNode->Flags; 3793446Smrj 3803446Smrj /* Grandchildren should have all been deleted already */ 3813446Smrj 3823446Smrj if (ChildNode->Child) 3833446Smrj { 3843446Smrj ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p", 3853446Smrj ParentNode, ChildNode)); 3863446Smrj } 3873446Smrj 3883446Smrj /* Now we can free this child object */ 3893446Smrj 3903446Smrj ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 3913446Smrj 3923446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 3933446Smrj ChildNode, AcpiGbl_CurrentNodeCount)); 3943446Smrj 395*9980SDana.Myers@Sun.COM /* Detach an object if there is one, then free the child node */ 396*9980SDana.Myers@Sun.COM 3973446Smrj AcpiNsDetachObject (ChildNode); 3983446Smrj 3993446Smrj /* Now we can delete the node */ 4003446Smrj 4013446Smrj (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, ChildNode); 4023446Smrj 4033446Smrj /* And move on to the next child in the list */ 4043446Smrj 4053446Smrj ChildNode = NextNode; 4063446Smrj 4073446Smrj } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 4083446Smrj 4093446Smrj /* Clear the parent's child pointer */ 4103446Smrj 4113446Smrj ParentNode->Child = NULL; 4123446Smrj return_VOID; 4133446Smrj } 4143446Smrj 4153446Smrj 4163446Smrj /******************************************************************************* 4173446Smrj * 4183446Smrj * FUNCTION: AcpiNsDeleteNamespaceSubtree 4193446Smrj * 4203446Smrj * PARAMETERS: ParentNode - Root of the subtree to be deleted 4213446Smrj * 4223446Smrj * RETURN: None. 4233446Smrj * 4243446Smrj * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 4253446Smrj * stored within the subtree. 4263446Smrj * 4273446Smrj ******************************************************************************/ 4283446Smrj 4293446Smrj void 4303446Smrj AcpiNsDeleteNamespaceSubtree ( 4313446Smrj ACPI_NAMESPACE_NODE *ParentNode) 4323446Smrj { 4333446Smrj ACPI_NAMESPACE_NODE *ChildNode = NULL; 4343446Smrj UINT32 Level = 1; 4353446Smrj 4363446Smrj 4373446Smrj ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree); 4383446Smrj 4393446Smrj 4403446Smrj if (!ParentNode) 4413446Smrj { 4423446Smrj return_VOID; 4433446Smrj } 4443446Smrj 4453446Smrj /* 4463446Smrj * Traverse the tree of objects until we bubble back up 4473446Smrj * to where we started. 4483446Smrj */ 4493446Smrj while (Level > 0) 4503446Smrj { 4513446Smrj /* Get the next node in this scope (NULL if none) */ 4523446Smrj 453*9980SDana.Myers@Sun.COM ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); 4543446Smrj if (ChildNode) 4553446Smrj { 4563446Smrj /* Found a child node - detach any attached object */ 4573446Smrj 4583446Smrj AcpiNsDetachObject (ChildNode); 4593446Smrj 4603446Smrj /* Check if this node has any children */ 4613446Smrj 462*9980SDana.Myers@Sun.COM if (ChildNode->Child) 4633446Smrj { 4643446Smrj /* 4653446Smrj * There is at least one child of this node, 4663446Smrj * visit the node 4673446Smrj */ 4683446Smrj Level++; 4693446Smrj ParentNode = ChildNode; 4703446Smrj ChildNode = NULL; 4713446Smrj } 4723446Smrj } 4733446Smrj else 4743446Smrj { 4753446Smrj /* 4763446Smrj * No more children of this parent node. 4773446Smrj * Move up to the grandparent. 4783446Smrj */ 4793446Smrj Level--; 4803446Smrj 4813446Smrj /* 4823446Smrj * Now delete all of the children of this parent 4833446Smrj * all at the same time. 4843446Smrj */ 4853446Smrj AcpiNsDeleteChildren (ParentNode); 4863446Smrj 4873446Smrj /* New "last child" is this parent node */ 4883446Smrj 4893446Smrj ChildNode = ParentNode; 4903446Smrj 4913446Smrj /* Move up the tree to the grandparent */ 4923446Smrj 4933446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 4943446Smrj } 4953446Smrj } 4963446Smrj 4973446Smrj return_VOID; 4983446Smrj } 4993446Smrj 5003446Smrj 5013446Smrj /******************************************************************************* 5023446Smrj * 5033446Smrj * FUNCTION: AcpiNsDeleteNamespaceByOwner 5043446Smrj * 5053446Smrj * PARAMETERS: OwnerId - All nodes with this owner will be deleted 5063446Smrj * 5073446Smrj * RETURN: Status 5083446Smrj * 5093446Smrj * DESCRIPTION: Delete entries within the namespace that are owned by a 5103446Smrj * specific ID. Used to delete entire ACPI tables. All 5113446Smrj * reference counts are updated. 5123446Smrj * 5133446Smrj * MUTEX: Locks namespace during deletion walk. 5143446Smrj * 5153446Smrj ******************************************************************************/ 5163446Smrj 5173446Smrj void 5183446Smrj AcpiNsDeleteNamespaceByOwner ( 5193446Smrj ACPI_OWNER_ID OwnerId) 5203446Smrj { 5213446Smrj ACPI_NAMESPACE_NODE *ChildNode; 5223446Smrj ACPI_NAMESPACE_NODE *DeletionNode; 5233446Smrj ACPI_NAMESPACE_NODE *ParentNode; 5243446Smrj UINT32 Level; 5253446Smrj ACPI_STATUS Status; 5263446Smrj 5273446Smrj 5283446Smrj ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId); 5293446Smrj 5303446Smrj 5313446Smrj if (OwnerId == 0) 5323446Smrj { 5333446Smrj return_VOID; 5343446Smrj } 5353446Smrj 5363446Smrj /* Lock namespace for possible update */ 5373446Smrj 5383446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 5393446Smrj if (ACPI_FAILURE (Status)) 5403446Smrj { 5413446Smrj return_VOID; 5423446Smrj } 5433446Smrj 5443446Smrj DeletionNode = NULL; 5453446Smrj ParentNode = AcpiGbl_RootNode; 5463446Smrj ChildNode = NULL; 5473446Smrj Level = 1; 5483446Smrj 5493446Smrj /* 5503446Smrj * Traverse the tree of nodes until we bubble back up 5513446Smrj * to where we started. 5523446Smrj */ 5533446Smrj while (Level > 0) 5543446Smrj { 5553446Smrj /* 5563446Smrj * Get the next child of this parent node. When ChildNode is NULL, 5573446Smrj * the first child of the parent is returned 5583446Smrj */ 559*9980SDana.Myers@Sun.COM ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); 5603446Smrj 5613446Smrj if (DeletionNode) 5623446Smrj { 5633446Smrj AcpiNsDeleteChildren (DeletionNode); 5643446Smrj AcpiNsDeleteNode (DeletionNode); 5653446Smrj DeletionNode = NULL; 5663446Smrj } 5673446Smrj 5683446Smrj if (ChildNode) 5693446Smrj { 5703446Smrj if (ChildNode->OwnerId == OwnerId) 5713446Smrj { 5723446Smrj /* Found a matching child node - detach any attached object */ 5733446Smrj 5743446Smrj AcpiNsDetachObject (ChildNode); 5753446Smrj } 5763446Smrj 5773446Smrj /* Check if this node has any children */ 5783446Smrj 579*9980SDana.Myers@Sun.COM if (ChildNode->Child) 5803446Smrj { 5813446Smrj /* 5823446Smrj * There is at least one child of this node, 5833446Smrj * visit the node 5843446Smrj */ 5853446Smrj Level++; 5863446Smrj ParentNode = ChildNode; 5873446Smrj ChildNode = NULL; 5883446Smrj } 5893446Smrj else if (ChildNode->OwnerId == OwnerId) 5903446Smrj { 5913446Smrj DeletionNode = ChildNode; 5923446Smrj } 5933446Smrj } 5943446Smrj else 5953446Smrj { 5963446Smrj /* 5973446Smrj * No more children of this parent node. 5983446Smrj * Move up to the grandparent. 5993446Smrj */ 6003446Smrj Level--; 6013446Smrj if (Level != 0) 6023446Smrj { 6033446Smrj if (ParentNode->OwnerId == OwnerId) 6043446Smrj { 6053446Smrj DeletionNode = ParentNode; 6063446Smrj } 6073446Smrj } 6083446Smrj 6093446Smrj /* New "last child" is this parent node */ 6103446Smrj 6113446Smrj ChildNode = ParentNode; 6123446Smrj 6133446Smrj /* Move up the tree to the grandparent */ 6143446Smrj 6153446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 6163446Smrj } 6173446Smrj } 6183446Smrj 6193446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 6203446Smrj return_VOID; 6213446Smrj } 6223446Smrj 6233446Smrj 624