13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: nsalloc - Namespace allocation and deletion utilities 43446Smrj * 53446Smrj ******************************************************************************/ 63446Smrj 73446Smrj /****************************************************************************** 83446Smrj * 93446Smrj * 1. Copyright Notice 103446Smrj * 119980SDana.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" 1209980SDana.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 1629980SDana.Myers@Sun.COM Temp = AcpiGbl_NsNodeList->TotalAllocated - 1639980SDana.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 * 184*11225SDana.Myers@Sun.COM * DESCRIPTION: Delete a namespace node. All node deletions must come through 185*11225SDana.Myers@Sun.COM * here. Detaches any attached objects, including any attached 186*11225SDana.Myers@Sun.COM * data. If a handler is associated with attached data, it is 187*11225SDana.Myers@Sun.COM * invoked before the node is deleted. 1883446Smrj * 1893446Smrj ******************************************************************************/ 1903446Smrj 1913446Smrj void 1923446Smrj AcpiNsDeleteNode ( 1933446Smrj ACPI_NAMESPACE_NODE *Node) 1943446Smrj { 195*11225SDana.Myers@Sun.COM ACPI_OPERAND_OBJECT *ObjDesc; 196*11225SDana.Myers@Sun.COM 197*11225SDana.Myers@Sun.COM 198*11225SDana.Myers@Sun.COM ACPI_FUNCTION_NAME (NsDeleteNode); 199*11225SDana.Myers@Sun.COM 200*11225SDana.Myers@Sun.COM 201*11225SDana.Myers@Sun.COM /* Detach an object if there is one */ 202*11225SDana.Myers@Sun.COM 203*11225SDana.Myers@Sun.COM AcpiNsDetachObject (Node); 204*11225SDana.Myers@Sun.COM 205*11225SDana.Myers@Sun.COM /* 206*11225SDana.Myers@Sun.COM * Delete an attached data object if present (an object that was created 207*11225SDana.Myers@Sun.COM * and attached via AcpiAttachData). Note: After any normal object is 208*11225SDana.Myers@Sun.COM * detached above, the only possible remaining object is a data object. 209*11225SDana.Myers@Sun.COM */ 210*11225SDana.Myers@Sun.COM ObjDesc = Node->Object; 211*11225SDana.Myers@Sun.COM if (ObjDesc && 212*11225SDana.Myers@Sun.COM (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA)) 213*11225SDana.Myers@Sun.COM { 214*11225SDana.Myers@Sun.COM /* Invoke the attached data deletion handler if present */ 215*11225SDana.Myers@Sun.COM 216*11225SDana.Myers@Sun.COM if (ObjDesc->Data.Handler) 217*11225SDana.Myers@Sun.COM { 218*11225SDana.Myers@Sun.COM ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer); 219*11225SDana.Myers@Sun.COM } 220*11225SDana.Myers@Sun.COM 221*11225SDana.Myers@Sun.COM AcpiUtRemoveReference (ObjDesc); 222*11225SDana.Myers@Sun.COM } 223*11225SDana.Myers@Sun.COM 224*11225SDana.Myers@Sun.COM /* Now we can delete the node */ 225*11225SDana.Myers@Sun.COM 226*11225SDana.Myers@Sun.COM (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node); 227*11225SDana.Myers@Sun.COM 228*11225SDana.Myers@Sun.COM ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++); 229*11225SDana.Myers@Sun.COM ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", 230*11225SDana.Myers@Sun.COM Node, AcpiGbl_CurrentNodeCount)); 231*11225SDana.Myers@Sun.COM } 232*11225SDana.Myers@Sun.COM 233*11225SDana.Myers@Sun.COM 234*11225SDana.Myers@Sun.COM /******************************************************************************* 235*11225SDana.Myers@Sun.COM * 236*11225SDana.Myers@Sun.COM * FUNCTION: AcpiNsRemoveNode 237*11225SDana.Myers@Sun.COM * 238*11225SDana.Myers@Sun.COM * PARAMETERS: Node - Node to be removed/deleted 239*11225SDana.Myers@Sun.COM * 240*11225SDana.Myers@Sun.COM * RETURN: None 241*11225SDana.Myers@Sun.COM * 242*11225SDana.Myers@Sun.COM * DESCRIPTION: Remove (unlink) and delete a namespace node 243*11225SDana.Myers@Sun.COM * 244*11225SDana.Myers@Sun.COM ******************************************************************************/ 245*11225SDana.Myers@Sun.COM 246*11225SDana.Myers@Sun.COM void 247*11225SDana.Myers@Sun.COM AcpiNsRemoveNode ( 248*11225SDana.Myers@Sun.COM ACPI_NAMESPACE_NODE *Node) 249*11225SDana.Myers@Sun.COM { 2503446Smrj ACPI_NAMESPACE_NODE *ParentNode; 2513446Smrj ACPI_NAMESPACE_NODE *PrevNode; 2523446Smrj ACPI_NAMESPACE_NODE *NextNode; 2533446Smrj 2543446Smrj 255*11225SDana.Myers@Sun.COM ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node); 2563446Smrj 2573446Smrj 2583446Smrj ParentNode = AcpiNsGetParentNode (Node); 2593446Smrj 2603446Smrj PrevNode = NULL; 2613446Smrj NextNode = ParentNode->Child; 2623446Smrj 2633446Smrj /* Find the node that is the previous peer in the parent's child list */ 2643446Smrj 2653446Smrj while (NextNode != Node) 2663446Smrj { 2673446Smrj PrevNode = NextNode; 2683446Smrj NextNode = PrevNode->Peer; 2693446Smrj } 2703446Smrj 2713446Smrj if (PrevNode) 2723446Smrj { 2733446Smrj /* Node is not first child, unlink it */ 2743446Smrj 2753446Smrj PrevNode->Peer = NextNode->Peer; 2763446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2773446Smrj { 2783446Smrj PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 2793446Smrj } 2803446Smrj } 2813446Smrj else 2823446Smrj { 2833446Smrj /* Node is first child (has no previous peer) */ 2843446Smrj 2853446Smrj if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 2863446Smrj { 2873446Smrj /* No peers at all */ 2883446Smrj 2893446Smrj ParentNode->Child = NULL; 2903446Smrj } 2913446Smrj else 2923446Smrj { /* Link peer list to parent */ 2933446Smrj 2943446Smrj ParentNode->Child = NextNode->Peer; 2953446Smrj } 2963446Smrj } 2973446Smrj 298*11225SDana.Myers@Sun.COM /* Delete the node and any attached objects */ 2993446Smrj 300*11225SDana.Myers@Sun.COM AcpiNsDeleteNode (Node); 3013446Smrj return_VOID; 3023446Smrj } 3033446Smrj 3043446Smrj 3053446Smrj /******************************************************************************* 3063446Smrj * 3073446Smrj * FUNCTION: AcpiNsInstallNode 3083446Smrj * 3093446Smrj * PARAMETERS: WalkState - Current state of the walk 3103446Smrj * ParentNode - The parent of the new Node 3113446Smrj * Node - The new Node to install 3123446Smrj * Type - ACPI object type of the new Node 3133446Smrj * 3143446Smrj * RETURN: None 3153446Smrj * 3163446Smrj * DESCRIPTION: Initialize a new namespace node and install it amongst 3173446Smrj * its peers. 3183446Smrj * 3193446Smrj * Note: Current namespace lookup is linear search. This appears 3203446Smrj * to be sufficient as namespace searches consume only a small 3213446Smrj * fraction of the execution time of the ACPI subsystem. 3223446Smrj * 3233446Smrj ******************************************************************************/ 3243446Smrj 3253446Smrj void 3263446Smrj AcpiNsInstallNode ( 3273446Smrj ACPI_WALK_STATE *WalkState, 3283446Smrj ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 3293446Smrj ACPI_NAMESPACE_NODE *Node, /* New Child*/ 3303446Smrj ACPI_OBJECT_TYPE Type) 3313446Smrj { 3323446Smrj ACPI_OWNER_ID OwnerId = 0; 3333446Smrj ACPI_NAMESPACE_NODE *ChildNode; 3343446Smrj 3353446Smrj 3363446Smrj ACPI_FUNCTION_TRACE (NsInstallNode); 3373446Smrj 3383446Smrj 3393446Smrj /* 3409980SDana.Myers@Sun.COM * Get the owner ID from the Walk state. The owner ID is used to track 3419980SDana.Myers@Sun.COM * table deletion and deletion of objects created by methods. 3423446Smrj */ 3433446Smrj if (WalkState) 3443446Smrj { 3453446Smrj OwnerId = WalkState->OwnerId; 3463446Smrj } 3473446Smrj 3483446Smrj /* Link the new entry into the parent and existing children */ 3493446Smrj 3503446Smrj ChildNode = ParentNode->Child; 3513446Smrj if (!ChildNode) 3523446Smrj { 3533446Smrj ParentNode->Child = Node; 3543446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3553446Smrj Node->Peer = ParentNode; 3563446Smrj } 3573446Smrj else 3583446Smrj { 3593446Smrj while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 3603446Smrj { 3613446Smrj ChildNode = ChildNode->Peer; 3623446Smrj } 3633446Smrj 3643446Smrj ChildNode->Peer = Node; 3653446Smrj 3663446Smrj /* Clear end-of-list flag */ 3673446Smrj 3683446Smrj ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 3693446Smrj Node->Flags |= ANOBJ_END_OF_PEER_LIST; 3703446Smrj Node->Peer = ParentNode; 3713446Smrj } 3723446Smrj 3733446Smrj /* Init the new entry */ 3743446Smrj 3753446Smrj Node->OwnerId = OwnerId; 3763446Smrj Node->Type = (UINT8) Type; 3773446Smrj 3783446Smrj ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 3793446Smrj "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 3803446Smrj AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, 3813446Smrj AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), 3823446Smrj ParentNode)); 3833446Smrj 3843446Smrj return_VOID; 3853446Smrj } 3863446Smrj 3873446Smrj 3883446Smrj /******************************************************************************* 3893446Smrj * 3903446Smrj * FUNCTION: AcpiNsDeleteChildren 3913446Smrj * 3923446Smrj * PARAMETERS: ParentNode - Delete this objects children 3933446Smrj * 3943446Smrj * RETURN: None. 3953446Smrj * 3963446Smrj * DESCRIPTION: Delete all children of the parent object. In other words, 3973446Smrj * deletes a "scope". 3983446Smrj * 3993446Smrj ******************************************************************************/ 4003446Smrj 4013446Smrj void 4023446Smrj AcpiNsDeleteChildren ( 4033446Smrj ACPI_NAMESPACE_NODE *ParentNode) 4043446Smrj { 4053446Smrj ACPI_NAMESPACE_NODE *ChildNode; 4063446Smrj ACPI_NAMESPACE_NODE *NextNode; 4073446Smrj UINT8 Flags; 4083446Smrj 4093446Smrj 4103446Smrj ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode); 4113446Smrj 4123446Smrj 4133446Smrj if (!ParentNode) 4143446Smrj { 4153446Smrj return_VOID; 4163446Smrj } 4173446Smrj 4183446Smrj /* If no children, all done! */ 4193446Smrj 4203446Smrj ChildNode = ParentNode->Child; 4213446Smrj if (!ChildNode) 4223446Smrj { 4233446Smrj return_VOID; 4243446Smrj } 4253446Smrj 4269980SDana.Myers@Sun.COM /* Deallocate all children at this level */ 4279980SDana.Myers@Sun.COM 4283446Smrj do 4293446Smrj { 4303446Smrj /* Get the things we need */ 4313446Smrj 4323446Smrj NextNode = ChildNode->Peer; 4333446Smrj Flags = ChildNode->Flags; 4343446Smrj 4353446Smrj /* Grandchildren should have all been deleted already */ 4363446Smrj 4373446Smrj if (ChildNode->Child) 4383446Smrj { 4393446Smrj ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p", 4403446Smrj ParentNode, ChildNode)); 4413446Smrj } 4423446Smrj 443*11225SDana.Myers@Sun.COM /* 444*11225SDana.Myers@Sun.COM * Delete this child node and move on to the next child in the list. 445*11225SDana.Myers@Sun.COM * No need to unlink the node since we are deleting the entire branch. 446*11225SDana.Myers@Sun.COM */ 447*11225SDana.Myers@Sun.COM AcpiNsDeleteNode (ChildNode); 4483446Smrj ChildNode = NextNode; 4493446Smrj 4503446Smrj } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 4513446Smrj 4523446Smrj /* Clear the parent's child pointer */ 4533446Smrj 4543446Smrj ParentNode->Child = NULL; 4553446Smrj return_VOID; 4563446Smrj } 4573446Smrj 4583446Smrj 4593446Smrj /******************************************************************************* 4603446Smrj * 4613446Smrj * FUNCTION: AcpiNsDeleteNamespaceSubtree 4623446Smrj * 4633446Smrj * PARAMETERS: ParentNode - Root of the subtree to be deleted 4643446Smrj * 4653446Smrj * RETURN: None. 4663446Smrj * 4673446Smrj * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 4683446Smrj * stored within the subtree. 4693446Smrj * 4703446Smrj ******************************************************************************/ 4713446Smrj 4723446Smrj void 4733446Smrj AcpiNsDeleteNamespaceSubtree ( 4743446Smrj ACPI_NAMESPACE_NODE *ParentNode) 4753446Smrj { 4763446Smrj ACPI_NAMESPACE_NODE *ChildNode = NULL; 4773446Smrj UINT32 Level = 1; 4783446Smrj 4793446Smrj 4803446Smrj ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree); 4813446Smrj 4823446Smrj 4833446Smrj if (!ParentNode) 4843446Smrj { 4853446Smrj return_VOID; 4863446Smrj } 4873446Smrj 4883446Smrj /* 4893446Smrj * Traverse the tree of objects until we bubble back up 4903446Smrj * to where we started. 4913446Smrj */ 4923446Smrj while (Level > 0) 4933446Smrj { 4943446Smrj /* Get the next node in this scope (NULL if none) */ 4953446Smrj 4969980SDana.Myers@Sun.COM ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); 4973446Smrj if (ChildNode) 4983446Smrj { 4993446Smrj /* Found a child node - detach any attached object */ 5003446Smrj 5013446Smrj AcpiNsDetachObject (ChildNode); 5023446Smrj 5033446Smrj /* Check if this node has any children */ 5043446Smrj 5059980SDana.Myers@Sun.COM if (ChildNode->Child) 5063446Smrj { 5073446Smrj /* 5083446Smrj * There is at least one child of this node, 5093446Smrj * visit the node 5103446Smrj */ 5113446Smrj Level++; 5123446Smrj ParentNode = ChildNode; 5133446Smrj ChildNode = NULL; 5143446Smrj } 5153446Smrj } 5163446Smrj else 5173446Smrj { 5183446Smrj /* 5193446Smrj * No more children of this parent node. 5203446Smrj * Move up to the grandparent. 5213446Smrj */ 5223446Smrj Level--; 5233446Smrj 5243446Smrj /* 5253446Smrj * Now delete all of the children of this parent 5263446Smrj * all at the same time. 5273446Smrj */ 5283446Smrj AcpiNsDeleteChildren (ParentNode); 5293446Smrj 5303446Smrj /* New "last child" is this parent node */ 5313446Smrj 5323446Smrj ChildNode = ParentNode; 5333446Smrj 5343446Smrj /* Move up the tree to the grandparent */ 5353446Smrj 5363446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 5373446Smrj } 5383446Smrj } 5393446Smrj 5403446Smrj return_VOID; 5413446Smrj } 5423446Smrj 5433446Smrj 5443446Smrj /******************************************************************************* 5453446Smrj * 5463446Smrj * FUNCTION: AcpiNsDeleteNamespaceByOwner 5473446Smrj * 5483446Smrj * PARAMETERS: OwnerId - All nodes with this owner will be deleted 5493446Smrj * 5503446Smrj * RETURN: Status 5513446Smrj * 5523446Smrj * DESCRIPTION: Delete entries within the namespace that are owned by a 5533446Smrj * specific ID. Used to delete entire ACPI tables. All 5543446Smrj * reference counts are updated. 5553446Smrj * 5563446Smrj * MUTEX: Locks namespace during deletion walk. 5573446Smrj * 5583446Smrj ******************************************************************************/ 5593446Smrj 5603446Smrj void 5613446Smrj AcpiNsDeleteNamespaceByOwner ( 5623446Smrj ACPI_OWNER_ID OwnerId) 5633446Smrj { 5643446Smrj ACPI_NAMESPACE_NODE *ChildNode; 5653446Smrj ACPI_NAMESPACE_NODE *DeletionNode; 5663446Smrj ACPI_NAMESPACE_NODE *ParentNode; 5673446Smrj UINT32 Level; 5683446Smrj ACPI_STATUS Status; 5693446Smrj 5703446Smrj 5713446Smrj ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId); 5723446Smrj 5733446Smrj 5743446Smrj if (OwnerId == 0) 5753446Smrj { 5763446Smrj return_VOID; 5773446Smrj } 5783446Smrj 5793446Smrj /* Lock namespace for possible update */ 5803446Smrj 5813446Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 5823446Smrj if (ACPI_FAILURE (Status)) 5833446Smrj { 5843446Smrj return_VOID; 5853446Smrj } 5863446Smrj 5873446Smrj DeletionNode = NULL; 5883446Smrj ParentNode = AcpiGbl_RootNode; 5893446Smrj ChildNode = NULL; 5903446Smrj Level = 1; 5913446Smrj 5923446Smrj /* 5933446Smrj * Traverse the tree of nodes until we bubble back up 5943446Smrj * to where we started. 5953446Smrj */ 5963446Smrj while (Level > 0) 5973446Smrj { 5983446Smrj /* 5993446Smrj * Get the next child of this parent node. When ChildNode is NULL, 6003446Smrj * the first child of the parent is returned 6013446Smrj */ 6029980SDana.Myers@Sun.COM ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode); 6033446Smrj 6043446Smrj if (DeletionNode) 6053446Smrj { 6063446Smrj AcpiNsDeleteChildren (DeletionNode); 607*11225SDana.Myers@Sun.COM AcpiNsRemoveNode (DeletionNode); 6083446Smrj DeletionNode = NULL; 6093446Smrj } 6103446Smrj 6113446Smrj if (ChildNode) 6123446Smrj { 6133446Smrj if (ChildNode->OwnerId == OwnerId) 6143446Smrj { 6153446Smrj /* Found a matching child node - detach any attached object */ 6163446Smrj 6173446Smrj AcpiNsDetachObject (ChildNode); 6183446Smrj } 6193446Smrj 6203446Smrj /* Check if this node has any children */ 6213446Smrj 6229980SDana.Myers@Sun.COM if (ChildNode->Child) 6233446Smrj { 6243446Smrj /* 6253446Smrj * There is at least one child of this node, 6263446Smrj * visit the node 6273446Smrj */ 6283446Smrj Level++; 6293446Smrj ParentNode = ChildNode; 6303446Smrj ChildNode = NULL; 6313446Smrj } 6323446Smrj else if (ChildNode->OwnerId == OwnerId) 6333446Smrj { 6343446Smrj DeletionNode = ChildNode; 6353446Smrj } 6363446Smrj } 6373446Smrj else 6383446Smrj { 6393446Smrj /* 6403446Smrj * No more children of this parent node. 6413446Smrj * Move up to the grandparent. 6423446Smrj */ 6433446Smrj Level--; 6443446Smrj if (Level != 0) 6453446Smrj { 6463446Smrj if (ParentNode->OwnerId == OwnerId) 6473446Smrj { 6483446Smrj DeletionNode = ParentNode; 6493446Smrj } 6503446Smrj } 6513446Smrj 6523446Smrj /* New "last child" is this parent node */ 6533446Smrj 6543446Smrj ChildNode = ParentNode; 6553446Smrj 6563446Smrj /* Move up the tree to the grandparent */ 6573446Smrj 6583446Smrj ParentNode = AcpiNsGetParentNode (ParentNode); 6593446Smrj } 6603446Smrj } 6613446Smrj 6623446Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 6633446Smrj return_VOID; 6643446Smrj } 6653446Smrj 6663446Smrj 667