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