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