nsalloc.c revision 91116
1178172Simp/*******************************************************************************
2178172Simp *
3178172Simp * Module Name: nsalloc - Namespace allocation and deletion utilities
4178172Simp *              $Revision: 70 $
5178172Simp *
6178172Simp ******************************************************************************/
7178172Simp
8178172Simp/******************************************************************************
9178172Simp *
10178172Simp * 1. Copyright Notice
11178172Simp *
12178172Simp * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp.
13178172Simp * All rights reserved.
14178172Simp *
15178172Simp * 2. License
16178172Simp *
17178172Simp * 2.1. This is your license from Intel Corp. under its intellectual property
18178172Simp * rights.  You may have additional license terms from the party that provided
19178172Simp * you this software, covering your right to use that party's intellectual
20178172Simp * property rights.
21178172Simp *
22178172Simp * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23178172Simp * copy of the source code appearing in this file ("Covered Code") an
24178172Simp * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25178172Simp * base code distributed originally by Intel ("Original Intel Code") to copy,
26178172Simp * make derivatives, distribute, use and display any portion of the Covered
27178172Simp * Code in any form, with the right to sublicense such rights; and
28178172Simp *
29178172Simp * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30178172Simp * license (with the right to sublicense), under only those claims of Intel
31178172Simp * patents that are infringed by the Original Intel Code, to make, use, sell,
32178172Simp * offer to sell, and import the Covered Code and derivative works thereof
33178172Simp * solely to the minimum extent necessary to exercise the above copyright
34178172Simp * license, and in no event shall the patent license extend to any additions
35178172Simp * to or modifications of the Original Intel Code.  No other license or right
36178172Simp * is granted directly or by implication, estoppel or otherwise;
37178172Simp *
38178172Simp * The above copyright and patent license is granted only if the following
39178172Simp * conditions are met:
40178172Simp *
41218266Stijl * 3. Conditions
42217155Stijl *
43217155Stijl * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44206715Sjmallett * Redistribution of source code of any substantial portion of the Covered
45217155Stijl * Code or modification with rights to further distribute source must include
46217155Stijl * the above Copyright Notice, the above License, this list of Conditions,
47206715Sjmallett * and the following Disclaimer and Export Compliance provision.  In addition,
48206715Sjmallett * Licensee must cause all Covered Code to which Licensee contributes to
49178172Simp * contain a file documenting the changes Licensee made to create that Covered
50178172Simp * Code and the date of any change.  Licensee must include in that file the
51217156Stijl * documentation of any changes made by any predecessor Licensee.  Licensee
52217156Stijl * must include a prominent statement that the modification is derived,
53217156Stijl * directly or indirectly, from Original Intel Code.
54217155Stijl *
55217156Stijl * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56217156Stijl * Redistribution of source code of any substantial portion of the Covered
57217156Stijl * Code or modification without rights to further distribute source must
58217155Stijl * include the following Disclaimer and Export Compliance provision in the
59217156Stijl * documentation and/or other materials provided with distribution.  In
60217156Stijl * addition, Licensee may not authorize further sublicense of source of any
61217156Stijl * portion of the Covered Code, and must include terms to the effect that the
62217155Stijl * license from Licensee to its licensee is limited to the intellectual
63217156Stijl * property embodied in the software Licensee provides to its licensee, and
64217155Stijl * not to intellectual property embodied in modifications its licensee may
65178172Simp * make.
66217156Stijl *
67217156Stijl * 3.3. Redistribution of Executable. Redistribution in executable form of any
68217156Stijl * substantial portion of the Covered Code or modification must reproduce the
69217155Stijl * above Copyright Notice, and the following Disclaimer and Export Compliance
70217156Stijl * provision in the documentation and/or other materials provided with the
71217156Stijl * distribution.
72217156Stijl *
73217155Stijl * 3.4. Intel retains all right, title, and interest in and to the Original
74217156Stijl * Intel Code.
75217156Stijl *
76217156Stijl * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77217155Stijl * Intel shall be used in advertising or otherwise to promote the sale, use or
78217156Stijl * other dealings in products derived from or relating to the Covered Code
79217155Stijl * without prior written authorization from Intel.
80178172Simp *
81178172Simp * 4. Disclaimer and Export Compliance
82178172Simp *
83217156Stijl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84217156Stijl * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85217156Stijl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86217155Stijl * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87217156Stijl * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88217156Stijl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89217156Stijl * PARTICULAR PURPOSE.
90217155Stijl *
91217156Stijl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92217156Stijl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93217156Stijl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94217155Stijl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95217156Stijl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96217155Stijl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97178172Simp * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98217156Stijl * LIMITED REMEDY.
99217156Stijl *
100217156Stijl * 4.3. Licensee shall not export, either directly or indirectly, any of this
101217155Stijl * software or system incorporating such software without first obtaining any
102217156Stijl * required license or other approval from the U. S. Department of Commerce or
103217156Stijl * any other agency or department of the United States Government.  In the
104217156Stijl * event Licensee exports any such software from the United States or
105217155Stijl * re-exports any such software from a foreign destination, Licensee shall
106217156Stijl * ensure that the distribution and export/re-export of the software is in
107217156Stijl * compliance with all laws, regulations, orders, or other restrictions of the
108217156Stijl * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109217155Stijl * any of its subsidiaries will export/re-export any technical data, process,
110217156Stijl * software, or service, directly or indirectly, to any country for which the
111217155Stijl * United States government or any agency thereof requires an export license,
112178172Simp * other governmental approval, or letter of assurance, without first obtaining
113217156Stijl * such license, approval or letter.
114217156Stijl *
115217156Stijl *****************************************************************************/
116217155Stijl
117217156Stijl
118217156Stijl#define __NSALLOC_C__
119217156Stijl
120217155Stijl#include "acpi.h"
121217156Stijl#include "acnamesp.h"
122217156Stijl#include "acinterp.h"
123217156Stijl
124217155Stijl
125217156Stijl#define _COMPONENT          ACPI_NAMESPACE
126217155Stijl        ACPI_MODULE_NAME    ("nsalloc")
127178172Simp
128217156Stijl
129217156Stijl/*******************************************************************************
130217156Stijl *
131217155Stijl * FUNCTION:    AcpiNsCreateNode
132217156Stijl *
133217156Stijl * PARAMETERS:  AcpiName        - Name of the new node
134217156Stijl *
135217155Stijl * RETURN:      None
136217156Stijl *
137217156Stijl * DESCRIPTION: Create a namespace node
138217156Stijl *
139217155Stijl ******************************************************************************/
140217156Stijl
141217155StijlACPI_NAMESPACE_NODE *
142178172SimpAcpiNsCreateNode (
143178172Simp    UINT32                  Name)
144178172Simp{
145217156Stijl    ACPI_NAMESPACE_NODE     *Node;
146217156Stijl
147217156Stijl
148217155Stijl    ACPI_FUNCTION_TRACE ("NsCreateNode");
149217156Stijl
150217156Stijl
151217156Stijl    Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE));
152217155Stijl    if (!Node)
153217156Stijl    {
154217156Stijl        return_PTR (NULL);
155217156Stijl    }
156217155Stijl
157217156Stijl    ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++);
158217155Stijl
159178172Simp    Node->Name           = Name;
160217156Stijl    Node->ReferenceCount = 1;
161217156Stijl    ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED);
162217156Stijl
163217155Stijl    return_PTR (Node);
164217156Stijl}
165217156Stijl
166217156Stijl
167217155Stijl/*******************************************************************************
168217156Stijl *
169217156Stijl * FUNCTION:    AcpiNsDeleteNode
170217156Stijl *
171217155Stijl * PARAMETERS:  Node            - Node to be deleted
172217156Stijl *
173217155Stijl * RETURN:      None
174178172Simp *
175178172Simp * DESCRIPTION: Delete a namespace node
176178172Simp *
177217156Stijl ******************************************************************************/
178217156Stijl
179217156Stijlvoid
180217155StijlAcpiNsDeleteNode (
181217156Stijl    ACPI_NAMESPACE_NODE     *Node)
182217156Stijl{
183217156Stijl    ACPI_NAMESPACE_NODE     *ParentNode;
184217155Stijl    ACPI_NAMESPACE_NODE     *PrevNode;
185217156Stijl    ACPI_NAMESPACE_NODE     *NextNode;
186217156Stijl
187217156Stijl
188217155Stijl    ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node);
189217156Stijl
190217155Stijl
191178172Simp    ParentNode = AcpiNsGetParentNode (Node);
192217156Stijl
193217156Stijl    PrevNode = NULL;
194217156Stijl    NextNode = ParentNode->Child;
195217155Stijl
196217156Stijl    while (NextNode != Node)
197217156Stijl    {
198217156Stijl        PrevNode = NextNode;
199217155Stijl        NextNode = PrevNode->Peer;
200217156Stijl    }
201217156Stijl
202217156Stijl    if (PrevNode)
203217155Stijl    {
204217156Stijl        PrevNode->Peer = NextNode->Peer;
205217155Stijl        if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST)
206178172Simp        {
207217156Stijl            PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST;
208217156Stijl        }
209217156Stijl    }
210217155Stijl    else
211217156Stijl    {
212217156Stijl        ParentNode->Child = NextNode->Peer;
213217156Stijl    }
214217155Stijl
215217156Stijl
216217156Stijl    ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++);
217217156Stijl
218217155Stijl    /*
219217156Stijl     * Detach an object if there is one then delete the node
220217155Stijl     */
221178172Simp    AcpiNsDetachObject (Node);
222178172Simp    ACPI_MEM_FREE (Node);
223    return_VOID;
224}
225
226
227/*******************************************************************************
228 *
229 * FUNCTION:    AcpiNsInstallNode
230 *
231 * PARAMETERS:  WalkState       - Current state of the walk
232 *              ParentNode      - The parent of the new Node
233 *              Node            - The new Node to install
234 *              Type            - ACPI object type of the new Node
235 *
236 * RETURN:      None
237 *
238 * DESCRIPTION: Initialize a new namespace node and install it amongst
239 *              its peers.
240 *
241 *              Note: Current namespace lookup is linear search, so the nodes
242 *              are not linked in any particular order.
243 *
244 ******************************************************************************/
245
246void
247AcpiNsInstallNode (
248    ACPI_WALK_STATE         *WalkState,
249    ACPI_NAMESPACE_NODE     *ParentNode,    /* Parent */
250    ACPI_NAMESPACE_NODE     *Node,          /* New Child*/
251    ACPI_OBJECT_TYPE        Type)
252{
253    UINT16                  OwnerId = TABLE_ID_DSDT;
254    ACPI_NAMESPACE_NODE     *ChildNode;
255
256
257    ACPI_FUNCTION_TRACE ("NsInstallNode");
258
259
260    /*
261     * Get the owner ID from the Walk state
262     * The owner ID is used to track table deletion and
263     * deletion of objects created by methods
264     */
265    if (WalkState)
266    {
267        OwnerId = WalkState->OwnerId;
268    }
269
270    /* Link the new entry into the parent and existing children */
271
272    ChildNode = ParentNode->Child;
273    if (!ChildNode)
274    {
275        ParentNode->Child = Node;
276    }
277    else
278    {
279        while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST))
280        {
281            ChildNode = ChildNode->Peer;
282        }
283
284        ChildNode->Peer = Node;
285
286        /* Clear end-of-list flag */
287
288        ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST;
289    }
290
291    /* Init the new entry */
292
293    Node->OwnerId   = OwnerId;
294    Node->Flags     |= ANOBJ_END_OF_PEER_LIST;
295    Node->Peer      = ParentNode;
296
297
298    /*
299     * If adding a name with unknown type, or having to
300     * add the region in order to define fields in it, we
301     * have a forward reference.
302     */
303    if ((ACPI_TYPE_ANY == Type) ||
304        (INTERNAL_TYPE_FIELD_DEFN == Type) ||
305        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
306    {
307        /*
308         * We don't want to abort here, however!
309         * We will fill in the actual type when the
310         * real definition is found later.
311         */
312        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "[%4.4s] is a forward reference\n",
313            (char *) &Node->Name));
314    }
315
316    /*
317     * The DefFieldDefn and BankFieldDefn cases are actually
318     * looking up the Region in which the field will be defined
319     */
320    if ((INTERNAL_TYPE_FIELD_DEFN == Type) ||
321        (INTERNAL_TYPE_BANK_FIELD_DEFN == Type))
322    {
323        Type = ACPI_TYPE_REGION;
324    }
325
326    /*
327     * Scope, DefAny, and IndexFieldDefn are bogus "types" which do
328     * not actually have anything to do with the type of the name
329     * being looked up.  Save any other value of Type as the type of
330     * the entry.
331     */
332    if ((Type != INTERNAL_TYPE_SCOPE) &&
333        (Type != INTERNAL_TYPE_DEF_ANY) &&
334        (Type != INTERNAL_TYPE_INDEX_FIELD_DEFN))
335    {
336        Node->Type = (UINT8) Type;
337    }
338
339    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s added to %p at %p\n",
340        (char *) &Node->Name, ParentNode, Node));
341
342    /*
343     * Increment the reference count(s) of all parents up to
344     * the root!
345     */
346    while ((Node = AcpiNsGetParentNode (Node)) != NULL)
347    {
348        Node->ReferenceCount++;
349    }
350
351    return_VOID;
352}
353
354
355/*******************************************************************************
356 *
357 * FUNCTION:    AcpiNsDeleteChildren
358 *
359 * PARAMETERS:  ParentNode      - Delete this objects children
360 *
361 * RETURN:      None.
362 *
363 * DESCRIPTION: Delete all children of the parent object. In other words,
364 *              deletes a "scope".
365 *
366 ******************************************************************************/
367
368void
369AcpiNsDeleteChildren (
370    ACPI_NAMESPACE_NODE     *ParentNode)
371{
372    ACPI_NAMESPACE_NODE     *ChildNode;
373    ACPI_NAMESPACE_NODE     *NextNode;
374    UINT8                   Flags;
375
376
377    ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode);
378
379
380    if (!ParentNode)
381    {
382        return_VOID;
383    }
384
385    /* If no children, all done! */
386
387    ChildNode = ParentNode->Child;
388    if (!ChildNode)
389    {
390        return_VOID;
391    }
392
393    /*
394     * Deallocate all children at this level
395     */
396    do
397    {
398        /* Get the things we need */
399
400        NextNode    = ChildNode->Peer;
401        Flags       = ChildNode->Flags;
402
403        /* Grandchildren should have all been deleted already */
404
405        if (ChildNode->Child)
406        {
407            ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n",
408                ParentNode, ChildNode));
409        }
410
411        /* Now we can free this child object */
412
413        ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++);
414
415        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Object %p, Remaining %X\n",
416            ChildNode, AcpiGbl_CurrentNodeCount));
417
418        /*
419         * Detach an object if there is one, then free the child node
420         */
421        AcpiNsDetachObject (ChildNode);
422        ACPI_MEM_FREE (ChildNode);
423
424        /* And move on to the next child in the list */
425
426        ChildNode = NextNode;
427
428    } while (!(Flags & ANOBJ_END_OF_PEER_LIST));
429
430
431    /* Clear the parent's child pointer */
432
433    ParentNode->Child = NULL;
434
435    return_VOID;
436}
437
438
439/*******************************************************************************
440 *
441 * FUNCTION:    AcpiNsDeleteNamespaceSubtree
442 *
443 * PARAMETERS:  ParentNode      - Root of the subtree to be deleted
444 *
445 * RETURN:      None.
446 *
447 * DESCRIPTION: Delete a subtree of the namespace.  This includes all objects
448 *              stored within the subtree.
449 *
450 ******************************************************************************/
451
452ACPI_STATUS
453AcpiNsDeleteNamespaceSubtree (
454    ACPI_NAMESPACE_NODE     *ParentNode)
455{
456    ACPI_NAMESPACE_NODE     *ChildNode = NULL;
457    UINT32                  Level = 1;
458
459
460    ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree");
461
462
463    if (!ParentNode)
464    {
465        return_ACPI_STATUS (AE_OK);
466    }
467
468    /*
469     * Traverse the tree of objects until we bubble back up
470     * to where we started.
471     */
472    while (Level > 0)
473    {
474        /* Get the next node in this scope (NULL if none) */
475
476        ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode,
477                                            ChildNode);
478        if (ChildNode)
479        {
480            /* Found a child node - detach any attached object */
481
482            AcpiNsDetachObject (ChildNode);
483
484            /* Check if this node has any children */
485
486            if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0))
487            {
488                /*
489                 * There is at least one child of this node,
490                 * visit the node
491                 */
492                Level++;
493                ParentNode    = ChildNode;
494                ChildNode     = 0;
495            }
496        }
497        else
498        {
499            /*
500             * No more children of this parent node.
501             * Move up to the grandparent.
502             */
503            Level--;
504
505            /*
506             * Now delete all of the children of this parent
507             * all at the same time.
508             */
509            AcpiNsDeleteChildren (ParentNode);
510
511            /* New "last child" is this parent node */
512
513            ChildNode = ParentNode;
514
515            /* Move up the tree to the grandparent */
516
517            ParentNode = AcpiNsGetParentNode (ParentNode);
518        }
519    }
520
521    return_ACPI_STATUS (AE_OK);
522}
523
524
525/*******************************************************************************
526 *
527 * FUNCTION:    AcpiNsRemoveReference
528 *
529 * PARAMETERS:  Node           - Named node whose reference count is to be
530 *                               decremented
531 *
532 * RETURN:      None.
533 *
534 * DESCRIPTION: Remove a Node reference.  Decrements the reference count
535 *              of all parent Nodes up to the root.  Any node along
536 *              the way that reaches zero references is freed.
537 *
538 ******************************************************************************/
539
540static void
541AcpiNsRemoveReference (
542    ACPI_NAMESPACE_NODE     *Node)
543{
544    ACPI_NAMESPACE_NODE     *ParentNode;
545    ACPI_NAMESPACE_NODE     *ThisNode;
546
547
548    ACPI_FUNCTION_ENTRY ();
549
550
551    /*
552     * Decrement the reference count(s) of this node and all
553     * nodes up to the root,  Delete anything with zero remaining references.
554     */
555    ThisNode = Node;
556    while (ThisNode)
557    {
558        /* Prepare to move up to parent */
559
560        ParentNode = AcpiNsGetParentNode (ThisNode);
561
562        /* Decrement the reference count on this node */
563
564        ThisNode->ReferenceCount--;
565
566        /* Delete the node if no more references */
567
568        if (!ThisNode->ReferenceCount)
569        {
570            /* Delete all children and delete the node */
571
572            AcpiNsDeleteChildren (ThisNode);
573            AcpiNsDeleteNode (ThisNode);
574        }
575
576        ThisNode = ParentNode;
577    }
578}
579
580
581/*******************************************************************************
582 *
583 * FUNCTION:    AcpiNsDeleteNamespaceByOwner
584 *
585 * PARAMETERS:  OwnerId     - All nodes with this owner will be deleted
586 *
587 * RETURN:      Status
588 *
589 * DESCRIPTION: Delete entries within the namespace that are owned by a
590 *              specific ID.  Used to delete entire ACPI tables.  All
591 *              reference counts are updated.
592 *
593 ******************************************************************************/
594
595ACPI_STATUS
596AcpiNsDeleteNamespaceByOwner (
597    UINT16                  OwnerId)
598{
599    ACPI_NAMESPACE_NODE     *ChildNode;
600    ACPI_NAMESPACE_NODE     *DeletionNode;
601    UINT32                  Level;
602    ACPI_NAMESPACE_NODE     *ParentNode;
603
604
605    ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId);
606
607
608    ParentNode    = AcpiGbl_RootNode;
609    ChildNode     = NULL;
610    DeletionNode  = NULL;
611    Level         = 1;
612
613    /*
614     * Traverse the tree of nodes until we bubble back up
615     * to where we started.
616     */
617    while (Level > 0)
618    {
619        /*
620         * Get the next child of this parent node. When ChildNode is NULL,
621         * the first child of the parent is returned
622         */
623        ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode);
624
625        if (DeletionNode)
626        {
627            AcpiNsRemoveReference (DeletionNode);
628            DeletionNode = NULL;
629        }
630
631        if (ChildNode)
632        {
633            if (ChildNode->OwnerId == OwnerId)
634            {
635                /* Found a matching child node - detach any attached object */
636
637                AcpiNsDetachObject (ChildNode);
638            }
639
640            /* Check if this node has any children */
641
642            if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL))
643            {
644                /*
645                 * There is at least one child of this node,
646                 * visit the node
647                 */
648                Level++;
649                ParentNode    = ChildNode;
650                ChildNode     = NULL;
651            }
652            else if (ChildNode->OwnerId == OwnerId)
653            {
654                DeletionNode = ChildNode;
655            }
656        }
657        else
658        {
659            /*
660             * No more children of this parent node.
661             * Move up to the grandparent.
662             */
663            Level--;
664            if (Level != 0)
665            {
666                if (ParentNode->OwnerId == OwnerId)
667                {
668                    DeletionNode = ParentNode;
669                }
670            }
671
672            /* New "last child" is this parent node */
673
674            ChildNode = ParentNode;
675
676            /* Move up the tree to the grandparent */
677
678            ParentNode = AcpiNsGetParentNode (ParentNode);
679        }
680    }
681
682    return_ACPI_STATUS (AE_OK);
683}
684
685
686