nsalloc.c revision 71867
167754Smsmith/*******************************************************************************
267754Smsmith *
367754Smsmith * Module Name: nsalloc - Namespace allocation and deletion utilities
471867Smsmith *              $Revision: 45 $
567754Smsmith *
667754Smsmith ******************************************************************************/
767754Smsmith
867754Smsmith/******************************************************************************
967754Smsmith *
1067754Smsmith * 1. Copyright Notice
1167754Smsmith *
1271867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
1370243Smsmith * All rights reserved.
1467754Smsmith *
1567754Smsmith * 2. License
1667754Smsmith *
1767754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
1867754Smsmith * rights.  You may have additional license terms from the party that provided
1967754Smsmith * you this software, covering your right to use that party's intellectual
2067754Smsmith * property rights.
2167754Smsmith *
2267754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2367754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2467754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2567754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2667754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2767754Smsmith * Code in any form, with the right to sublicense such rights; and
2867754Smsmith *
2967754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3067754Smsmith * license (with the right to sublicense), under only those claims of Intel
3167754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3267754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3367754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3467754Smsmith * license, and in no event shall the patent license extend to any additions
3567754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3667754Smsmith * is granted directly or by implication, estoppel or otherwise;
3767754Smsmith *
3867754Smsmith * The above copyright and patent license is granted only if the following
3967754Smsmith * conditions are met:
4067754Smsmith *
4167754Smsmith * 3. Conditions
4267754Smsmith *
4367754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4467754Smsmith * Redistribution of source code of any substantial portion of the Covered
4567754Smsmith * Code or modification with rights to further distribute source must include
4667754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4767754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
4867754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
4967754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5067754Smsmith * Code and the date of any change.  Licensee must include in that file the
5167754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5267754Smsmith * must include a prominent statement that the modification is derived,
5367754Smsmith * directly or indirectly, from Original Intel Code.
5467754Smsmith *
5567754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5667754Smsmith * Redistribution of source code of any substantial portion of the Covered
5767754Smsmith * Code or modification without rights to further distribute source must
5867754Smsmith * include the following Disclaimer and Export Compliance provision in the
5967754Smsmith * documentation and/or other materials provided with distribution.  In
6067754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6167754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6267754Smsmith * license from Licensee to its licensee is limited to the intellectual
6367754Smsmith * property embodied in the software Licensee provides to its licensee, and
6467754Smsmith * not to intellectual property embodied in modifications its licensee may
6567754Smsmith * make.
6667754Smsmith *
6767754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
6867754Smsmith * substantial portion of the Covered Code or modification must reproduce the
6967754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7067754Smsmith * provision in the documentation and/or other materials provided with the
7167754Smsmith * distribution.
7267754Smsmith *
7367754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7467754Smsmith * Intel Code.
7567754Smsmith *
7667754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7767754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
7867754Smsmith * other dealings in products derived from or relating to the Covered Code
7967754Smsmith * without prior written authorization from Intel.
8067754Smsmith *
8167754Smsmith * 4. Disclaimer and Export Compliance
8267754Smsmith *
8367754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8467754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8567754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8667754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8767754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8867754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
8967754Smsmith * PARTICULAR PURPOSE.
9067754Smsmith *
9167754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9267754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9367754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9467754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9567754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9667754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9767754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9867754Smsmith * LIMITED REMEDY.
9967754Smsmith *
10067754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10167754Smsmith * software or system incorporating such software without first obtaining any
10267754Smsmith * required license or other approval from the U. S. Department of Commerce or
10367754Smsmith * any other agency or department of the United States Government.  In the
10467754Smsmith * event Licensee exports any such software from the United States or
10567754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10667754Smsmith * ensure that the distribution and export/re-export of the software is in
10767754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
10867754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
10967754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11067754Smsmith * software, or service, directly or indirectly, to any country for which the
11167754Smsmith * United States government or any agency thereof requires an export license,
11267754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11367754Smsmith * such license, approval or letter.
11467754Smsmith *
11567754Smsmith *****************************************************************************/
11667754Smsmith
11767754Smsmith
11867754Smsmith#define __NSALLOC_C__
11967754Smsmith
12067754Smsmith#include "acpi.h"
12167754Smsmith#include "acnamesp.h"
12267754Smsmith#include "acinterp.h"
12367754Smsmith
12467754Smsmith
12567754Smsmith#define _COMPONENT          NAMESPACE
12667754Smsmith        MODULE_NAME         ("nsalloc")
12767754Smsmith
12867754Smsmith
12967754Smsmith/*******************************************************************************
13067754Smsmith *
13167754Smsmith * FUNCTION:    AcpiNsCreateNode
13267754Smsmith *
13367754Smsmith * PARAMETERS:
13467754Smsmith *
13567754Smsmith * RETURN:      None
13667754Smsmith *
13767754Smsmith * DESCRIPTION:
13867754Smsmith *
13967754Smsmith ******************************************************************************/
14067754Smsmith
14167754SmsmithACPI_NAMESPACE_NODE *
14267754SmsmithAcpiNsCreateNode (
14367754Smsmith    UINT32                  AcpiName)
14467754Smsmith{
14567754Smsmith    ACPI_NAMESPACE_NODE     *Node;
14667754Smsmith
14767754Smsmith    FUNCTION_TRACE ("NsCreateNode");
14867754Smsmith
14967754Smsmith
15067754Smsmith    Node = AcpiCmCallocate (sizeof (ACPI_NAMESPACE_NODE));
15167754Smsmith    if (!Node)
15267754Smsmith    {
15367754Smsmith        return_PTR (NULL);
15467754Smsmith    }
15567754Smsmith
15667754Smsmith    INCREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
15767754Smsmith
15867754Smsmith    Node->DataType       = ACPI_DESC_TYPE_NAMED;
15967754Smsmith    Node->Name           = AcpiName;
16067754Smsmith    Node->ReferenceCount = 1;
16167754Smsmith
16267754Smsmith    return_PTR (Node);
16367754Smsmith}
16467754Smsmith
16567754Smsmith
16667754Smsmith/*******************************************************************************
16767754Smsmith *
16867754Smsmith * FUNCTION:    AcpiNsDeleteNode
16967754Smsmith *
17067754Smsmith * PARAMETERS:
17167754Smsmith *
17267754Smsmith * RETURN:      None
17367754Smsmith *
17467754Smsmith * DESCRIPTION:
17567754Smsmith *
17667754Smsmith ******************************************************************************/
17767754Smsmith
17867754Smsmithvoid
17967754SmsmithAcpiNsDeleteNode (
18067754Smsmith    ACPI_NAMESPACE_NODE     *Node)
18167754Smsmith{
18267754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode;
18367754Smsmith    ACPI_NAMESPACE_NODE     *PrevNode;
18467754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
18567754Smsmith
18667754Smsmith
18767754Smsmith    FUNCTION_TRACE_PTR ("NsDeleteNode", Node);
18867754Smsmith
18967754Smsmith    ParentNode = AcpiNsGetParentObject (Node);
19067754Smsmith
19167754Smsmith    PrevNode = NULL;
19267754Smsmith    NextNode = ParentNode->Child;
19367754Smsmith
19467754Smsmith    while (NextNode != Node)
19567754Smsmith    {
19667754Smsmith        PrevNode = NextNode;
19767754Smsmith        NextNode = PrevNode->Peer;
19867754Smsmith    }
19967754Smsmith
20067754Smsmith    if (PrevNode)
20167754Smsmith    {
20267754Smsmith        PrevNode->Peer = NextNode->Peer;
20367754Smsmith        if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST)
20467754Smsmith        {
20567754Smsmith            PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST;
20667754Smsmith        }
20767754Smsmith    }
20867754Smsmith    else
20967754Smsmith    {
21067754Smsmith        ParentNode->Child = NextNode->Peer;
21167754Smsmith    }
21267754Smsmith
21367754Smsmith
21467754Smsmith    DECREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
21567754Smsmith
21667754Smsmith    /*
21767754Smsmith     * Detach an object if there is one
21867754Smsmith     */
21967754Smsmith
22067754Smsmith    if (Node->Object)
22167754Smsmith    {
22267754Smsmith        AcpiNsDetachObject (Node);
22367754Smsmith    }
22467754Smsmith
22567754Smsmith    AcpiCmFree (Node);
22667754Smsmith
22767754Smsmith
22867754Smsmith    return_VOID;
22967754Smsmith}
23067754Smsmith
23167754Smsmith
23267754Smsmith/*******************************************************************************
23367754Smsmith *
23467754Smsmith * FUNCTION:    AcpiNsInstallNode
23567754Smsmith *
23667754Smsmith * PARAMETERS:  WalkState       - Current state of the walk
23767754Smsmith *              ParentNode      - The parent of the new Node
23867754Smsmith *              Node        - The new Node to install
23967754Smsmith *              Type            - ACPI object type of the new Node
24067754Smsmith *
24167754Smsmith * RETURN:      None
24267754Smsmith *
24367754Smsmith * DESCRIPTION: Initialize a new entry within a namespace table.
24467754Smsmith *
24567754Smsmith ******************************************************************************/
24667754Smsmith
24767754Smsmithvoid
24867754SmsmithAcpiNsInstallNode (
24967754Smsmith    ACPI_WALK_STATE         *WalkState,
25067754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
25167754Smsmith    ACPI_NAMESPACE_NODE     *Node,      /* New Child*/
25267754Smsmith    OBJECT_TYPE_INTERNAL    Type)
25367754Smsmith{
25467754Smsmith    UINT16                  OwnerId = TABLE_ID_DSDT;
25567754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
25667754Smsmith
25767754Smsmith
25867754Smsmith    FUNCTION_TRACE ("NsInstallNode");
25967754Smsmith
26067754Smsmith
26167754Smsmith    /*
26267754Smsmith     * Get the owner ID from the Walk state
26367754Smsmith     * The owner ID is used to track table deletion and
26467754Smsmith     * deletion of objects created by methods
26567754Smsmith     */
26667754Smsmith    if (WalkState)
26767754Smsmith    {
26867754Smsmith        OwnerId = WalkState->OwnerId;
26967754Smsmith    }
27067754Smsmith
27167754Smsmith
27267754Smsmith    /* link the new entry into the parent and existing children */
27367754Smsmith
27467754Smsmith    /* TBD: Could be first, last, or alphabetic */
27567754Smsmith
27667754Smsmith    ChildNode = ParentNode->Child;
27767754Smsmith    if (!ChildNode)
27867754Smsmith    {
27967754Smsmith        ParentNode->Child = Node;
28067754Smsmith    }
28167754Smsmith
28267754Smsmith    else
28367754Smsmith    {
28467754Smsmith        while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST))
28567754Smsmith        {
28667754Smsmith            ChildNode = ChildNode->Peer;
28767754Smsmith        }
28867754Smsmith
28967754Smsmith        ChildNode->Peer = Node;
29067754Smsmith
29167754Smsmith        /* Clear end-of-list flag */
29267754Smsmith
29367754Smsmith        ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST;
29467754Smsmith    }
29567754Smsmith
29667754Smsmith    /* Init the new entry */
29767754Smsmith
29867754Smsmith    Node->OwnerId   = OwnerId;
29967754Smsmith    Node->Flags     |= ANOBJ_END_OF_PEER_LIST;
30067754Smsmith    Node->Peer      = ParentNode;
30167754Smsmith
30267754Smsmith
30367754Smsmith    /*
30467754Smsmith     * If adding a name with unknown type, or having to
30567754Smsmith     * add the region in order to define fields in it, we
30667754Smsmith     * have a forward reference.
30767754Smsmith     */
30867754Smsmith
30967754Smsmith    if ((ACPI_TYPE_ANY == Type) ||
31067754Smsmith        (INTERNAL_TYPE_DEF_FIELD_DEFN == Type) ||
31167754Smsmith        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
31267754Smsmith    {
31367754Smsmith        /*
31467754Smsmith         * We don't want to abort here, however!
31567754Smsmith         * We will fill in the actual type when the
31667754Smsmith         * real definition is found later.
31767754Smsmith         */
31867754Smsmith
31967754Smsmith        DEBUG_PRINT (ACPI_INFO,
32067754Smsmith            ("NsInstallNode: [%4.4s] is a forward reference\n",
32167754Smsmith            &Node->Name));
32267754Smsmith
32367754Smsmith    }
32467754Smsmith
32567754Smsmith    /*
32667754Smsmith     * The DefFieldDefn and BankFieldDefn cases are actually
32767754Smsmith     * looking up the Region in which the field will be defined
32867754Smsmith     */
32967754Smsmith
33067754Smsmith    if ((INTERNAL_TYPE_DEF_FIELD_DEFN == Type) ||
33167754Smsmith        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
33267754Smsmith    {
33367754Smsmith        Type = ACPI_TYPE_REGION;
33467754Smsmith    }
33567754Smsmith
33667754Smsmith    /*
33767754Smsmith     * Scope, DefAny, and IndexFieldDefn are bogus "types" which do
33867754Smsmith     * not actually have anything to do with the type of the name
33967754Smsmith     * being looked up.  Save any other value of Type as the type of
34067754Smsmith     * the entry.
34167754Smsmith     */
34267754Smsmith
34367754Smsmith    if ((Type != INTERNAL_TYPE_SCOPE) &&
34467754Smsmith        (Type != INTERNAL_TYPE_DEF_ANY) &&
34567754Smsmith        (Type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
34667754Smsmith    {
34767754Smsmith        Node->Type = (UINT8) Type;
34867754Smsmith    }
34967754Smsmith
35067754Smsmith    DEBUG_PRINT (TRACE_NAMES,
35167754Smsmith        ("NsInstallNode: %4.4s added to %p at %p\n",
35267754Smsmith        &Node->Name, ParentNode, Node));
35367754Smsmith
35467754Smsmith    /*
35567754Smsmith     * Increment the reference count(s) of all parents up to
35667754Smsmith     * the root!
35767754Smsmith     */
35867754Smsmith
35967754Smsmith    while ((Node = AcpiNsGetParentObject (Node)) != NULL)
36067754Smsmith    {
36167754Smsmith        Node->ReferenceCount++;
36267754Smsmith    }
36367754Smsmith
36467754Smsmith    return_VOID;
36567754Smsmith}
36667754Smsmith
36767754Smsmith
36867754Smsmith/*******************************************************************************
36967754Smsmith *
37067754Smsmith * FUNCTION:    AcpiNsDeleteChildren
37167754Smsmith *
37267754Smsmith * PARAMETERS:  ParentNode      - Delete this objects children
37367754Smsmith *
37467754Smsmith * RETURN:      None.
37567754Smsmith *
37667754Smsmith * DESCRIPTION: Delete all children of the parent object. Deletes a
37767754Smsmith *              "scope".
37867754Smsmith *
37967754Smsmith ******************************************************************************/
38067754Smsmith
38167754Smsmithvoid
38267754SmsmithAcpiNsDeleteChildren (
38367754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
38467754Smsmith{
38567754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
38667754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
38767754Smsmith    UINT8                   Flags;
38867754Smsmith
38967754Smsmith
39067754Smsmith    FUNCTION_TRACE_PTR ("AcpiNsDeleteChildren", ParentNode);
39167754Smsmith
39267754Smsmith
39367754Smsmith    if (!ParentNode)
39467754Smsmith    {
39567754Smsmith        return_VOID;
39667754Smsmith    }
39767754Smsmith
39867754Smsmith    /* If no children, all done! */
39967754Smsmith
40067754Smsmith    ChildNode = ParentNode->Child;
40167754Smsmith    if (!ChildNode)
40267754Smsmith    {
40367754Smsmith        return_VOID;
40467754Smsmith    }
40567754Smsmith
40667754Smsmith    /*
40767754Smsmith     * Deallocate all children at this level
40867754Smsmith     */
40967754Smsmith    do
41067754Smsmith    {
41167754Smsmith        /* Get the things we need */
41267754Smsmith
41367754Smsmith        NextNode    = ChildNode->Peer;
41467754Smsmith        Flags       = ChildNode->Flags;
41567754Smsmith
41667754Smsmith        /* Grandchildren should have all been deleted already */
41767754Smsmith
41867754Smsmith        if (ChildNode->Child)
41967754Smsmith        {
42067754Smsmith            DEBUG_PRINT (ACPI_ERROR,
42167754Smsmith                ("NsDeleteChildren: Found a grandchild! P=%X C=%X\n",
42267754Smsmith                ParentNode, ChildNode));
42367754Smsmith        }
42467754Smsmith
42567754Smsmith        /* Now we can free this child object */
42667754Smsmith
42767754Smsmith        DECREMENT_NAME_TABLE_METRICS (sizeof (ACPI_NAMESPACE_NODE));
42867754Smsmith
42967754Smsmith        DEBUG_PRINT (ACPI_INFO,
43069746Smsmith            ("AcpiNsDeleteChildren: Object %p, Remaining %X\n",
43167754Smsmith            ChildNode, AcpiGbl_CurrentNodeCount));
43267754Smsmith
43367754Smsmith        /*
43467754Smsmith         * Detach an object if there is one
43567754Smsmith         */
43667754Smsmith
43767754Smsmith        if (ChildNode->Object)
43867754Smsmith        {
43967754Smsmith            AcpiNsDetachObject (ChildNode);
44067754Smsmith        }
44167754Smsmith
44267754Smsmith        AcpiCmFree (ChildNode);
44367754Smsmith
44467754Smsmith        /* And move on to the next child in the list */
44567754Smsmith
44667754Smsmith        ChildNode = NextNode;
44767754Smsmith
44867754Smsmith    } while (!(Flags & ANOBJ_END_OF_PEER_LIST));
44967754Smsmith
45067754Smsmith
45167754Smsmith    /* Clear the parent's child pointer */
45267754Smsmith
45367754Smsmith    ParentNode->Child = NULL;
45467754Smsmith
45567754Smsmith    return_VOID;
45667754Smsmith}
45767754Smsmith
45867754Smsmith
45967754Smsmith/*******************************************************************************
46067754Smsmith *
46167754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceSubtree
46267754Smsmith *
46367754Smsmith * PARAMETERS:  None.
46467754Smsmith *
46567754Smsmith * RETURN:      None.
46667754Smsmith *
46767754Smsmith * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
46867754Smsmith *              stored within the subtree.  Scope tables are deleted also
46967754Smsmith *
47067754Smsmith ******************************************************************************/
47167754Smsmith
47267754SmsmithACPI_STATUS
47367754SmsmithAcpiNsDeleteNamespaceSubtree (
47467754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode)
47567754Smsmith{
47667754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
47767754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
47867754Smsmith    UINT32                  Level;
47967754Smsmith
48067754Smsmith
48167754Smsmith    FUNCTION_TRACE ("NsDeleteNamespaceSubtree");
48267754Smsmith
48367754Smsmith
48467754Smsmith    if (!ParentNode)
48567754Smsmith    {
48667754Smsmith        return_ACPI_STATUS (AE_OK);
48767754Smsmith    }
48867754Smsmith
48967754Smsmith
49067754Smsmith    ChildNode   = 0;
49167754Smsmith    Level       = 1;
49267754Smsmith
49367754Smsmith    /*
49467754Smsmith     * Traverse the tree of objects until we bubble back up
49567754Smsmith     * to where we started.
49667754Smsmith     */
49767754Smsmith
49867754Smsmith    while (Level > 0)
49967754Smsmith    {
50067754Smsmith        /*
50167754Smsmith         * Get the next typed object in this scope.
50267754Smsmith         * Null returned if not found
50367754Smsmith         */
50467754Smsmith
50567754Smsmith        ChildNode = AcpiNsGetNextObject (ACPI_TYPE_ANY, ParentNode,
50667754Smsmith                                            ChildNode);
50767754Smsmith        if (ChildNode)
50867754Smsmith        {
50967754Smsmith            /*
51067754Smsmith             * Found an object - delete the object within
51167754Smsmith             * the Value field
51267754Smsmith             */
51367754Smsmith
51467754Smsmith            ObjDesc = AcpiNsGetAttachedObject (ChildNode);
51567754Smsmith            if (ObjDesc)
51667754Smsmith            {
51767754Smsmith                AcpiNsDetachObject (ChildNode);
51867754Smsmith                AcpiCmRemoveReference (ObjDesc);
51967754Smsmith            }
52067754Smsmith
52167754Smsmith
52267754Smsmith            /* Check if this object has any children */
52367754Smsmith
52467754Smsmith            if (AcpiNsGetNextObject (ACPI_TYPE_ANY, ChildNode, 0))
52567754Smsmith            {
52667754Smsmith                /*
52767754Smsmith                 * There is at least one child of this object,
52867754Smsmith                 * visit the object
52967754Smsmith                 */
53067754Smsmith
53167754Smsmith                Level++;
53267754Smsmith                ParentNode    = ChildNode;
53367754Smsmith                ChildNode     = 0;
53467754Smsmith            }
53567754Smsmith        }
53667754Smsmith
53767754Smsmith        else
53867754Smsmith        {
53967754Smsmith            /*
54067754Smsmith             * No more children in this object.
54167754Smsmith             * We will move up to the grandparent.
54267754Smsmith             */
54367754Smsmith            Level--;
54467754Smsmith
54567754Smsmith            /*
54667754Smsmith             * Now delete all of the children of this parent
54767754Smsmith             * all at the same time.
54867754Smsmith             */
54967754Smsmith            AcpiNsDeleteChildren (ParentNode);
55067754Smsmith
55167754Smsmith            /* New "last child" is this parent object */
55267754Smsmith
55367754Smsmith            ChildNode = ParentNode;
55467754Smsmith
55567754Smsmith            /* Now we can move up the tree to the grandparent */
55667754Smsmith
55767754Smsmith            ParentNode = AcpiNsGetParentObject (ParentNode);
55867754Smsmith        }
55967754Smsmith    }
56067754Smsmith
56167754Smsmith
56267754Smsmith    return_ACPI_STATUS (AE_OK);
56367754Smsmith}
56467754Smsmith
56567754Smsmith
56667754Smsmith/*******************************************************************************
56767754Smsmith *
56867754Smsmith * FUNCTION:    AcpiNsRemoveReference
56967754Smsmith *
57067754Smsmith * PARAMETERS:  Node           - Named object whose reference count is to be
57167754Smsmith *                                decremented
57267754Smsmith *
57367754Smsmith * RETURN:      None.
57467754Smsmith *
57567754Smsmith * DESCRIPTION: Remove a Node reference.  Decrements the reference count
57667754Smsmith *              of all parent Nodes up to the root.  Any object along
57767754Smsmith *              the way that reaches zero references is freed.
57867754Smsmith *
57967754Smsmith ******************************************************************************/
58067754Smsmith
58169450Smsmithstatic void
58267754SmsmithAcpiNsRemoveReference (
58367754Smsmith    ACPI_NAMESPACE_NODE     *Node)
58467754Smsmith{
58567754Smsmith    ACPI_NAMESPACE_NODE     *NextNode;
58667754Smsmith
58767754Smsmith
58867754Smsmith    /*
58967754Smsmith     * Decrement the reference count(s) of this object and all
59067754Smsmith     * objects up to the root,  Delete anything with zero remaining references.
59167754Smsmith     */
59267754Smsmith    NextNode = Node;
59367754Smsmith    while (NextNode)
59467754Smsmith    {
59567754Smsmith        /* Decrement the reference count on this object*/
59667754Smsmith
59767754Smsmith        NextNode->ReferenceCount--;
59867754Smsmith
59967754Smsmith        /* Delete the object if no more references */
60067754Smsmith
60167754Smsmith        if (!NextNode->ReferenceCount)
60267754Smsmith        {
60367754Smsmith            /* Delete all children and delete the object */
60467754Smsmith
60567754Smsmith            AcpiNsDeleteChildren (NextNode);
60667754Smsmith            AcpiNsDeleteNode (NextNode);
60767754Smsmith        }
60867754Smsmith
60967754Smsmith        /* Move up to parent */
61067754Smsmith
61167754Smsmith        NextNode = AcpiNsGetParentObject (NextNode);
61267754Smsmith    }
61367754Smsmith}
61467754Smsmith
61567754Smsmith
61667754Smsmith/*******************************************************************************
61767754Smsmith *
61867754Smsmith * FUNCTION:    AcpiNsDeleteNamespaceByOwner
61967754Smsmith *
62067754Smsmith * PARAMETERS:  None.
62167754Smsmith *
62267754Smsmith * RETURN:      None.
62367754Smsmith *
62467754Smsmith * DESCRIPTION: Delete entries within the namespace that are owned by a
62567754Smsmith *              specific ID.  Used to delete entire ACPI tables.  All
62667754Smsmith *              reference counts are updated.
62767754Smsmith *
62867754Smsmith ******************************************************************************/
62967754Smsmith
63067754SmsmithACPI_STATUS
63167754SmsmithAcpiNsDeleteNamespaceByOwner (
63267754Smsmith    UINT16                  OwnerId)
63367754Smsmith{
63467754Smsmith    ACPI_NAMESPACE_NODE     *ChildNode;
63567754Smsmith    UINT32                  Level;
63667754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
63767754Smsmith    ACPI_NAMESPACE_NODE     *ParentNode;
63867754Smsmith
63967754Smsmith
64067754Smsmith    FUNCTION_TRACE ("NsDeleteNamespaceSubtree");
64167754Smsmith
64267754Smsmith
64367754Smsmith    ParentNode  = AcpiGbl_RootNode;
64467754Smsmith    ChildNode   = 0;
64567754Smsmith    Level       = 1;
64667754Smsmith
64767754Smsmith    /*
64867754Smsmith     * Traverse the tree of objects until we bubble back up
64967754Smsmith     * to where we started.
65067754Smsmith     */
65167754Smsmith
65267754Smsmith    while (Level > 0)
65367754Smsmith    {
65467754Smsmith        /*
65567754Smsmith         * Get the next typed object in this scope.
65667754Smsmith         * Null returned if not found
65767754Smsmith         */
65867754Smsmith
65967754Smsmith        ChildNode = AcpiNsGetNextObject (ACPI_TYPE_ANY, ParentNode,
66067754Smsmith                                            ChildNode);
66167754Smsmith
66267754Smsmith        if (ChildNode)
66367754Smsmith        {
66467754Smsmith            if (ChildNode->OwnerId == OwnerId)
66567754Smsmith            {
66667754Smsmith                /*
66767754Smsmith                 * Found an object - delete the object within
66867754Smsmith                 * the Value field
66967754Smsmith                 */
67067754Smsmith
67167754Smsmith                ObjDesc = AcpiNsGetAttachedObject (ChildNode);
67267754Smsmith                if (ObjDesc)
67367754Smsmith                {
67467754Smsmith                    AcpiNsDetachObject (ChildNode);
67567754Smsmith                    AcpiCmRemoveReference (ObjDesc);
67667754Smsmith                }
67767754Smsmith            }
67867754Smsmith
67967754Smsmith            /* Check if this object has any children */
68067754Smsmith
68167754Smsmith            if (AcpiNsGetNextObject (ACPI_TYPE_ANY, ChildNode, 0))
68267754Smsmith            {
68367754Smsmith                /*
68467754Smsmith                 * There is at least one child of this object,
68567754Smsmith                 * visit the object
68667754Smsmith                 */
68767754Smsmith
68867754Smsmith                Level++;
68967754Smsmith                ParentNode    = ChildNode;
69067754Smsmith                ChildNode     = 0;
69167754Smsmith            }
69267754Smsmith
69367754Smsmith            else if (ChildNode->OwnerId == OwnerId)
69467754Smsmith            {
69567754Smsmith                AcpiNsRemoveReference (ChildNode);
69667754Smsmith            }
69767754Smsmith        }
69867754Smsmith
69967754Smsmith        else
70067754Smsmith        {
70167754Smsmith            /*
70267754Smsmith             * No more children in this object.  Move up to grandparent.
70367754Smsmith             */
70467754Smsmith            Level--;
70567754Smsmith
70667754Smsmith            if (Level != 0)
70767754Smsmith            {
70867754Smsmith                if (ParentNode->OwnerId == OwnerId)
70967754Smsmith                {
71067754Smsmith                    AcpiNsRemoveReference (ParentNode);
71167754Smsmith                }
71267754Smsmith            }
71367754Smsmith
71467754Smsmith            /* New "last child" is this parent object */
71567754Smsmith
71667754Smsmith            ChildNode = ParentNode;
71767754Smsmith
71867754Smsmith            /* Now we can move up the tree to the grandparent */
71967754Smsmith
72067754Smsmith            ParentNode = AcpiNsGetParentObject (ParentNode);
72167754Smsmith        }
72267754Smsmith    }
72367754Smsmith
72467754Smsmith
72567754Smsmith    return_ACPI_STATUS (AE_OK);
72667754Smsmith}
72767754Smsmith
72867754Smsmith
729