nsalloc.c revision 197104
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: nsalloc - Namespace allocation and deletion utilities
467754Smsmith *
567754Smsmith ******************************************************************************/
667754Smsmith
767754Smsmith/******************************************************************************
867754Smsmith *
967754Smsmith * 1. Copyright Notice
1067754Smsmith *
11193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, 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
25891116Smsmith    ParentNode = AcpiNsGetParentNode (Node);
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;
26867754Smsmith        NextNode = PrevNode->Peer;
26967754Smsmith    }
27067754Smsmith
27167754Smsmith    if (PrevNode)
27267754Smsmith    {
273115351Snjl        /* Node is not first child, unlink it */
274115351Snjl
27567754Smsmith        PrevNode->Peer = NextNode->Peer;
27667754Smsmith        if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST)
27767754Smsmith        {
27867754Smsmith            PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST;
27967754Smsmith        }
28067754Smsmith    }
28167754Smsmith    else
28267754Smsmith    {
283115351Snjl        /* Node is first child (has no previous peer) */
284115351Snjl
285115351Snjl        if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST)
286115351Snjl        {
287115351Snjl            /* No peers at all */
288115351Snjl
289115351Snjl            ParentNode->Child = NULL;
290115351Snjl        }
291115351Snjl        else
292115351Snjl        {   /* Link peer list to parent */
293115351Snjl
294115351Snjl            ParentNode->Child = NextNode->Peer;
295115351Snjl        }
29667754Smsmith    }
29767754Smsmith
298197104Sjkim    /* Delete the node and any attached objects */
29967754Smsmith
300197104Sjkim    AcpiNsDeleteNode (Node);
30167754Smsmith    return_VOID;
30267754Smsmith}
30367754Smsmith
30467754Smsmith
30567754Smsmith/*******************************************************************************
30667754Smsmith *
30767754Smsmith * FUNCTION:    AcpiNsInstallNode
30867754Smsmith *
30967754Smsmith * PARAMETERS:  WalkState       - Current state of the walk
31067754Smsmith *              ParentNode      - The parent of the new Node
31183174Smsmith *              Node            - The new Node to install
31267754Smsmith *              Type            - ACPI object type of the new Node
31367754Smsmith *
31467754Smsmith * RETURN:      None
31567754Smsmith *
31687031Smsmith * DESCRIPTION: Initialize a new namespace node and install it amongst
31787031Smsmith *              its peers.
31867754Smsmith *
319151937Sjkim *              Note: Current namespace lookup is linear search. This appears
320151937Sjkim *              to be sufficient as namespace searches consume only a small
321151937Sjkim *              fraction of the execution time of the ACPI subsystem.
32287031Smsmith *
32367754Smsmith ******************************************************************************/
32467754Smsmith
32567754Smsmithvoid
32667754SmsmithAcpiNsInstallNode (
32767754Smsmith    ACPI_WALK_STATE         *WalkState,
32867754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
32983174Smsmith    ACPI_NAMESPACE_NODE     *Node,          /* New Child*/
33091116Smsmith    ACPI_OBJECT_TYPE        Type)
33167754Smsmith{
332151937Sjkim    ACPI_OWNER_ID           OwnerId = 0;
33367754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
33467754Smsmith
33567754Smsmith
336167802Sjkim    ACPI_FUNCTION_TRACE (NsInstallNode);
33767754Smsmith
33867754Smsmith
33967754Smsmith    /*
340193267Sjkim     * Get the owner ID from the Walk state. The owner ID is used to track
341193267Sjkim     * table deletion and deletion of objects created by methods.
34267754Smsmith     */
34367754Smsmith    if (WalkState)
34467754Smsmith    {
34567754Smsmith        OwnerId = WalkState->OwnerId;
34667754Smsmith    }
34767754Smsmith
34887031Smsmith    /* Link the new entry into the parent and existing children */
34967754Smsmith
35067754Smsmith    ChildNode = ParentNode->Child;
35167754Smsmith    if (!ChildNode)
35267754Smsmith    {
35367754Smsmith        ParentNode->Child = Node;
354107325Siwasaki        Node->Flags |= ANOBJ_END_OF_PEER_LIST;
355107325Siwasaki        Node->Peer = ParentNode;
35667754Smsmith    }
35767754Smsmith    else
35867754Smsmith    {
35967754Smsmith        while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST))
36067754Smsmith        {
36167754Smsmith            ChildNode = ChildNode->Peer;
36267754Smsmith        }
36367754Smsmith
36467754Smsmith        ChildNode->Peer = Node;
36567754Smsmith
36667754Smsmith        /* Clear end-of-list flag */
36767754Smsmith
36867754Smsmith        ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST;
369151937Sjkim        Node->Flags |= ANOBJ_END_OF_PEER_LIST;
370107325Siwasaki        Node->Peer = ParentNode;
37167754Smsmith    }
37267754Smsmith
37367754Smsmith    /* Init the new entry */
37467754Smsmith
375107325Siwasaki    Node->OwnerId = OwnerId;
376107325Siwasaki    Node->Type = (UINT8) Type;
37767754Smsmith
378129684Snjl    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
379127175Snjl        "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
380127175Snjl        AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId,
381123315Snjl        AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type),
382127175Snjl        ParentNode));
38367754Smsmith
38467754Smsmith    return_VOID;
38567754Smsmith}
38667754Smsmith
38767754Smsmith
38867754Smsmith/*******************************************************************************
38967754Smsmith *
39067754Smsmith * FUNCTION:    AcpiNsDeleteChildren
39167754Smsmith *
39267754Smsmith * PARAMETERS:  ParentNode      - Delete this objects children
39367754Smsmith *
39467754Smsmith * RETURN:      None.
39567754Smsmith *
39691116Smsmith * DESCRIPTION: Delete all children of the parent object. In other words,
39791116Smsmith *              deletes a "scope".
39867754Smsmith *
39967754Smsmith ******************************************************************************/
40067754Smsmith
40167754Smsmithvoid
40267754SmsmithAcpiNsDeleteChildren (
40367754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
40467754Smsmith{
40567754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
40667754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
40767754Smsmith    UINT8                   Flags;
40867754Smsmith
40967754Smsmith
410167802Sjkim    ACPI_FUNCTION_TRACE_PTR (NsDeleteChildren, ParentNode);
41167754Smsmith
41267754Smsmith
41367754Smsmith    if (!ParentNode)
41467754Smsmith    {
41567754Smsmith        return_VOID;
41667754Smsmith    }
41767754Smsmith
41867754Smsmith    /* If no children, all done! */
41967754Smsmith
42067754Smsmith    ChildNode = ParentNode->Child;
42167754Smsmith    if (!ChildNode)
42267754Smsmith    {
42367754Smsmith        return_VOID;
42467754Smsmith    }
42567754Smsmith
426193267Sjkim    /* Deallocate all children at this level */
427193267Sjkim
42867754Smsmith    do
42967754Smsmith    {
43067754Smsmith        /* Get the things we need */
43167754Smsmith
432167802Sjkim        NextNode = ChildNode->Peer;
433167802Sjkim        Flags = ChildNode->Flags;
43467754Smsmith
43567754Smsmith        /* Grandchildren should have all been deleted already */
43667754Smsmith
43767754Smsmith        if (ChildNode->Child)
43867754Smsmith        {
439167802Sjkim            ACPI_ERROR ((AE_INFO, "Found a grandchild! P=%p C=%p",
44067754Smsmith                ParentNode, ChildNode));
44167754Smsmith        }
44267754Smsmith
443197104Sjkim        /*
444197104Sjkim         * Delete this child node and move on to the next child in the list.
445197104Sjkim         * No need to unlink the node since we are deleting the entire branch.
446197104Sjkim         */
447197104Sjkim        AcpiNsDeleteNode (ChildNode);
44867754Smsmith        ChildNode = NextNode;
44967754Smsmith
45067754Smsmith    } while (!(Flags & ANOBJ_END_OF_PEER_LIST));
45167754Smsmith
45267754Smsmith    /* Clear the parent's child pointer */
45367754Smsmith
45467754Smsmith    ParentNode->Child = NULL;
45567754Smsmith    return_VOID;
45667754Smsmith}
45767754Smsmith
45867754Smsmith
45967754Smsmith/*******************************************************************************
46067754Smsmith *
46167754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceSubtree
46267754Smsmith *
46383174Smsmith * PARAMETERS:  ParentNode      - Root of the subtree to be deleted
46467754Smsmith *
46567754Smsmith * RETURN:      None.
46667754Smsmith *
46767754Smsmith * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
46891116Smsmith *              stored within the subtree.
46967754Smsmith *
47067754Smsmith ******************************************************************************/
47167754Smsmith
47299679Siwasakivoid
47367754SmsmithAcpiNsDeleteNamespaceSubtree (
47467754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
47567754Smsmith{
47684491Smsmith    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
47784491Smsmith    UINT32                  Level = 1;
47867754Smsmith
47967754Smsmith
480167802Sjkim    ACPI_FUNCTION_TRACE (NsDeleteNamespaceSubtree);
48167754Smsmith
48267754Smsmith
48367754Smsmith    if (!ParentNode)
48467754Smsmith    {
48599679Siwasaki        return_VOID;
48667754Smsmith    }
48767754Smsmith
48867754Smsmith    /*
48967754Smsmith     * Traverse the tree of objects until we bubble back up
49067754Smsmith     * to where we started.
49167754Smsmith     */
49267754Smsmith    while (Level > 0)
49367754Smsmith    {
49485756Smsmith        /* Get the next node in this scope (NULL if none) */
49585756Smsmith
496193267Sjkim        ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
49767754Smsmith        if (ChildNode)
49867754Smsmith        {
49985756Smsmith            /* Found a child node - detach any attached object */
50067754Smsmith
50185756Smsmith            AcpiNsDetachObject (ChildNode);
50267754Smsmith
50385756Smsmith            /* Check if this node has any children */
50467754Smsmith
505193267Sjkim            if (ChildNode->Child)
50667754Smsmith            {
50767754Smsmith                /*
50885756Smsmith                 * There is at least one child of this node,
50985756Smsmith                 * visit the node
51067754Smsmith                 */
51167754Smsmith                Level++;
512138287Smarks                ParentNode = ChildNode;
513138287Smarks                ChildNode  = NULL;
51467754Smsmith            }
51567754Smsmith        }
51667754Smsmith        else
51767754Smsmith        {
51867754Smsmith            /*
51985756Smsmith             * No more children of this parent node.
52085756Smsmith             * Move up to the grandparent.
52167754Smsmith             */
52267754Smsmith            Level--;
52367754Smsmith
52467754Smsmith            /*
52567754Smsmith             * Now delete all of the children of this parent
52667754Smsmith             * all at the same time.
52767754Smsmith             */
52867754Smsmith            AcpiNsDeleteChildren (ParentNode);
52967754Smsmith
53085756Smsmith            /* New "last child" is this parent node */
53167754Smsmith
53267754Smsmith            ChildNode = ParentNode;
53367754Smsmith
53485756Smsmith            /* Move up the tree to the grandparent */
53567754Smsmith
53691116Smsmith            ParentNode = AcpiNsGetParentNode (ParentNode);
53767754Smsmith        }
53867754Smsmith    }
53967754Smsmith
54099679Siwasaki    return_VOID;
54167754Smsmith}
54267754Smsmith
54367754Smsmith
54467754Smsmith/*******************************************************************************
54567754Smsmith *
54667754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceByOwner
54767754Smsmith *
54883174Smsmith * PARAMETERS:  OwnerId     - All nodes with this owner will be deleted
54967754Smsmith *
55083174Smsmith * RETURN:      Status
55167754Smsmith *
55267754Smsmith * DESCRIPTION: Delete entries within the namespace that are owned by a
55367754Smsmith *              specific ID.  Used to delete entire ACPI tables.  All
55467754Smsmith *              reference counts are updated.
55567754Smsmith *
556167802Sjkim * MUTEX:       Locks namespace during deletion walk.
557167802Sjkim *
55867754Smsmith ******************************************************************************/
55967754Smsmith
56099679Siwasakivoid
56167754SmsmithAcpiNsDeleteNamespaceByOwner (
562151937Sjkim    ACPI_OWNER_ID            OwnerId)
56367754Smsmith{
56467754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
56591116Smsmith    ACPI_NAMESPACE_NODE     *DeletionNode;
566167802Sjkim    ACPI_NAMESPACE_NODE     *ParentNode;
56767754Smsmith    UINT32                  Level;
568167802Sjkim    ACPI_STATUS             Status;
56967754Smsmith
57067754Smsmith
571167802Sjkim    ACPI_FUNCTION_TRACE_U32 (NsDeleteNamespaceByOwner, OwnerId);
57267754Smsmith
57367754Smsmith
574151937Sjkim    if (OwnerId == 0)
575151937Sjkim    {
576151937Sjkim        return_VOID;
577151937Sjkim    }
578151937Sjkim
579167802Sjkim    /* Lock namespace for possible update */
58067754Smsmith
581167802Sjkim    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
582167802Sjkim    if (ACPI_FAILURE (Status))
583167802Sjkim    {
584167802Sjkim        return_VOID;
585167802Sjkim    }
586167802Sjkim
587167802Sjkim    DeletionNode = NULL;
588167802Sjkim    ParentNode = AcpiGbl_RootNode;
589167802Sjkim    ChildNode = NULL;
590167802Sjkim    Level = 1;
591167802Sjkim
59267754Smsmith    /*
59385756Smsmith     * Traverse the tree of nodes until we bubble back up
59467754Smsmith     * to where we started.
59567754Smsmith     */
59667754Smsmith    while (Level > 0)
59767754Smsmith    {
59891116Smsmith        /*
59991116Smsmith         * Get the next child of this parent node. When ChildNode is NULL,
60091116Smsmith         * the first child of the parent is returned
60191116Smsmith         */
602193267Sjkim        ChildNode = AcpiNsGetNextNode (ParentNode, ChildNode);
60385756Smsmith
60491116Smsmith        if (DeletionNode)
60591116Smsmith        {
606167802Sjkim            AcpiNsDeleteChildren (DeletionNode);
607197104Sjkim            AcpiNsRemoveNode (DeletionNode);
60891116Smsmith            DeletionNode = NULL;
60991116Smsmith        }
61091116Smsmith
61167754Smsmith        if (ChildNode)
61267754Smsmith        {
61367754Smsmith            if (ChildNode->OwnerId == OwnerId)
61467754Smsmith            {
61591116Smsmith                /* Found a matching child node - detach any attached object */
61685756Smsmith
61785756Smsmith                AcpiNsDetachObject (ChildNode);
61867754Smsmith            }
61967754Smsmith
62085756Smsmith            /* Check if this node has any children */
62167754Smsmith
622193267Sjkim            if (ChildNode->Child)
62367754Smsmith            {
62467754Smsmith                /*
62585756Smsmith                 * There is at least one child of this node,
62685756Smsmith                 * visit the node
62767754Smsmith                 */
62867754Smsmith                Level++;
629138287Smarks                ParentNode = ChildNode;
630138287Smarks                ChildNode  = NULL;
63167754Smsmith            }
63267754Smsmith            else if (ChildNode->OwnerId == OwnerId)
63367754Smsmith            {
63491116Smsmith                DeletionNode = ChildNode;
63567754Smsmith            }
63667754Smsmith        }
63767754Smsmith        else
63867754Smsmith        {
63967754Smsmith            /*
64085756Smsmith             * No more children of this parent node.
64185756Smsmith             * Move up to the grandparent.
64267754Smsmith             */
64367754Smsmith            Level--;
64467754Smsmith            if (Level != 0)
64567754Smsmith            {
64667754Smsmith                if (ParentNode->OwnerId == OwnerId)
64767754Smsmith                {
64891116Smsmith                    DeletionNode = ParentNode;
64967754Smsmith                }
65067754Smsmith            }
65167754Smsmith
65285756Smsmith            /* New "last child" is this parent node */
65367754Smsmith
65467754Smsmith            ChildNode = ParentNode;
65567754Smsmith
65685756Smsmith            /* Move up the tree to the grandparent */
65767754Smsmith
65891116Smsmith            ParentNode = AcpiNsGetParentNode (ParentNode);
65967754Smsmith        }
66067754Smsmith    }
66167754Smsmith
662167802Sjkim    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
66399679Siwasaki    return_VOID;
66467754Smsmith}
66567754Smsmith
66667754Smsmith
667