nsalloc.c revision 209746
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: nsalloc - Namespace allocation and deletion utilities
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11202771Sjkim * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp.
1270243Smsmith * All rights reserved.
1367754Smsmith *
1467754Smsmith * 2. License
1567754Smsmith *
1667754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1767754Smsmith * rights.  You may have additional license terms from the party that provided
1867754Smsmith * you this software, covering your right to use that party's intellectual
1967754Smsmith * property rights.
2067754Smsmith *
2167754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2267754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2367754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2467754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2567754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2667754Smsmith * Code in any form, with the right to sublicense such rights; and
2767754Smsmith *
2867754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
2967754Smsmith * license (with the right to sublicense), under only those claims of Intel
3067754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3167754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3267754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3367754Smsmith * license, and in no event shall the patent license extend to any additions
3467754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3567754Smsmith * is granted directly or by implication, estoppel or otherwise;
3667754Smsmith *
3767754Smsmith * The above copyright and patent license is granted only if the following
3867754Smsmith * conditions are met:
3967754Smsmith *
4067754Smsmith * 3. Conditions
4167754Smsmith *
4267754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4367754Smsmith * Redistribution of source code of any substantial portion of the Covered
4467754Smsmith * Code or modification with rights to further distribute source must include
4567754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4667754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4767754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4867754Smsmith * contain a file documenting the changes Licensee made to create that Covered
4967754Smsmith * Code and the date of any change.  Licensee must include in that file the
5067754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5167754Smsmith * must include a prominent statement that the modification is derived,
5267754Smsmith * directly or indirectly, from Original Intel Code.
5367754Smsmith *
5467754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5567754Smsmith * Redistribution of source code of any substantial portion of the Covered
5667754Smsmith * Code or modification without rights to further distribute source must
5767754Smsmith * include the following Disclaimer and Export Compliance provision in the
5867754Smsmith * documentation and/or other materials provided with distribution.  In
5967754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6067754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6167754Smsmith * license from Licensee to its licensee is limited to the intellectual
6267754Smsmith * property embodied in the software Licensee provides to its licensee, and
6367754Smsmith * not to intellectual property embodied in modifications its licensee may
6467754Smsmith * make.
6567754Smsmith *
6667754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6767754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6867754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
6967754Smsmith * provision in the documentation and/or other materials provided with the
7067754Smsmith * distribution.
7167754Smsmith *
7267754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7367754Smsmith * Intel Code.
7467754Smsmith *
7567754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7667754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7767754Smsmith * other dealings in products derived from or relating to the Covered Code
7867754Smsmith * without prior written authorization from Intel.
7967754Smsmith *
8067754Smsmith * 4. Disclaimer and Export Compliance
8167754Smsmith *
8267754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8367754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8467754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8567754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8667754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8767754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8867754Smsmith * PARTICULAR PURPOSE.
8967754Smsmith *
9067754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9167754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9267754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9367754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9467754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9567754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9667754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9767754Smsmith * LIMITED REMEDY.
9867754Smsmith *
9967754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10067754Smsmith * software or system incorporating such software without first obtaining any
10167754Smsmith * required license or other approval from the U. S. Department of Commerce or
10267754Smsmith * any other agency or department of the United States Government.  In the
10367754Smsmith * event Licensee exports any such software from the United States or
10467754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10567754Smsmith * ensure that the distribution and export/re-export of the software is in
10667754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10767754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10867754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
10967754Smsmith * software, or service, directly or indirectly, to any country for which the
11067754Smsmith * United States government or any agency thereof requires an export license,
11167754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11267754Smsmith * such license, approval or letter.
11367754Smsmith *
11467754Smsmith *****************************************************************************/
11567754Smsmith
11667754Smsmith
11767754Smsmith#define __NSALLOC_C__
11867754Smsmith
119193341Sjkim#include <contrib/dev/acpica/include/acpi.h>
120193341Sjkim#include <contrib/dev/acpica/include/accommon.h>
121193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h>
12267754Smsmith
12367754Smsmith
12477424Smsmith#define _COMPONENT          ACPI_NAMESPACE
12591116Smsmith        ACPI_MODULE_NAME    ("nsalloc")
12667754Smsmith
12767754Smsmith
12867754Smsmith/*******************************************************************************
12967754Smsmith *
13067754Smsmith * FUNCTION:    AcpiNsCreateNode
13167754Smsmith *
132151937Sjkim * PARAMETERS:  Name            - Name of the new node (4 char ACPI name)
13367754Smsmith *
134151937Sjkim * RETURN:      New namespace node (Null on failure)
13567754Smsmith *
13683174Smsmith * DESCRIPTION: Create a namespace node
13767754Smsmith *
13867754Smsmith ******************************************************************************/
13967754Smsmith
14067754SmsmithACPI_NAMESPACE_NODE *
14167754SmsmithAcpiNsCreateNode (
14284491Smsmith    UINT32                  Name)
14367754Smsmith{
14467754Smsmith    ACPI_NAMESPACE_NODE     *Node;
145167802Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS
146167802Sjkim    UINT32                  Temp;
147167802Sjkim#endif
14867754Smsmith
14983174Smsmith
150167802Sjkim    ACPI_FUNCTION_TRACE (NsCreateNode);
15167754Smsmith
15267754Smsmith
153167802Sjkim    Node = AcpiOsAcquireObject (AcpiGbl_NamespaceCache);
15467754Smsmith    if (!Node)
15567754Smsmith    {
15667754Smsmith        return_PTR (NULL);
15767754Smsmith    }
15867754Smsmith
159151937Sjkim    ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalAllocated++);
16067754Smsmith
161167802Sjkim#ifdef ACPI_DBG_TRACK_ALLOCATIONS
162193267Sjkim        Temp = AcpiGbl_NsNodeList->TotalAllocated -
163193267Sjkim                AcpiGbl_NsNodeList->TotalFreed;
164167802Sjkim        if (Temp > AcpiGbl_NsNodeList->MaxOccupied)
165167802Sjkim        {
166167802Sjkim            AcpiGbl_NsNodeList->MaxOccupied = Temp;
167167802Sjkim        }
168167802Sjkim#endif
169167802Sjkim
170167802Sjkim    Node->Name.Integer = Name;
17191116Smsmith    ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED);
17267754Smsmith    return_PTR (Node);
17367754Smsmith}
17467754Smsmith
17567754Smsmith
17667754Smsmith/*******************************************************************************
17767754Smsmith *
17867754Smsmith * FUNCTION:    AcpiNsDeleteNode
17967754Smsmith *
18083174Smsmith * PARAMETERS:  Node            - Node to be deleted
18167754Smsmith *
18267754Smsmith * RETURN:      None
18367754Smsmith *
184197104Sjkim * DESCRIPTION: Delete a namespace node. All node deletions must come through
185197104Sjkim *              here. Detaches any attached objects, including any attached
186197104Sjkim *              data. If a handler is associated with attached data, it is
187197104Sjkim *              invoked before the node is deleted.
18867754Smsmith *
18967754Smsmith ******************************************************************************/
19067754Smsmith
19167754Smsmithvoid
19267754SmsmithAcpiNsDeleteNode (
19367754Smsmith    ACPI_NAMESPACE_NODE     *Node)
19467754Smsmith{
195197104Sjkim    ACPI_OPERAND_OBJECT     *ObjDesc;
196197104Sjkim
197197104Sjkim
198197104Sjkim    ACPI_FUNCTION_NAME (NsDeleteNode);
199197104Sjkim
200197104Sjkim
201197104Sjkim    /* Detach an object if there is one */
202197104Sjkim
203197104Sjkim    AcpiNsDetachObject (Node);
204197104Sjkim
205197104Sjkim    /*
206197104Sjkim     * Delete an attached data object if present (an object that was created
207197104Sjkim     * and attached via AcpiAttachData). Note: After any normal object is
208197104Sjkim     * detached above, the only possible remaining object is a data object.
209197104Sjkim     */
210197104Sjkim    ObjDesc = Node->Object;
211197104Sjkim    if (ObjDesc &&
212197104Sjkim        (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_DATA))
213197104Sjkim    {
214197104Sjkim        /* Invoke the attached data deletion handler if present */
215197104Sjkim
216197104Sjkim        if (ObjDesc->Data.Handler)
217197104Sjkim        {
218197104Sjkim            ObjDesc->Data.Handler (Node, ObjDesc->Data.Pointer);
219197104Sjkim        }
220197104Sjkim
221197104Sjkim        AcpiUtRemoveReference (ObjDesc);
222197104Sjkim    }
223197104Sjkim
224197104Sjkim    /* Now we can delete the node */
225197104Sjkim
226197104Sjkim    (void) AcpiOsReleaseObject (AcpiGbl_NamespaceCache, Node);
227197104Sjkim
228197104Sjkim    ACPI_MEM_TRACKING (AcpiGbl_NsNodeList->TotalFreed++);
229197104Sjkim    ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n",
230197104Sjkim        Node, AcpiGbl_CurrentNodeCount));
231197104Sjkim}
232197104Sjkim
233197104Sjkim
234197104Sjkim/*******************************************************************************
235197104Sjkim *
236197104Sjkim * FUNCTION:    AcpiNsRemoveNode
237197104Sjkim *
238197104Sjkim * PARAMETERS:  Node            - Node to be removed/deleted
239197104Sjkim *
240197104Sjkim * RETURN:      None
241197104Sjkim *
242197104Sjkim * DESCRIPTION: Remove (unlink) and delete a namespace node
243197104Sjkim *
244197104Sjkim ******************************************************************************/
245197104Sjkim
246197104Sjkimvoid
247197104SjkimAcpiNsRemoveNode (
248197104Sjkim    ACPI_NAMESPACE_NODE     *Node)
249197104Sjkim{
25067754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode;
25167754Smsmith    ACPI_NAMESPACE_NODE     *PrevNode;
25267754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
25367754Smsmith
25467754Smsmith
255197104Sjkim    ACPI_FUNCTION_TRACE_PTR (NsRemoveNode, Node);
25667754Smsmith
25783174Smsmith
258209746Sjkim    ParentNode = Node->Parent;
25967754Smsmith
26067754Smsmith    PrevNode = NULL;
26167754Smsmith    NextNode = ParentNode->Child;
26267754Smsmith
263115351Snjl    /* Find the node that is the previous peer in the parent's child list */
264115351Snjl
26567754Smsmith    while (NextNode != Node)
26667754Smsmith    {
26767754Smsmith        PrevNode = NextNode;
268209746Sjkim        NextNode = NextNode->Peer;
26967754Smsmith    }
27067754Smsmith
27167754Smsmith    if (PrevNode)
27267754Smsmith    {
273115351Snjl        /* Node is not first child, unlink it */
274115351Snjl
275209746Sjkim        PrevNode->Peer = Node->Peer;
27667754Smsmith    }
27767754Smsmith    else
27867754Smsmith    {
279209746Sjkim        /*
280209746Sjkim         * Node is first child (has no previous peer).
281209746Sjkim         * Link peer list to parent
282209746Sjkim         */
283209746Sjkim        ParentNode->Child = Node->Peer;
28467754Smsmith    }
28567754Smsmith
286197104Sjkim    /* Delete the node and any attached objects */
28767754Smsmith
288197104Sjkim    AcpiNsDeleteNode (Node);
28967754Smsmith    return_VOID;
29067754Smsmith}
29167754Smsmith
29267754Smsmith
29367754Smsmith/*******************************************************************************
29467754Smsmith *
29567754Smsmith * FUNCTION:    AcpiNsInstallNode
29667754Smsmith *
29767754Smsmith * PARAMETERS:  WalkState       - Current state of the walk
29867754Smsmith *              ParentNode      - The parent of the new Node
29983174Smsmith *              Node            - The new Node to install
30067754Smsmith *              Type            - ACPI object type of the new Node
30167754Smsmith *
30267754Smsmith * RETURN:      None
30367754Smsmith *
30487031Smsmith * DESCRIPTION: Initialize a new namespace node and install it amongst
30587031Smsmith *              its peers.
30667754Smsmith *
307151937Sjkim *              Note: Current namespace lookup is linear search. This appears
308151937Sjkim *              to be sufficient as namespace searches consume only a small
309151937Sjkim *              fraction of the execution time of the ACPI subsystem.
31087031Smsmith *
31167754Smsmith ******************************************************************************/
31267754Smsmith
31367754Smsmithvoid
31467754SmsmithAcpiNsInstallNode (
31567754Smsmith    ACPI_WALK_STATE         *WalkState,
31667754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
31783174Smsmith    ACPI_NAMESPACE_NODE     *Node,          /* New Child*/
31891116Smsmith    ACPI_OBJECT_TYPE        Type)
31967754Smsmith{
320151937Sjkim    ACPI_OWNER_ID           OwnerId = 0;
32167754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
32267754Smsmith
32367754Smsmith
324167802Sjkim    ACPI_FUNCTION_TRACE (NsInstallNode);
32567754Smsmith
32667754Smsmith
32767754Smsmith    if (WalkState)
32867754Smsmith    {
329209746Sjkim        /*
330209746Sjkim         * Get the owner ID from the Walk state. The owner ID is used to
331209746Sjkim         * track table deletion and deletion of objects created by methods.
332209746Sjkim         */
33367754Smsmith        OwnerId = WalkState->OwnerId;
334209746Sjkim
335209746Sjkim        if ((WalkState->MethodDesc) &&
336209746Sjkim            (ParentNode != WalkState->MethodNode))
337209746Sjkim        {
338209746Sjkim            /*
339209746Sjkim             * A method is creating a new node that is not a child of the
340209746Sjkim             * method (it is non-local). Mark the executing method as having
341209746Sjkim             * modified the namespace. This is used for cleanup when the
342209746Sjkim             * method exits.
343209746Sjkim             */
344209746Sjkim            WalkState->MethodDesc->Method.Flags |= AOPOBJ_MODIFIED_NAMESPACE;
345209746Sjkim        }
34667754Smsmith    }
34767754Smsmith
34887031Smsmith    /* Link the new entry into the parent and existing children */
34967754Smsmith
350209746Sjkim    Node->Peer = NULL;
351209746Sjkim    Node->Parent = ParentNode;
35267754Smsmith    ChildNode = ParentNode->Child;
353209746Sjkim
35467754Smsmith    if (!ChildNode)
35567754Smsmith    {
35667754Smsmith        ParentNode->Child = Node;
35767754Smsmith    }
35867754Smsmith    else
35967754Smsmith    {
360209746Sjkim        /* Add node to the end of the peer list */
361209746Sjkim
362209746Sjkim        while (ChildNode->Peer)
36367754Smsmith        {
36467754Smsmith            ChildNode = ChildNode->Peer;
36567754Smsmith        }
36667754Smsmith
36767754Smsmith        ChildNode->Peer = Node;
36867754Smsmith    }
36967754Smsmith
37067754Smsmith    /* Init the new entry */
37167754Smsmith
372107325Siwasaki    Node->OwnerId = OwnerId;
373107325Siwasaki    Node->Type = (UINT8) Type;
37467754Smsmith
375129684Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
376127175Snjl        "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
377127175Snjl        AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId,
378123315Snjl        AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type),
379127175Snjl        ParentNode));
38067754Smsmith
38167754Smsmith    return_VOID;
38267754Smsmith}
38367754Smsmith
38467754Smsmith
38567754Smsmith/*******************************************************************************
38667754Smsmith *
38767754Smsmith * FUNCTION:    AcpiNsDeleteChildren
38867754Smsmith *
38967754Smsmith * PARAMETERS:  ParentNode      - Delete this objects children
39067754Smsmith *
39167754Smsmith * RETURN:      None.
39267754Smsmith *
39391116Smsmith * DESCRIPTION: Delete all children of the parent object. In other words,
39491116Smsmith *              deletes a "scope".
39567754Smsmith *
39667754Smsmith ******************************************************************************/
39767754Smsmith
39867754Smsmithvoid
39967754SmsmithAcpiNsDeleteChildren (
40067754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
40167754Smsmith{
40267754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
403209746Sjkim    ACPI_NAMESPACE_NODE     *NodeToDelete;
40467754Smsmith
40567754Smsmith
406167802Sjkim    ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode);
40767754Smsmith
40867754Smsmith
40967754Smsmith    if (!ParentNode)
41067754Smsmith    {
41167754Smsmith        return_VOID;
41267754Smsmith    }
41367754Smsmith
414193267Sjkim    /* Deallocate all children at this level */
415193267Sjkim
416209746Sjkim    NextNode = ParentNode->Child;
417209746Sjkim    while (NextNode)
41867754Smsmith    {
41967754Smsmith        /* Grandchildren should have all been deleted already */
42067754Smsmith
421209746Sjkim        if (NextNode->Child)
42267754Smsmith        {
423167802Sjkim            ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p",
424209746Sjkim                ParentNode, NextNode));
42567754Smsmith        }
42667754Smsmith
427197104Sjkim        /*
428197104Sjkim         * Delete this child node and move on to the next child in the list.
429197104Sjkim         * No need to unlink the node since we are deleting the entire branch.
430197104Sjkim         */
431209746Sjkim        NodeToDelete = NextNode;
432209746Sjkim        NextNode = NextNode->Peer;
433209746Sjkim        AcpiNsDeleteNode (NodeToDelete);
434209746Sjkim    };
43567754Smsmith
43667754Smsmith    /* Clear the parent's child pointer */
43767754Smsmith
43867754Smsmith    ParentNode->Child = NULL;
43967754Smsmith    return_VOID;
44067754Smsmith}
44167754Smsmith
44267754Smsmith
44367754Smsmith/*******************************************************************************
44467754Smsmith *
44567754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceSubtree
44667754Smsmith *
44783174Smsmith * PARAMETERS:  ParentNode      - Root of the subtree to be deleted
44867754Smsmith *
44967754Smsmith * RETURN:      None.
45067754Smsmith *
45167754Smsmith * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
45291116Smsmith *              stored within the subtree.
45367754Smsmith *
45467754Smsmith ******************************************************************************/
45567754Smsmith
45699679Siwasakivoid
45767754SmsmithAcpiNsDeleteNamespaceSubtree (
45867754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
45967754Smsmith{
46084491Smsmith    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
46184491Smsmith    UINT32                  Level = 1;
46267754Smsmith
46367754Smsmith
464167802Sjkim    ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree);
46567754Smsmith
46667754Smsmith
46767754Smsmith    if (!ParentNode)
46867754Smsmith    {
46999679Siwasaki        return_VOID;
47067754Smsmith    }
47167754Smsmith
47267754Smsmith    /*
47367754Smsmith     * Traverse the tree of objects until we bubble back up
47467754Smsmith     * to where we started.
47567754Smsmith     */
47667754Smsmith    while (Level > 0)
47767754Smsmith    {
47885756Smsmith        /* Get the next node in this scope (NULL if none) */
47985756Smsmith
480193267Sjkim        ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
48167754Smsmith        if (ChildNode)
48267754Smsmith        {
48385756Smsmith            /* Found a child node - detach any attached object */
48467754Smsmith
48585756Smsmith            AcpiNsDetachObject (ChildNode);
48667754Smsmith
48785756Smsmith            /* Check if this node has any children */
48867754Smsmith
489193267Sjkim            if (ChildNode->Child)
49067754Smsmith            {
49167754Smsmith                /*
49285756Smsmith                 * There is at least one child of this node,
49385756Smsmith                 * visit the node
49467754Smsmith                 */
49567754Smsmith                Level++;
496138287Smarks                ParentNode = ChildNode;
497138287Smarks                ChildNode  = NULL;
49867754Smsmith            }
49967754Smsmith        }
50067754Smsmith        else
50167754Smsmith        {
50267754Smsmith            /*
50385756Smsmith             * No more children of this parent node.
50485756Smsmith             * Move up to the grandparent.
50567754Smsmith             */
50667754Smsmith            Level--;
50767754Smsmith
50867754Smsmith            /*
50967754Smsmith             * Now delete all of the children of this parent
51067754Smsmith             * all at the same time.
51167754Smsmith             */
51267754Smsmith            AcpiNsDeleteChildren (ParentNode);
51367754Smsmith
51485756Smsmith            /* New "last child" is this parent node */
51567754Smsmith
51667754Smsmith            ChildNode = ParentNode;
51767754Smsmith
51885756Smsmith            /* Move up the tree to the grandparent */
51967754Smsmith
520209746Sjkim            ParentNode = ParentNode->Parent;
52167754Smsmith        }
52267754Smsmith    }
52367754Smsmith
52499679Siwasaki    return_VOID;
52567754Smsmith}
52667754Smsmith
52767754Smsmith
52867754Smsmith/*******************************************************************************
52967754Smsmith *
53067754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceByOwner
53167754Smsmith *
53283174Smsmith * PARAMETERS:  OwnerId     - All nodes with this owner will be deleted
53367754Smsmith *
53483174Smsmith * RETURN:      Status
53567754Smsmith *
53667754Smsmith * DESCRIPTION: Delete entries within the namespace that are owned by a
53767754Smsmith *              specific ID.  Used to delete entire ACPI tables.  All
53867754Smsmith *              reference counts are updated.
53967754Smsmith *
540167802Sjkim * MUTEX:       Locks namespace during deletion walk.
541167802Sjkim *
54267754Smsmith ******************************************************************************/
54367754Smsmith
54499679Siwasakivoid
54567754SmsmithAcpiNsDeleteNamespaceByOwner (
546151937Sjkim    ACPI_OWNER_ID            OwnerId)
54767754Smsmith{
54867754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
54991116Smsmith    ACPI_NAMESPACE_NODE     *DeletionNode;
550167802Sjkim    ACPI_NAMESPACE_NODE     *ParentNode;
55167754Smsmith    UINT32                  Level;
552167802Sjkim    ACPI_STATUS             Status;
55367754Smsmith
55467754Smsmith
555167802Sjkim    ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId);
55667754Smsmith
55767754Smsmith
558151937Sjkim    if (OwnerId == 0)
559151937Sjkim    {
560151937Sjkim        return_VOID;
561151937Sjkim    }
562151937Sjkim
563167802Sjkim    /* Lock namespace for possible update */
56467754Smsmith
565167802Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
566167802Sjkim    if (ACPI_FAILURE (Status))
567167802Sjkim    {
568167802Sjkim        return_VOID;
569167802Sjkim    }
570167802Sjkim
571167802Sjkim    DeletionNode = NULL;
572167802Sjkim    ParentNode = AcpiGbl_RootNode;
573167802Sjkim    ChildNode = NULL;
574167802Sjkim    Level = 1;
575167802Sjkim
57667754Smsmith    /*
57785756Smsmith     * Traverse the tree of nodes until we bubble back up
57867754Smsmith     * to where we started.
57967754Smsmith     */
58067754Smsmith    while (Level > 0)
58167754Smsmith    {
58291116Smsmith        /*
58391116Smsmith         * Get the next child of this parent node. When ChildNode is NULL,
58491116Smsmith         * the first child of the parent is returned
58591116Smsmith         */
586193267Sjkim        ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
58785756Smsmith
58891116Smsmith        if (DeletionNode)
58991116Smsmith        {
590167802Sjkim            AcpiNsDeleteChildren (DeletionNode);
591197104Sjkim            AcpiNsRemoveNode (DeletionNode);
59291116Smsmith            DeletionNode = NULL;
59391116Smsmith        }
59491116Smsmith
59567754Smsmith        if (ChildNode)
59667754Smsmith        {
59767754Smsmith            if (ChildNode->OwnerId == OwnerId)
59867754Smsmith            {
59991116Smsmith                /* Found a matching child node - detach any attached object */
60085756Smsmith
60185756Smsmith                AcpiNsDetachObject (ChildNode);
60267754Smsmith            }
60367754Smsmith
60485756Smsmith            /* Check if this node has any children */
60567754Smsmith
606193267Sjkim            if (ChildNode->Child)
60767754Smsmith            {
60867754Smsmith                /*
60985756Smsmith                 * There is at least one child of this node,
61085756Smsmith                 * visit the node
61167754Smsmith                 */
61267754Smsmith                Level++;
613138287Smarks                ParentNode = ChildNode;
614138287Smarks                ChildNode  = NULL;
61567754Smsmith            }
61667754Smsmith            else if (ChildNode->OwnerId == OwnerId)
61767754Smsmith            {
61891116Smsmith                DeletionNode = ChildNode;
61967754Smsmith            }
62067754Smsmith        }
62167754Smsmith        else
62267754Smsmith        {
62367754Smsmith            /*
62485756Smsmith             * No more children of this parent node.
62585756Smsmith             * Move up to the grandparent.
62667754Smsmith             */
62767754Smsmith            Level--;
62867754Smsmith            if (Level != 0)
62967754Smsmith            {
63067754Smsmith                if (ParentNode->OwnerId == OwnerId)
63167754Smsmith                {
63291116Smsmith                    DeletionNode = ParentNode;
63367754Smsmith                }
63467754Smsmith            }
63567754Smsmith
63685756Smsmith            /* New "last child" is this parent node */
63767754Smsmith
63867754Smsmith            ChildNode = ParentNode;
63967754Smsmith
64085756Smsmith            /* Move up the tree to the grandparent */
64167754Smsmith
642209746Sjkim            ParentNode = ParentNode->Parent;
64367754Smsmith        }
64467754Smsmith    }
64567754Smsmith
646167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
64799679Siwasaki    return_VOID;
64867754Smsmith}
64967754Smsmith
65067754Smsmith
651