nsalloc.c revision 99679
1193323Sed/*******************************************************************************
2193323Sed *
3193323Sed * Module Name: nsalloc - Namespace allocation and deletion utilities
4193323Sed *              $Revision: 74 $
5193323Sed *
6193323Sed ******************************************************************************/
7193323Sed
8193323Sed/******************************************************************************
9193323Sed *
10193323Sed * 1. Copyright Notice
11193323Sed *
12193323Sed * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
13193323Sed * All rights reserved.
14193323Sed *
15193323Sed * 2. License
16249423Sdim *
17249423Sdim * 2.1. This is your license from Intel Corp. under its intellectual property
18249423Sdim * rights.  You may have additional license terms from the party that provided
19249423Sdim * you this software, covering your right to use that party's intellectual
20288943Sdim * property rights.
21249423Sdim *
22276479Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23249423Sdim * copy of the source code appearing in this file ("Covered Code") an
24193323Sed * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25193323Sed * base code distributed originally by Intel ("Original Intel Code") to copy,
26193323Sed * make derivatives, distribute, use and display any portion of the Covered
27218885Sdim * Code in any form, with the right to sublicense such rights; and
28218885Sdim *
29249423Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30249423Sdim * license (with the right to sublicense), under only those claims of Intel
31249423Sdim * patents that are infringed by the Original Intel Code, to make, use, sell,
32249423Sdim * offer to sell, and import the Covered Code and derivative works thereof
33249423Sdim * solely to the minimum extent necessary to exercise the above copyright
34193323Sed * license, and in no event shall the patent license extend to any additions
35193323Sed * to or modifications of the Original Intel Code.  No other license or right
36193323Sed * is granted directly or by implication, estoppel or otherwise;
37276479Sdim *
38276479Sdim * The above copyright and patent license is granted only if the following
39193323Sed * conditions are met:
40193323Sed *
41198090Srdivacky * 3. Conditions
42193323Sed *
43193323Sed * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44193323Sed * Redistribution of source code of any substantial portion of the Covered
45193323Sed * Code or modification with rights to further distribute source must include
46193323Sed * the above Copyright Notice, the above License, this list of Conditions,
47193323Sed * and the following Disclaimer and Export Compliance provision.  In addition,
48193323Sed * Licensee must cause all Covered Code to which Licensee contributes to
49193323Sed * contain a file documenting the changes Licensee made to create that Covered
50193323Sed * Code and the date of any change.  Licensee must include in that file the
51193323Sed * documentation of any changes made by any predecessor Licensee.  Licensee
52234353Sdim * must include a prominent statement that the modification is derived,
53234353Sdim * directly or indirectly, from Original Intel Code.
54276479Sdim *
55234353Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56234353Sdim * Redistribution of source code of any substantial portion of the Covered
57234353Sdim * Code or modification without rights to further distribute source must
58234353Sdim * include the following Disclaimer and Export Compliance provision in the
59234353Sdim * documentation and/or other materials provided with distribution.  In
60234353Sdim * addition, Licensee may not authorize further sublicense of source of any
61234353Sdim * portion of the Covered Code, and must include terms to the effect that the
62234353Sdim * license from Licensee to its licensee is limited to the intellectual
63234353Sdim * property embodied in the software Licensee provides to its licensee, and
64234353Sdim * not to intellectual property embodied in modifications its licensee may
65234353Sdim * make.
66234353Sdim *
67234353Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any
68234353Sdim * substantial portion of the Covered Code or modification must reproduce the
69234353Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance
70234353Sdim * provision in the documentation and/or other materials provided with the
71234353Sdim * distribution.
72234353Sdim *
73234353Sdim * 3.4. Intel retains all right, title, and interest in and to the Original
74234353Sdim * Intel Code.
75234353Sdim *
76234353Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77234353Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or
78234353Sdim * other dealings in products derived from or relating to the Covered Code
79234353Sdim * without prior written authorization from Intel.
80234353Sdim *
81276479Sdim * 4. Disclaimer and Export Compliance
82234353Sdim *
83234353Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84234353Sdim * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85280031Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86280031Sdim * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87280031Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88212793Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89296417Sdim * PARTICULAR PURPOSE.
90193323Sed *
91193323Sed * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92193323Sed * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93193323Sed * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94212793Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95193323Sed * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96193323Sed * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97193323Sed * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98193323Sed * LIMITED REMEDY.
99193323Sed *
100193323Sed * 4.3. Licensee shall not export, either directly or indirectly, any of this
101193323Sed * software or system incorporating such software without first obtaining any
102193323Sed * required license or other approval from the U. S. Department of Commerce or
103296417Sdim * any other agency or department of the United States Government.  In the
104193323Sed * event Licensee exports any such software from the United States or
105193323Sed * re-exports any such software from a foreign destination, Licensee shall
106210006Srdivacky * ensure that the distribution and export/re-export of the software is in
107193323Sed * compliance with all laws, regulations, orders, or other restrictions of the
108193323Sed * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109193323Sed * any of its subsidiaries will export/re-export any technical data, process,
110193323Sed * software, or service, directly or indirectly, to any country for which the
111193323Sed * United States government or any agency thereof requires an export license,
112193323Sed * other governmental approval, or letter of assurance, without first obtaining
113212793Sdim * such license, approval or letter.
114193323Sed *
115212793Sdim *****************************************************************************/
116193323Sed
117212793Sdim
118193323Sed#define __NSALLOC_C__
119212793Sdim
120193323Sed#include "acpi.h"
121212793Sdim#include "acnamesp.h"
122280031Sdim
123212793Sdim
124212793Sdim#define _COMPONENT          ACPI_NAMESPACE
125212793Sdim        ACPI_MODULE_NAME    ("nsalloc")
126212793Sdim
127212793Sdim
128212793Sdim/*******************************************************************************
129193323Sed *
130193323Sed * FUNCTION:    AcpiNsCreateNode
131280031Sdim *
132280031Sdim * PARAMETERS:  AcpiName        - Name of the new node
133193323Sed *
134193323Sed * RETURN:      None
135193323Sed *
136193323Sed * DESCRIPTION: Create a namespace node
137212793Sdim *
138212793Sdim ******************************************************************************/
139193323Sed
140193323SedACPI_NAMESPACE_NODE *
141212793SdimAcpiNsCreateNode (
142193323Sed    UINT32                  Name)
143212793Sdim{
144193323Sed    ACPI_NAMESPACE_NODE     *Node;
145280031Sdim
146276479Sdim
147198090Srdivacky    ACPI_FUNCTION_TRACE ("NsCreateNode");
148280031Sdim
149193323Sed
150193323Sed    Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE));
151193323Sed    if (!Node)
152193323Sed    {
153193323Sed        return_PTR (NULL);
154280031Sdim    }
155212793Sdim
156212793Sdim    ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++);
157193323Sed
158280031Sdim    Node->Name.Integer   = Name;
159276479Sdim    Node->ReferenceCount = 1;
160198090Srdivacky    ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED);
161212793Sdim
162198090Srdivacky    return_PTR (Node);
163276479Sdim}
164193323Sed
165193323Sed
166193323Sed/*******************************************************************************
167193323Sed *
168193323Sed * FUNCTION:    AcpiNsDeleteNode
169193323Sed *
170193323Sed * PARAMETERS:  Node            - Node to be deleted
171276479Sdim *
172193323Sed * RETURN:      None
173193323Sed *
174193323Sed * DESCRIPTION: Delete a namespace node
175193323Sed *
176193323Sed ******************************************************************************/
177193323Sed
178193323Sedvoid
179193323SedAcpiNsDeleteNode (
180193323Sed    ACPI_NAMESPACE_NODE     *Node)
181193323Sed{
182296417Sdim    ACPI_NAMESPACE_NODE     *ParentNode;
183296417Sdim    ACPI_NAMESPACE_NODE     *PrevNode;
184296417Sdim    ACPI_NAMESPACE_NODE     *NextNode;
185296417Sdim
186296417Sdim
187296417Sdim    ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node);
188296417Sdim
189296417Sdim
190296417Sdim    ParentNode = AcpiNsGetParentNode (Node);
191296417Sdim
192296417Sdim    PrevNode = NULL;
193296417Sdim    NextNode = ParentNode->Child;
194296417Sdim
195296417Sdim    while (NextNode != Node)
196296417Sdim    {
197296417Sdim        PrevNode = NextNode;
198296417Sdim        NextNode = PrevNode->Peer;
199296417Sdim    }
200296417Sdim
201296417Sdim    if (PrevNode)
202296417Sdim    {
203193323Sed        PrevNode->Peer = NextNode->Peer;
204296417Sdim        if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST)
205296417Sdim        {
206296417Sdim            PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST;
207296417Sdim        }
208296417Sdim    }
209296417Sdim    else
210296417Sdim    {
211296417Sdim        ParentNode->Child = NextNode->Peer;
212296417Sdim    }
213193323Sed
214193323Sed
215193323Sed    ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++);
216193323Sed
217296417Sdim    /*
218296417Sdim     * Detach an object if there is one then delete the node
219193323Sed     */
220193323Sed    AcpiNsDetachObject (Node);
221193323Sed    ACPI_MEM_FREE (Node);
222193323Sed    return_VOID;
223193323Sed}
224193323Sed
225193323Sed
226193323Sed/*******************************************************************************
227193323Sed *
228193323Sed * FUNCTION:    AcpiNsInstallNode
229224133Sdim *
230288943Sdim * PARAMETERS:  WalkState       - Current state of the walk
231226584Sdim *              ParentNode      - The parent of the new Node
232288943Sdim *              Node            - The new Node to install
233193323Sed *              Type            - ACPI object type of the new Node
234224133Sdim *
235224133Sdim * RETURN:      None
236224133Sdim *
237224133Sdim * DESCRIPTION: Initialize a new namespace node and install it amongst
238224133Sdim *              its peers.
239193323Sed *
240193323Sed *              Note: Current namespace lookup is linear search, so the nodes
241193323Sed *              are not linked in any particular order.
242193323Sed *
243193323Sed ******************************************************************************/
244193323Sed
245193323Sedvoid
246193323SedAcpiNsInstallNode (
247193323Sed    ACPI_WALK_STATE         *WalkState,
248193323Sed    ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
249193323Sed    ACPI_NAMESPACE_NODE     *Node,          /* New Child*/
250218885Sdim    ACPI_OBJECT_TYPE        Type)
251193323Sed{
252193323Sed    UINT16                  OwnerId = TABLE_ID_DSDT;
253193323Sed    ACPI_NAMESPACE_NODE     *ChildNode;
254193323Sed
255193323Sed
256193323Sed    ACPI_FUNCTION_TRACE ("NsInstallNode");
257193323Sed
258193323Sed
259193323Sed    /*
260193323Sed     * Get the owner ID from the Walk state
261193323Sed     * The owner ID is used to track table deletion and
262193323Sed     * deletion of objects created by methods
263193323Sed     */
264193323Sed    if (WalkState)
265193323Sed    {
266193323Sed        OwnerId = WalkState->OwnerId;
267193323Sed    }
268193323Sed
269193323Sed    /* Link the new entry into the parent and existing children */
270193323Sed
271193323Sed    ChildNode = ParentNode->Child;
272193323Sed    if (!ChildNode)
273193323Sed    {
274193323Sed        ParentNode->Child = Node;
275193323Sed    }
276193323Sed    else
277193323Sed    {
278210006Srdivacky        while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST))
279193323Sed        {
280193323Sed            ChildNode = ChildNode->Peer;
281193323Sed        }
282193323Sed
283193323Sed        ChildNode->Peer = Node;
284193323Sed
285193323Sed        /* Clear end-of-list flag */
286193323Sed
287193323Sed        ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST;
288198090Srdivacky    }
289198090Srdivacky
290198090Srdivacky    /* Init the new entry */
291193323Sed
292193323Sed    Node->OwnerId   = OwnerId;
293193323Sed    Node->Flags     |= ANOBJ_END_OF_PEER_LIST;
294193323Sed    Node->Peer      = ParentNode;
295193323Sed
296193323Sed
297193323Sed    /*
298193323Sed     * If adding a name with unknown type, or having to
299193323Sed     * add the region in order to define fields in it, we
300198090Srdivacky     * have a forward reference.
301198090Srdivacky     */
302198090Srdivacky    if ((ACPI_TYPE_ANY == Type) ||
303193323Sed        (INTERNAL_TYPE_FIELD_DEFN == Type) ||
304193323Sed        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
305193323Sed    {
306296417Sdim        /*
307296417Sdim         * We don't want to abort here, however!
308218885Sdim         * We will fill in the actual type when the
309193323Sed         * real definition is found later.
310193323Sed         */
311193323Sed        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] is a forward reference\n",
312193323Sed            Node->Name.Ascii));
313193323Sed    }
314193323Sed
315198090Srdivacky    /*
316198090Srdivacky     * The DefFieldDefn and BankFieldDefn cases are actually
317193323Sed     * looking up the Region in which the field will be defined
318193323Sed     */
319193323Sed    if ((INTERNAL_TYPE_FIELD_DEFN == Type) ||
320218885Sdim        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
321296417Sdim    {
322193323Sed        Type = ACPI_TYPE_REGION;
323193323Sed    }
324193323Sed
325193323Sed    /*
326210006Srdivacky     * Scope, DefAny, and IndexFieldDefn are bogus "types" which do
327198090Srdivacky     * not actually have anything to do with the type of the name
328276479Sdim     * being looked up.  Save any other value of Type as the type of
329198090Srdivacky     * the entry.
330210006Srdivacky     */
331193323Sed    if ((Type != INTERNAL_TYPE_SCOPE) &&
332193323Sed        (Type != INTERNAL_TYPE_DEF_ANY) &&
333193323Sed        (Type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
334193323Sed    {
335193323Sed        Node->Type = (UINT8) Type;
336296417Sdim    }
337296417Sdim
338296417Sdim    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s added to %p at %p\n",
339193323Sed        Node->Name.Ascii, ParentNode, Node));
340234353Sdim
341296417Sdim    /*
342296417Sdim     * Increment the reference count(s) of all parents up to
343296417Sdim     * the root!
344234353Sdim     */
345234353Sdim    while ((Node = AcpiNsGetParentNode (Node)) != NULL)
346234353Sdim    {
347276479Sdim        Node->ReferenceCount++;
348234353Sdim    }
349234353Sdim
350234353Sdim    return_VOID;
351234353Sdim}
352234353Sdim
353296417Sdim
354234353Sdim/*******************************************************************************
355234353Sdim *
356296417Sdim * FUNCTION:    AcpiNsDeleteChildren
357234353Sdim *
358234353Sdim * PARAMETERS:  ParentNode      - Delete this objects children
359234353Sdim *
360193323Sed * RETURN:      None.
361193323Sed *
362296417Sdim * DESCRIPTION: Delete all children of the parent object. In other words,
363296417Sdim *              deletes a "scope".
364296417Sdim *
365193323Sed ******************************************************************************/
366193323Sed
367193323Sedvoid
368193323SedAcpiNsDeleteChildren (
369193323Sed    ACPI_NAMESPACE_NODE     *ParentNode)
370193323Sed{
371193323Sed    ACPI_NAMESPACE_NODE     *ChildNode;
372280031Sdim    ACPI_NAMESPACE_NODE     *NextNode;
373280031Sdim    UINT8                   Flags;
374280031Sdim
375261991Sdim
376261991Sdim    ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode);
377276479Sdim
378261991Sdim
379261991Sdim    if (!ParentNode)
380198090Srdivacky    {
381261991Sdim        return_VOID;
382212793Sdim    }
383276479Sdim
384193323Sed    /* If no children, all done! */
385261991Sdim
386193323Sed    ChildNode = ParentNode->Child;
387261991Sdim    if (!ChildNode)
388193323Sed    {
389193323Sed        return_VOID;
390193323Sed    }
391193323Sed
392193323Sed    /*
393193323Sed     * Deallocate all children at this level
394234353Sdim     */
395212793Sdim    do
396193323Sed    {
397212793Sdim        /* Get the things we need */
398212793Sdim
399261991Sdim        NextNode    = ChildNode->Peer;
400212793Sdim        Flags       = ChildNode->Flags;
401212793Sdim
402276479Sdim        /* Grandchildren should have all been deleted already */
403212793Sdim
404212793Sdim        if (ChildNode->Child)
405193323Sed        {
406261991Sdim            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n",
407261991Sdim                ParentNode, ChildNode));
408203954Srdivacky        }
409193323Sed
410212793Sdim        /* Now we can free this child object */
411212793Sdim
412280031Sdim        ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++);
413193323Sed
414261991Sdim        ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n",
415193323Sed            ChildNode, AcpiGbl_CurrentNodeCount));
416276479Sdim
417198090Srdivacky        /*
418212793Sdim         * Detach an object if there is one, then free the child node
419193323Sed         */
420193323Sed        AcpiNsDetachObject (ChildNode);
421193323Sed        ACPI_MEM_FREE (ChildNode);
422
423        /* And move on to the next child in the list */
424
425        ChildNode = NextNode;
426
427    } while (!(Flags & ANOBJ_END_OF_PEER_LIST));
428
429
430    /* Clear the parent's child pointer */
431
432    ParentNode->Child = NULL;
433
434    return_VOID;
435}
436
437
438/*******************************************************************************
439 *
440 * FUNCTION:    AcpiNsDeleteNamespaceSubtree
441 *
442 * PARAMETERS:  ParentNode      - Root of the subtree to be deleted
443 *
444 * RETURN:      None.
445 *
446 * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
447 *              stored within the subtree.
448 *
449 ******************************************************************************/
450
451void
452AcpiNsDeleteNamespaceSubtree (
453    ACPI_NAMESPACE_NODE     *ParentNode)
454{
455    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
456    UINT32                  Level = 1;
457
458
459    ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree");
460
461
462    if (!ParentNode)
463    {
464        return_VOID;
465    }
466
467    /*
468     * Traverse the tree of objects until we bubble back up
469     * to where we started.
470     */
471    while (Level > 0)
472    {
473        /* Get the next node in this scope (NULL if none) */
474
475        ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode,
476                                            ChildNode);
477        if (ChildNode)
478        {
479            /* Found a child node - detach any attached object */
480
481            AcpiNsDetachObject (ChildNode);
482
483            /* Check if this node has any children */
484
485            if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0))
486            {
487                /*
488                 * There is at least one child of this node,
489                 * visit the node
490                 */
491                Level++;
492                ParentNode    = ChildNode;
493                ChildNode     = 0;
494            }
495        }
496        else
497        {
498            /*
499             * No more children of this parent node.
500             * Move up to the grandparent.
501             */
502            Level--;
503
504            /*
505             * Now delete all of the children of this parent
506             * all at the same time.
507             */
508            AcpiNsDeleteChildren (ParentNode);
509
510            /* New "last child" is this parent node */
511
512            ChildNode = ParentNode;
513
514            /* Move up the tree to the grandparent */
515
516            ParentNode = AcpiNsGetParentNode (ParentNode);
517        }
518    }
519
520    return_VOID;
521}
522
523
524/*******************************************************************************
525 *
526 * FUNCTION:    AcpiNsRemoveReference
527 *
528 * PARAMETERS:  Node           - Named node whose reference count is to be
529 *                               decremented
530 *
531 * RETURN:      None.
532 *
533 * DESCRIPTION: Remove a Node reference.  Decrements the reference count
534 *              of all parent Nodes up to the root.  Any node along
535 *              the way that reaches zero references is freed.
536 *
537 ******************************************************************************/
538
539static void
540AcpiNsRemoveReference (
541    ACPI_NAMESPACE_NODE     *Node)
542{
543    ACPI_NAMESPACE_NODE     *ParentNode;
544    ACPI_NAMESPACE_NODE     *ThisNode;
545
546
547    ACPI_FUNCTION_ENTRY ();
548
549
550    /*
551     * Decrement the reference count(s) of this node and all
552     * nodes up to the root,  Delete anything with zero remaining references.
553     */
554    ThisNode = Node;
555    while (ThisNode)
556    {
557        /* Prepare to move up to parent */
558
559        ParentNode = AcpiNsGetParentNode (ThisNode);
560
561        /* Decrement the reference count on this node */
562
563        ThisNode->ReferenceCount--;
564
565        /* Delete the node if no more references */
566
567        if (!ThisNode->ReferenceCount)
568        {
569            /* Delete all children and delete the node */
570
571            AcpiNsDeleteChildren (ThisNode);
572            AcpiNsDeleteNode (ThisNode);
573        }
574
575        ThisNode = ParentNode;
576    }
577}
578
579
580/*******************************************************************************
581 *
582 * FUNCTION:    AcpiNsDeleteNamespaceByOwner
583 *
584 * PARAMETERS:  OwnerId     - All nodes with this owner will be deleted
585 *
586 * RETURN:      Status
587 *
588 * DESCRIPTION: Delete entries within the namespace that are owned by a
589 *              specific ID.  Used to delete entire ACPI tables.  All
590 *              reference counts are updated.
591 *
592 ******************************************************************************/
593
594void
595AcpiNsDeleteNamespaceByOwner (
596    UINT16                  OwnerId)
597{
598    ACPI_NAMESPACE_NODE     *ChildNode;
599    ACPI_NAMESPACE_NODE     *DeletionNode;
600    UINT32                  Level;
601    ACPI_NAMESPACE_NODE     *ParentNode;
602
603
604    ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId);
605
606
607    ParentNode    = AcpiGbl_RootNode;
608    ChildNode     = NULL;
609    DeletionNode  = NULL;
610    Level         = 1;
611
612    /*
613     * Traverse the tree of nodes until we bubble back up
614     * to where we started.
615     */
616    while (Level > 0)
617    {
618        /*
619         * Get the next child of this parent node. When ChildNode is NULL,
620         * the first child of the parent is returned
621         */
622        ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode);
623
624        if (DeletionNode)
625        {
626            AcpiNsRemoveReference (DeletionNode);
627            DeletionNode = NULL;
628        }
629
630        if (ChildNode)
631        {
632            if (ChildNode->OwnerId == OwnerId)
633            {
634                /* Found a matching child node - detach any attached object */
635
636                AcpiNsDetachObject (ChildNode);
637            }
638
639            /* Check if this node has any children */
640
641            if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL))
642            {
643                /*
644                 * There is at least one child of this node,
645                 * visit the node
646                 */
647                Level++;
648                ParentNode    = ChildNode;
649                ChildNode     = NULL;
650            }
651            else if (ChildNode->OwnerId == OwnerId)
652            {
653                DeletionNode = ChildNode;
654            }
655        }
656        else
657        {
658            /*
659             * No more children of this parent node.
660             * Move up to the grandparent.
661             */
662            Level--;
663            if (Level != 0)
664            {
665                if (ParentNode->OwnerId == OwnerId)
666                {
667                    DeletionNode = ParentNode;
668                }
669            }
670
671            /* New "last child" is this parent node */
672
673            ChildNode = ParentNode;
674
675            /* Move up the tree to the grandparent */
676
677            ParentNode = AcpiNsGetParentNode (ParentNode);
678        }
679    }
680
681    return_VOID;
682}
683
684
685