nsalloc.c revision 99146
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsalloc - Namespace allocation and deletion utilities 499146Siwasaki * $Revision: 72 $ 567754Smsmith * 667754Smsmith ******************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 1291116Smsmith * Some or all of this work - Copyright (c) 1999 - 2002, 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 12577424Smsmith#define _COMPONENT ACPI_NAMESPACE 12691116Smsmith ACPI_MODULE_NAME ("nsalloc") 12767754Smsmith 12867754Smsmith 12967754Smsmith/******************************************************************************* 13067754Smsmith * 13167754Smsmith * FUNCTION: AcpiNsCreateNode 13267754Smsmith * 13383174Smsmith * PARAMETERS: AcpiName - Name of the new node 13467754Smsmith * 13567754Smsmith * RETURN: None 13667754Smsmith * 13783174Smsmith * DESCRIPTION: Create a namespace node 13867754Smsmith * 13967754Smsmith ******************************************************************************/ 14067754Smsmith 14167754SmsmithACPI_NAMESPACE_NODE * 14267754SmsmithAcpiNsCreateNode ( 14384491Smsmith UINT32 Name) 14467754Smsmith{ 14567754Smsmith ACPI_NAMESPACE_NODE *Node; 14667754Smsmith 14783174Smsmith 14891116Smsmith ACPI_FUNCTION_TRACE ("NsCreateNode"); 14967754Smsmith 15067754Smsmith 15180062Smsmith Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); 15267754Smsmith if (!Node) 15367754Smsmith { 15467754Smsmith return_PTR (NULL); 15567754Smsmith } 15667754Smsmith 15782367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++); 15867754Smsmith 15999146Siwasaki Node->Name.Integer = Name; 16067754Smsmith Node->ReferenceCount = 1; 16191116Smsmith ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 16267754Smsmith 16367754Smsmith return_PTR (Node); 16467754Smsmith} 16567754Smsmith 16667754Smsmith 16767754Smsmith/******************************************************************************* 16867754Smsmith * 16967754Smsmith * FUNCTION: AcpiNsDeleteNode 17067754Smsmith * 17183174Smsmith * PARAMETERS: Node - Node to be deleted 17267754Smsmith * 17367754Smsmith * RETURN: None 17467754Smsmith * 17583174Smsmith * DESCRIPTION: Delete a namespace node 17667754Smsmith * 17767754Smsmith ******************************************************************************/ 17867754Smsmith 17967754Smsmithvoid 18067754SmsmithAcpiNsDeleteNode ( 18167754Smsmith ACPI_NAMESPACE_NODE *Node) 18267754Smsmith{ 18367754Smsmith ACPI_NAMESPACE_NODE *ParentNode; 18467754Smsmith ACPI_NAMESPACE_NODE *PrevNode; 18567754Smsmith ACPI_NAMESPACE_NODE *NextNode; 18667754Smsmith 18767754Smsmith 18891116Smsmith ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node); 18967754Smsmith 19083174Smsmith 19191116Smsmith ParentNode = AcpiNsGetParentNode (Node); 19267754Smsmith 19367754Smsmith PrevNode = NULL; 19467754Smsmith NextNode = ParentNode->Child; 19567754Smsmith 19667754Smsmith while (NextNode != Node) 19767754Smsmith { 19867754Smsmith PrevNode = NextNode; 19967754Smsmith NextNode = PrevNode->Peer; 20067754Smsmith } 20167754Smsmith 20267754Smsmith if (PrevNode) 20367754Smsmith { 20467754Smsmith PrevNode->Peer = NextNode->Peer; 20567754Smsmith if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 20667754Smsmith { 20767754Smsmith PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 20867754Smsmith } 20967754Smsmith } 21067754Smsmith else 21167754Smsmith { 21267754Smsmith ParentNode->Child = NextNode->Peer; 21367754Smsmith } 21467754Smsmith 21567754Smsmith 21682367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 21767754Smsmith 21867754Smsmith /* 21987031Smsmith * Detach an object if there is one then delete the node 22067754Smsmith */ 22187031Smsmith AcpiNsDetachObject (Node); 22280062Smsmith ACPI_MEM_FREE (Node); 22367754Smsmith return_VOID; 22467754Smsmith} 22567754Smsmith 22667754Smsmith 22767754Smsmith/******************************************************************************* 22867754Smsmith * 22967754Smsmith * FUNCTION: AcpiNsInstallNode 23067754Smsmith * 23167754Smsmith * PARAMETERS: WalkState - Current state of the walk 23267754Smsmith * ParentNode - The parent of the new Node 23383174Smsmith * Node - The new Node to install 23467754Smsmith * Type - ACPI object type of the new Node 23567754Smsmith * 23667754Smsmith * RETURN: None 23767754Smsmith * 23887031Smsmith * DESCRIPTION: Initialize a new namespace node and install it amongst 23987031Smsmith * its peers. 24067754Smsmith * 24187031Smsmith * Note: Current namespace lookup is linear search, so the nodes 24291116Smsmith * are not linked in any particular order. 24387031Smsmith * 24467754Smsmith ******************************************************************************/ 24567754Smsmith 24667754Smsmithvoid 24767754SmsmithAcpiNsInstallNode ( 24867754Smsmith ACPI_WALK_STATE *WalkState, 24967754Smsmith ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 25083174Smsmith ACPI_NAMESPACE_NODE *Node, /* New Child*/ 25191116Smsmith ACPI_OBJECT_TYPE Type) 25267754Smsmith{ 25367754Smsmith UINT16 OwnerId = TABLE_ID_DSDT; 25467754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 25567754Smsmith 25667754Smsmith 25791116Smsmith ACPI_FUNCTION_TRACE ("NsInstallNode"); 25867754Smsmith 25967754Smsmith 26067754Smsmith /* 26167754Smsmith * Get the owner ID from the Walk state 26267754Smsmith * The owner ID is used to track table deletion and 26367754Smsmith * deletion of objects created by methods 26467754Smsmith */ 26567754Smsmith if (WalkState) 26667754Smsmith { 26767754Smsmith OwnerId = WalkState->OwnerId; 26867754Smsmith } 26967754Smsmith 27087031Smsmith /* Link the new entry into the parent and existing children */ 27167754Smsmith 27267754Smsmith ChildNode = ParentNode->Child; 27367754Smsmith if (!ChildNode) 27467754Smsmith { 27567754Smsmith ParentNode->Child = Node; 27667754Smsmith } 27767754Smsmith else 27867754Smsmith { 27967754Smsmith while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 28067754Smsmith { 28167754Smsmith ChildNode = ChildNode->Peer; 28267754Smsmith } 28367754Smsmith 28467754Smsmith ChildNode->Peer = Node; 28567754Smsmith 28667754Smsmith /* Clear end-of-list flag */ 28767754Smsmith 28867754Smsmith ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 28967754Smsmith } 29067754Smsmith 29167754Smsmith /* Init the new entry */ 29267754Smsmith 29367754Smsmith Node->OwnerId = OwnerId; 29467754Smsmith Node->Flags |= ANOBJ_END_OF_PEER_LIST; 29567754Smsmith Node->Peer = ParentNode; 29667754Smsmith 29767754Smsmith 29867754Smsmith /* 29967754Smsmith * If adding a name with unknown type, or having to 30067754Smsmith * add the region in order to define fields in it, we 30167754Smsmith * have a forward reference. 30267754Smsmith */ 30367754Smsmith if ((ACPI_TYPE_ANY == Type) || 30477424Smsmith (INTERNAL_TYPE_FIELD_DEFN == Type) || 30567754Smsmith (INTERNAL_TYPE_BANK_FIELD_DEFN == Type)) 30667754Smsmith { 30767754Smsmith /* 30867754Smsmith * We don't want to abort here, however! 30967754Smsmith * We will fill in the actual type when the 31067754Smsmith * real definition is found later. 31167754Smsmith */ 31299146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] is a forward reference\n", 31391116Smsmith (char *) &Node->Name)); 31467754Smsmith } 31567754Smsmith 31667754Smsmith /* 31767754Smsmith * The DefFieldDefn and BankFieldDefn cases are actually 31867754Smsmith * looking up the Region in which the field will be defined 31967754Smsmith */ 32077424Smsmith if ((INTERNAL_TYPE_FIELD_DEFN == Type) || 32167754Smsmith (INTERNAL_TYPE_BANK_FIELD_DEFN == Type)) 32267754Smsmith { 32367754Smsmith Type = ACPI_TYPE_REGION; 32467754Smsmith } 32567754Smsmith 32667754Smsmith /* 32767754Smsmith * Scope, DefAny, and IndexFieldDefn are bogus "types" which do 32867754Smsmith * not actually have anything to do with the type of the name 32967754Smsmith * being looked up. Save any other value of Type as the type of 33067754Smsmith * the entry. 33167754Smsmith */ 33267754Smsmith if ((Type != INTERNAL_TYPE_SCOPE) && 33367754Smsmith (Type != INTERNAL_TYPE_DEF_ANY) && 33467754Smsmith (Type != INTERNAL_TYPE_INDEX_FIELD_DEFN)) 33567754Smsmith { 33667754Smsmith Node->Type = (UINT8) Type; 33767754Smsmith } 33867754Smsmith 33982367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s added to %p at %p\n", 34091116Smsmith (char *) &Node->Name, ParentNode, Node)); 34167754Smsmith 34267754Smsmith /* 34367754Smsmith * Increment the reference count(s) of all parents up to 34467754Smsmith * the root! 34567754Smsmith */ 34691116Smsmith while ((Node = AcpiNsGetParentNode (Node)) != NULL) 34767754Smsmith { 34867754Smsmith Node->ReferenceCount++; 34967754Smsmith } 35067754Smsmith 35167754Smsmith return_VOID; 35267754Smsmith} 35367754Smsmith 35467754Smsmith 35567754Smsmith/******************************************************************************* 35667754Smsmith * 35767754Smsmith * FUNCTION: AcpiNsDeleteChildren 35867754Smsmith * 35967754Smsmith * PARAMETERS: ParentNode - Delete this objects children 36067754Smsmith * 36167754Smsmith * RETURN: None. 36267754Smsmith * 36391116Smsmith * DESCRIPTION: Delete all children of the parent object. In other words, 36491116Smsmith * deletes a "scope". 36567754Smsmith * 36667754Smsmith ******************************************************************************/ 36767754Smsmith 36867754Smsmithvoid 36967754SmsmithAcpiNsDeleteChildren ( 37067754Smsmith ACPI_NAMESPACE_NODE *ParentNode) 37167754Smsmith{ 37267754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 37367754Smsmith ACPI_NAMESPACE_NODE *NextNode; 37467754Smsmith UINT8 Flags; 37567754Smsmith 37667754Smsmith 37791116Smsmith ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode); 37867754Smsmith 37967754Smsmith 38067754Smsmith if (!ParentNode) 38167754Smsmith { 38267754Smsmith return_VOID; 38367754Smsmith } 38467754Smsmith 38567754Smsmith /* If no children, all done! */ 38667754Smsmith 38767754Smsmith ChildNode = ParentNode->Child; 38867754Smsmith if (!ChildNode) 38967754Smsmith { 39067754Smsmith return_VOID; 39167754Smsmith } 39267754Smsmith 39367754Smsmith /* 39467754Smsmith * Deallocate all children at this level 39567754Smsmith */ 39667754Smsmith do 39767754Smsmith { 39867754Smsmith /* Get the things we need */ 39967754Smsmith 40067754Smsmith NextNode = ChildNode->Peer; 40167754Smsmith Flags = ChildNode->Flags; 40267754Smsmith 40367754Smsmith /* Grandchildren should have all been deleted already */ 40467754Smsmith 40567754Smsmith if (ChildNode->Child) 40667754Smsmith { 40785756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 40867754Smsmith ParentNode, ChildNode)); 40967754Smsmith } 41067754Smsmith 41167754Smsmith /* Now we can free this child object */ 41267754Smsmith 41382367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 41467754Smsmith 41599146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 41667754Smsmith ChildNode, AcpiGbl_CurrentNodeCount)); 41767754Smsmith 41867754Smsmith /* 41985756Smsmith * Detach an object if there is one, then free the child node 42067754Smsmith */ 42185756Smsmith AcpiNsDetachObject (ChildNode); 42280062Smsmith ACPI_MEM_FREE (ChildNode); 42367754Smsmith 42467754Smsmith /* And move on to the next child in the list */ 42567754Smsmith 42667754Smsmith ChildNode = NextNode; 42767754Smsmith 42867754Smsmith } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 42967754Smsmith 43067754Smsmith 43167754Smsmith /* Clear the parent's child pointer */ 43267754Smsmith 43367754Smsmith ParentNode->Child = NULL; 43467754Smsmith 43567754Smsmith return_VOID; 43667754Smsmith} 43767754Smsmith 43867754Smsmith 43967754Smsmith/******************************************************************************* 44067754Smsmith * 44167754Smsmith * FUNCTION: AcpiNsDeleteNamespaceSubtree 44267754Smsmith * 44383174Smsmith * PARAMETERS: ParentNode - Root of the subtree to be deleted 44467754Smsmith * 44567754Smsmith * RETURN: None. 44667754Smsmith * 44767754Smsmith * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 44891116Smsmith * stored within the subtree. 44967754Smsmith * 45067754Smsmith ******************************************************************************/ 45167754Smsmith 45267754SmsmithACPI_STATUS 45367754SmsmithAcpiNsDeleteNamespaceSubtree ( 45467754Smsmith ACPI_NAMESPACE_NODE *ParentNode) 45567754Smsmith{ 45684491Smsmith ACPI_NAMESPACE_NODE *ChildNode = NULL; 45784491Smsmith UINT32 Level = 1; 45867754Smsmith 45967754Smsmith 46091116Smsmith ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree"); 46167754Smsmith 46267754Smsmith 46367754Smsmith if (!ParentNode) 46467754Smsmith { 46567754Smsmith return_ACPI_STATUS (AE_OK); 46667754Smsmith } 46767754Smsmith 46867754Smsmith /* 46967754Smsmith * Traverse the tree of objects until we bubble back up 47067754Smsmith * to where we started. 47167754Smsmith */ 47267754Smsmith while (Level > 0) 47367754Smsmith { 47485756Smsmith /* Get the next node in this scope (NULL if none) */ 47585756Smsmith 47685756Smsmith ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, 47767754Smsmith ChildNode); 47867754Smsmith if (ChildNode) 47967754Smsmith { 48085756Smsmith /* Found a child node - detach any attached object */ 48167754Smsmith 48285756Smsmith AcpiNsDetachObject (ChildNode); 48367754Smsmith 48485756Smsmith /* Check if this node has any children */ 48567754Smsmith 48685756Smsmith if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0)) 48767754Smsmith { 48867754Smsmith /* 48985756Smsmith * There is at least one child of this node, 49085756Smsmith * visit the node 49167754Smsmith */ 49267754Smsmith Level++; 49367754Smsmith ParentNode = ChildNode; 49467754Smsmith ChildNode = 0; 49567754Smsmith } 49667754Smsmith } 49767754Smsmith else 49867754Smsmith { 49967754Smsmith /* 50085756Smsmith * No more children of this parent node. 50185756Smsmith * Move up to the grandparent. 50267754Smsmith */ 50367754Smsmith Level--; 50467754Smsmith 50567754Smsmith /* 50667754Smsmith * Now delete all of the children of this parent 50767754Smsmith * all at the same time. 50867754Smsmith */ 50967754Smsmith AcpiNsDeleteChildren (ParentNode); 51067754Smsmith 51185756Smsmith /* New "last child" is this parent node */ 51267754Smsmith 51367754Smsmith ChildNode = ParentNode; 51467754Smsmith 51585756Smsmith /* Move up the tree to the grandparent */ 51667754Smsmith 51791116Smsmith ParentNode = AcpiNsGetParentNode (ParentNode); 51867754Smsmith } 51967754Smsmith } 52067754Smsmith 52167754Smsmith return_ACPI_STATUS (AE_OK); 52267754Smsmith} 52367754Smsmith 52467754Smsmith 52567754Smsmith/******************************************************************************* 52667754Smsmith * 52767754Smsmith * FUNCTION: AcpiNsRemoveReference 52867754Smsmith * 52985756Smsmith * PARAMETERS: Node - Named node whose reference count is to be 53083174Smsmith * decremented 53167754Smsmith * 53267754Smsmith * RETURN: None. 53367754Smsmith * 53467754Smsmith * DESCRIPTION: Remove a Node reference. Decrements the reference count 53585756Smsmith * of all parent Nodes up to the root. Any node along 53667754Smsmith * the way that reaches zero references is freed. 53767754Smsmith * 53867754Smsmith ******************************************************************************/ 53967754Smsmith 54069450Smsmithstatic void 54167754SmsmithAcpiNsRemoveReference ( 54267754Smsmith ACPI_NAMESPACE_NODE *Node) 54367754Smsmith{ 54491116Smsmith ACPI_NAMESPACE_NODE *ParentNode; 54591116Smsmith ACPI_NAMESPACE_NODE *ThisNode; 54667754Smsmith 54767754Smsmith 54891116Smsmith ACPI_FUNCTION_ENTRY (); 54983174Smsmith 55083174Smsmith 55167754Smsmith /* 55285756Smsmith * Decrement the reference count(s) of this node and all 55385756Smsmith * nodes up to the root, Delete anything with zero remaining references. 55467754Smsmith */ 55591116Smsmith ThisNode = Node; 55691116Smsmith while (ThisNode) 55767754Smsmith { 55891116Smsmith /* Prepare to move up to parent */ 55967754Smsmith 56091116Smsmith ParentNode = AcpiNsGetParentNode (ThisNode); 56167754Smsmith 56291116Smsmith /* Decrement the reference count on this node */ 56391116Smsmith 56491116Smsmith ThisNode->ReferenceCount--; 56591116Smsmith 56685756Smsmith /* Delete the node if no more references */ 56767754Smsmith 56891116Smsmith if (!ThisNode->ReferenceCount) 56967754Smsmith { 57085756Smsmith /* Delete all children and delete the node */ 57167754Smsmith 57291116Smsmith AcpiNsDeleteChildren (ThisNode); 57391116Smsmith AcpiNsDeleteNode (ThisNode); 57467754Smsmith } 57567754Smsmith 57691116Smsmith ThisNode = ParentNode; 57767754Smsmith } 57867754Smsmith} 57967754Smsmith 58067754Smsmith 58167754Smsmith/******************************************************************************* 58267754Smsmith * 58367754Smsmith * FUNCTION: AcpiNsDeleteNamespaceByOwner 58467754Smsmith * 58583174Smsmith * PARAMETERS: OwnerId - All nodes with this owner will be deleted 58667754Smsmith * 58783174Smsmith * RETURN: Status 58867754Smsmith * 58967754Smsmith * DESCRIPTION: Delete entries within the namespace that are owned by a 59067754Smsmith * specific ID. Used to delete entire ACPI tables. All 59167754Smsmith * reference counts are updated. 59267754Smsmith * 59367754Smsmith ******************************************************************************/ 59467754Smsmith 59567754SmsmithACPI_STATUS 59667754SmsmithAcpiNsDeleteNamespaceByOwner ( 59767754Smsmith UINT16 OwnerId) 59867754Smsmith{ 59967754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 60091116Smsmith ACPI_NAMESPACE_NODE *DeletionNode; 60167754Smsmith UINT32 Level; 60267754Smsmith ACPI_NAMESPACE_NODE *ParentNode; 60367754Smsmith 60467754Smsmith 60591116Smsmith ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId); 60667754Smsmith 60767754Smsmith 60891116Smsmith ParentNode = AcpiGbl_RootNode; 60991116Smsmith ChildNode = NULL; 61091116Smsmith DeletionNode = NULL; 61191116Smsmith Level = 1; 61267754Smsmith 61367754Smsmith /* 61485756Smsmith * Traverse the tree of nodes until we bubble back up 61567754Smsmith * to where we started. 61667754Smsmith */ 61767754Smsmith while (Level > 0) 61867754Smsmith { 61991116Smsmith /* 62091116Smsmith * Get the next child of this parent node. When ChildNode is NULL, 62191116Smsmith * the first child of the parent is returned 62291116Smsmith */ 62391116Smsmith ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 62485756Smsmith 62591116Smsmith if (DeletionNode) 62691116Smsmith { 62791116Smsmith AcpiNsRemoveReference (DeletionNode); 62891116Smsmith DeletionNode = NULL; 62991116Smsmith } 63091116Smsmith 63167754Smsmith if (ChildNode) 63267754Smsmith { 63367754Smsmith if (ChildNode->OwnerId == OwnerId) 63467754Smsmith { 63591116Smsmith /* Found a matching child node - detach any attached object */ 63685756Smsmith 63785756Smsmith AcpiNsDetachObject (ChildNode); 63867754Smsmith } 63967754Smsmith 64085756Smsmith /* Check if this node has any children */ 64167754Smsmith 64291116Smsmith if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 64367754Smsmith { 64467754Smsmith /* 64585756Smsmith * There is at least one child of this node, 64685756Smsmith * visit the node 64767754Smsmith */ 64867754Smsmith Level++; 64967754Smsmith ParentNode = ChildNode; 65091116Smsmith ChildNode = NULL; 65167754Smsmith } 65267754Smsmith else if (ChildNode->OwnerId == OwnerId) 65367754Smsmith { 65491116Smsmith DeletionNode = ChildNode; 65567754Smsmith } 65667754Smsmith } 65767754Smsmith else 65867754Smsmith { 65967754Smsmith /* 66085756Smsmith * No more children of this parent node. 66185756Smsmith * Move up to the grandparent. 66267754Smsmith */ 66367754Smsmith Level--; 66467754Smsmith if (Level != 0) 66567754Smsmith { 66667754Smsmith if (ParentNode->OwnerId == OwnerId) 66767754Smsmith { 66891116Smsmith DeletionNode = ParentNode; 66967754Smsmith } 67067754Smsmith } 67167754Smsmith 67285756Smsmith /* New "last child" is this parent node */ 67367754Smsmith 67467754Smsmith ChildNode = ParentNode; 67567754Smsmith 67685756Smsmith /* Move up the tree to the grandparent */ 67767754Smsmith 67891116Smsmith ParentNode = AcpiNsGetParentNode (ParentNode); 67967754Smsmith } 68067754Smsmith } 68167754Smsmith 68267754Smsmith return_ACPI_STATUS (AE_OK); 68367754Smsmith} 68467754Smsmith 68567754Smsmith 686