nsalloc.c revision 138287
167754Smsmith/******************************************************************************* 267754Smsmith * 367754Smsmith * Module Name: nsalloc - Namespace allocation and deletion utilities 4138287Smarks * $Revision: 88 $ 567754Smsmith * 667754Smsmith ******************************************************************************/ 767754Smsmith 867754Smsmith/****************************************************************************** 967754Smsmith * 1067754Smsmith * 1. Copyright Notice 1167754Smsmith * 12126372Snjl * Some or all of this work - Copyright (c) 1999 - 2004, 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 12367754Smsmith 12477424Smsmith#define _COMPONENT ACPI_NAMESPACE 12591116Smsmith ACPI_MODULE_NAME ("nsalloc") 12667754Smsmith 12767754Smsmith 12867754Smsmith/******************************************************************************* 12967754Smsmith * 13067754Smsmith * FUNCTION: AcpiNsCreateNode 13167754Smsmith * 13283174Smsmith * PARAMETERS: AcpiName - Name of the new node 13367754Smsmith * 13467754Smsmith * RETURN: None 13567754Smsmith * 13683174Smsmith * DESCRIPTION: Create a namespace node 13767754Smsmith * 13867754Smsmith ******************************************************************************/ 13967754Smsmith 14067754SmsmithACPI_NAMESPACE_NODE * 14167754SmsmithAcpiNsCreateNode ( 14284491Smsmith UINT32 Name) 14367754Smsmith{ 14467754Smsmith ACPI_NAMESPACE_NODE *Node; 14567754Smsmith 14683174Smsmith 14791116Smsmith ACPI_FUNCTION_TRACE ("NsCreateNode"); 14867754Smsmith 14967754Smsmith 15080062Smsmith Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); 15167754Smsmith if (!Node) 15267754Smsmith { 15367754Smsmith return_PTR (NULL); 15467754Smsmith } 15567754Smsmith 15682367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++); 15767754Smsmith 15899146Siwasaki Node->Name.Integer = Name; 15967754Smsmith Node->ReferenceCount = 1; 16091116Smsmith ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 16167754Smsmith 16267754Smsmith return_PTR (Node); 16367754Smsmith} 16467754Smsmith 16567754Smsmith 16667754Smsmith/******************************************************************************* 16767754Smsmith * 16867754Smsmith * FUNCTION: AcpiNsDeleteNode 16967754Smsmith * 17083174Smsmith * PARAMETERS: Node - Node to be deleted 17167754Smsmith * 17267754Smsmith * RETURN: None 17367754Smsmith * 17483174Smsmith * DESCRIPTION: Delete a namespace node 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 18791116Smsmith ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node); 18867754Smsmith 18983174Smsmith 19091116Smsmith ParentNode = AcpiNsGetParentNode (Node); 19167754Smsmith 19267754Smsmith PrevNode = NULL; 19367754Smsmith NextNode = ParentNode->Child; 19467754Smsmith 195115351Snjl /* Find the node that is the previous peer in the parent's child list */ 196115351Snjl 19767754Smsmith while (NextNode != Node) 19867754Smsmith { 19967754Smsmith PrevNode = NextNode; 20067754Smsmith NextNode = PrevNode->Peer; 20167754Smsmith } 20267754Smsmith 20367754Smsmith if (PrevNode) 20467754Smsmith { 205115351Snjl /* Node is not first child, unlink it */ 206115351Snjl 20767754Smsmith PrevNode->Peer = NextNode->Peer; 20867754Smsmith if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 20967754Smsmith { 21067754Smsmith PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 21167754Smsmith } 21267754Smsmith } 21367754Smsmith else 21467754Smsmith { 215115351Snjl /* Node is first child (has no previous peer) */ 216115351Snjl 217115351Snjl if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 218115351Snjl { 219115351Snjl /* No peers at all */ 220115351Snjl 221115351Snjl ParentNode->Child = NULL; 222115351Snjl } 223115351Snjl else 224115351Snjl { /* Link peer list to parent */ 225115351Snjl 226115351Snjl ParentNode->Child = NextNode->Peer; 227115351Snjl } 22867754Smsmith } 22967754Smsmith 23067754Smsmith 23182367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 23267754Smsmith 23367754Smsmith /* 23487031Smsmith * Detach an object if there is one then delete the node 23567754Smsmith */ 23687031Smsmith AcpiNsDetachObject (Node); 23780062Smsmith ACPI_MEM_FREE (Node); 23867754Smsmith return_VOID; 23967754Smsmith} 24067754Smsmith 24167754Smsmith 242107325Siwasaki#ifdef ACPI_ALPHABETIC_NAMESPACE 24367754Smsmith/******************************************************************************* 24467754Smsmith * 245114237Snjl * FUNCTION: AcpiNsCompareNames 246107325Siwasaki * 247107325Siwasaki * PARAMETERS: Name1 - First name to compare 248107325Siwasaki * Name2 - Second name to compare 249107325Siwasaki * 250107325Siwasaki * RETURN: value from strncmp 251107325Siwasaki * 252114237Snjl * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an 253107325Siwasaki * underscore are forced to be alphabetically first. 254107325Siwasaki * 255107325Siwasaki ******************************************************************************/ 256107325Siwasaki 257107325Siwasakiint 258107325SiwasakiAcpiNsCompareNames ( 259107325Siwasaki char *Name1, 260107325Siwasaki char *Name2) 261107325Siwasaki{ 262107325Siwasaki char ReversedName1[ACPI_NAME_SIZE]; 263107325Siwasaki char ReversedName2[ACPI_NAME_SIZE]; 264107325Siwasaki UINT32 i; 265107325Siwasaki UINT32 j; 266107325Siwasaki 267107325Siwasaki 268107325Siwasaki /* 269107325Siwasaki * Replace all instances of "underscore" with a value that is smaller so 270107325Siwasaki * that all names that are prefixed with underscore(s) are alphabetically 271107325Siwasaki * first. 272107325Siwasaki * 273107325Siwasaki * Reverse the name bytewise so we can just do a 32-bit compare instead 274107325Siwasaki * of a strncmp. 275107325Siwasaki */ 276107325Siwasaki for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) 277107325Siwasaki { 278107325Siwasaki ReversedName1[j] = Name1[i]; 279107325Siwasaki if (Name1[i] == '_') 280107325Siwasaki { 281107325Siwasaki ReversedName1[j] = '*'; 282107325Siwasaki } 283107325Siwasaki 284107325Siwasaki ReversedName2[j] = Name2[i]; 285107325Siwasaki if (Name2[i] == '_') 286107325Siwasaki { 287107325Siwasaki ReversedName2[j] = '*'; 288107325Siwasaki } 289107325Siwasaki } 290107325Siwasaki 291107325Siwasaki return (*(int *) ReversedName1 - *(int *) ReversedName2); 292107325Siwasaki} 293107325Siwasaki#endif 294107325Siwasaki 295107325Siwasaki 296107325Siwasaki/******************************************************************************* 297107325Siwasaki * 29867754Smsmith * FUNCTION: AcpiNsInstallNode 29967754Smsmith * 30067754Smsmith * PARAMETERS: WalkState - Current state of the walk 30167754Smsmith * ParentNode - The parent of the new Node 30283174Smsmith * Node - The new Node to install 30367754Smsmith * Type - ACPI object type of the new Node 30467754Smsmith * 30567754Smsmith * RETURN: None 30667754Smsmith * 30787031Smsmith * DESCRIPTION: Initialize a new namespace node and install it amongst 30887031Smsmith * its peers. 30967754Smsmith * 310107325Siwasaki * Note: Current namespace lookup is linear search. However, the 311107325Siwasaki * nodes are linked in alphabetical order to 1) put all reserved 312107325Siwasaki * names (start with underscore) first, and to 2) make a readable 313107325Siwasaki * namespace dump. 31487031Smsmith * 31567754Smsmith ******************************************************************************/ 31667754Smsmith 31767754Smsmithvoid 31867754SmsmithAcpiNsInstallNode ( 31967754Smsmith ACPI_WALK_STATE *WalkState, 32067754Smsmith ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 32183174Smsmith ACPI_NAMESPACE_NODE *Node, /* New Child*/ 32291116Smsmith ACPI_OBJECT_TYPE Type) 32367754Smsmith{ 324117521Snjl UINT16 OwnerId = 0; 32567754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 326107325Siwasaki#ifdef ACPI_ALPHABETIC_NAMESPACE 32767754Smsmith 328107325Siwasaki ACPI_NAMESPACE_NODE *PreviousChildNode; 329107325Siwasaki#endif 33067754Smsmith 331107325Siwasaki 33291116Smsmith ACPI_FUNCTION_TRACE ("NsInstallNode"); 33367754Smsmith 33467754Smsmith 33567754Smsmith /* 33667754Smsmith * Get the owner ID from the Walk state 33767754Smsmith * The owner ID is used to track table deletion and 33867754Smsmith * deletion of objects created by methods 33967754Smsmith */ 34067754Smsmith if (WalkState) 34167754Smsmith { 34267754Smsmith OwnerId = WalkState->OwnerId; 34367754Smsmith } 34467754Smsmith 34587031Smsmith /* Link the new entry into the parent and existing children */ 34667754Smsmith 34767754Smsmith ChildNode = ParentNode->Child; 34867754Smsmith if (!ChildNode) 34967754Smsmith { 35067754Smsmith ParentNode->Child = Node; 351107325Siwasaki Node->Flags |= ANOBJ_END_OF_PEER_LIST; 352107325Siwasaki Node->Peer = ParentNode; 35367754Smsmith } 35467754Smsmith else 35567754Smsmith { 356107325Siwasaki#ifdef ACPI_ALPHABETIC_NAMESPACE 357107325Siwasaki /* 358129684Snjl * Walk the list whilst searching for the correct 359107325Siwasaki * alphabetic placement. 360107325Siwasaki */ 361107325Siwasaki PreviousChildNode = NULL; 362123315Snjl while (AcpiNsCompareNames (AcpiUtGetNodeName (ChildNode), AcpiUtGetNodeName (Node)) < 0) 363107325Siwasaki { 364107325Siwasaki if (ChildNode->Flags & ANOBJ_END_OF_PEER_LIST) 365107325Siwasaki { 366107325Siwasaki /* Last peer; Clear end-of-list flag */ 367107325Siwasaki 368107325Siwasaki ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 369107325Siwasaki 370107325Siwasaki /* This node is the new peer to the child node */ 371107325Siwasaki 372107325Siwasaki ChildNode->Peer = Node; 373107325Siwasaki 374107325Siwasaki /* This node is the new end-of-list */ 375107325Siwasaki 376107325Siwasaki Node->Flags |= ANOBJ_END_OF_PEER_LIST; 377107325Siwasaki Node->Peer = ParentNode; 378107325Siwasaki break; 379107325Siwasaki } 380107325Siwasaki 381107325Siwasaki /* Get next peer */ 382107325Siwasaki 383107325Siwasaki PreviousChildNode = ChildNode; 384107325Siwasaki ChildNode = ChildNode->Peer; 385107325Siwasaki } 386107325Siwasaki 387107325Siwasaki /* Did the node get inserted at the end-of-list? */ 388107325Siwasaki 389107325Siwasaki if (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 390107325Siwasaki { 391114237Snjl /* 392107325Siwasaki * Loop above terminated without reaching the end-of-list. 393107325Siwasaki * Insert the new node at the current location 394107325Siwasaki */ 395107325Siwasaki if (PreviousChildNode) 396107325Siwasaki { 397107325Siwasaki /* Insert node alphabetically */ 398107325Siwasaki 399107325Siwasaki Node->Peer = ChildNode; 400107325Siwasaki PreviousChildNode->Peer = Node; 401107325Siwasaki } 402107325Siwasaki else 403107325Siwasaki { 404107325Siwasaki /* Insert node alphabetically at start of list */ 405107325Siwasaki 406107325Siwasaki Node->Peer = ChildNode; 407107325Siwasaki ParentNode->Child = Node; 408107325Siwasaki } 409107325Siwasaki } 410107325Siwasaki#else 41167754Smsmith while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 41267754Smsmith { 41367754Smsmith ChildNode = ChildNode->Peer; 41467754Smsmith } 41567754Smsmith 41667754Smsmith ChildNode->Peer = Node; 41767754Smsmith 41867754Smsmith /* Clear end-of-list flag */ 41967754Smsmith 42067754Smsmith ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 421107325Siwasaki Node->Flags |= ANOBJ_END_OF_PEER_LIST; 422107325Siwasaki Node->Peer = ParentNode; 423107325Siwasaki#endif 42467754Smsmith } 42567754Smsmith 42667754Smsmith /* Init the new entry */ 42767754Smsmith 428107325Siwasaki Node->OwnerId = OwnerId; 429107325Siwasaki Node->Type = (UINT8) Type; 43067754Smsmith 431129684Snjl ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 432127175Snjl "%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n", 433127175Snjl AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type), Node, OwnerId, 434123315Snjl AcpiUtGetNodeName (ParentNode), AcpiUtGetTypeName (ParentNode->Type), 435127175Snjl ParentNode)); 43667754Smsmith 43767754Smsmith /* 43867754Smsmith * Increment the reference count(s) of all parents up to 43967754Smsmith * the root! 44067754Smsmith */ 44191116Smsmith while ((Node = AcpiNsGetParentNode (Node)) != NULL) 44267754Smsmith { 44367754Smsmith Node->ReferenceCount++; 44467754Smsmith } 44567754Smsmith 44667754Smsmith return_VOID; 44767754Smsmith} 44867754Smsmith 44967754Smsmith 45067754Smsmith/******************************************************************************* 45167754Smsmith * 45267754Smsmith * FUNCTION: AcpiNsDeleteChildren 45367754Smsmith * 45467754Smsmith * PARAMETERS: ParentNode - Delete this objects children 45567754Smsmith * 45667754Smsmith * RETURN: None. 45767754Smsmith * 45891116Smsmith * DESCRIPTION: Delete all children of the parent object. In other words, 45991116Smsmith * deletes a "scope". 46067754Smsmith * 46167754Smsmith ******************************************************************************/ 46267754Smsmith 46367754Smsmithvoid 46467754SmsmithAcpiNsDeleteChildren ( 46567754Smsmith ACPI_NAMESPACE_NODE *ParentNode) 46667754Smsmith{ 46767754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 46867754Smsmith ACPI_NAMESPACE_NODE *NextNode; 469115351Snjl ACPI_NAMESPACE_NODE *Node; 47067754Smsmith UINT8 Flags; 47167754Smsmith 47267754Smsmith 47391116Smsmith ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode); 47467754Smsmith 47567754Smsmith 47667754Smsmith if (!ParentNode) 47767754Smsmith { 47867754Smsmith return_VOID; 47967754Smsmith } 48067754Smsmith 48167754Smsmith /* If no children, all done! */ 48267754Smsmith 48367754Smsmith ChildNode = ParentNode->Child; 48467754Smsmith if (!ChildNode) 48567754Smsmith { 48667754Smsmith return_VOID; 48767754Smsmith } 48867754Smsmith 48967754Smsmith /* 49067754Smsmith * Deallocate all children at this level 49167754Smsmith */ 49267754Smsmith do 49367754Smsmith { 49467754Smsmith /* Get the things we need */ 49567754Smsmith 49667754Smsmith NextNode = ChildNode->Peer; 49767754Smsmith Flags = ChildNode->Flags; 49867754Smsmith 49967754Smsmith /* Grandchildren should have all been deleted already */ 50067754Smsmith 50167754Smsmith if (ChildNode->Child) 50267754Smsmith { 50385756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 50467754Smsmith ParentNode, ChildNode)); 50567754Smsmith } 50667754Smsmith 50767754Smsmith /* Now we can free this child object */ 50867754Smsmith 50982367Smsmith ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 51067754Smsmith 51199146Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 51267754Smsmith ChildNode, AcpiGbl_CurrentNodeCount)); 51367754Smsmith 51467754Smsmith /* 51585756Smsmith * Detach an object if there is one, then free the child node 51667754Smsmith */ 51785756Smsmith AcpiNsDetachObject (ChildNode); 518115351Snjl 519115351Snjl /* 520115351Snjl * Decrement the reference count(s) of all parents up to 521115351Snjl * the root! (counts were incremented when the node was created) 522115351Snjl */ 523115351Snjl Node = ChildNode; 524115351Snjl while ((Node = AcpiNsGetParentNode (Node)) != NULL) 525115351Snjl { 526115351Snjl Node->ReferenceCount--; 527115351Snjl } 528115351Snjl 529115351Snjl /* There should be only one reference remaining on this node */ 530115351Snjl 531115351Snjl if (ChildNode->ReferenceCount != 1) 532115351Snjl { 533115351Snjl ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n", 534115351Snjl ChildNode->ReferenceCount, ChildNode)); 535115351Snjl } 536115351Snjl 537115351Snjl /* Now we can delete the node */ 538115351Snjl 53980062Smsmith ACPI_MEM_FREE (ChildNode); 54067754Smsmith 54167754Smsmith /* And move on to the next child in the list */ 54267754Smsmith 54367754Smsmith ChildNode = NextNode; 54467754Smsmith 54567754Smsmith } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 54667754Smsmith 54767754Smsmith 54867754Smsmith /* Clear the parent's child pointer */ 54967754Smsmith 55067754Smsmith ParentNode->Child = NULL; 55167754Smsmith 55267754Smsmith return_VOID; 55367754Smsmith} 55467754Smsmith 55567754Smsmith 55667754Smsmith/******************************************************************************* 55767754Smsmith * 55867754Smsmith * FUNCTION: AcpiNsDeleteNamespaceSubtree 55967754Smsmith * 56083174Smsmith * PARAMETERS: ParentNode - Root of the subtree to be deleted 56167754Smsmith * 56267754Smsmith * RETURN: None. 56367754Smsmith * 56467754Smsmith * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 56591116Smsmith * stored within the subtree. 56667754Smsmith * 56767754Smsmith ******************************************************************************/ 56867754Smsmith 56999679Siwasakivoid 57067754SmsmithAcpiNsDeleteNamespaceSubtree ( 57167754Smsmith ACPI_NAMESPACE_NODE *ParentNode) 57267754Smsmith{ 57384491Smsmith ACPI_NAMESPACE_NODE *ChildNode = NULL; 57484491Smsmith UINT32 Level = 1; 57567754Smsmith 57667754Smsmith 57791116Smsmith ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree"); 57867754Smsmith 57967754Smsmith 58067754Smsmith if (!ParentNode) 58167754Smsmith { 58299679Siwasaki return_VOID; 58367754Smsmith } 58467754Smsmith 58567754Smsmith /* 58667754Smsmith * Traverse the tree of objects until we bubble back up 58767754Smsmith * to where we started. 58867754Smsmith */ 58967754Smsmith while (Level > 0) 59067754Smsmith { 59185756Smsmith /* Get the next node in this scope (NULL if none) */ 59285756Smsmith 59385756Smsmith ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, 59467754Smsmith ChildNode); 59567754Smsmith if (ChildNode) 59667754Smsmith { 59785756Smsmith /* Found a child node - detach any attached object */ 59867754Smsmith 59985756Smsmith AcpiNsDetachObject (ChildNode); 60067754Smsmith 60185756Smsmith /* Check if this node has any children */ 60267754Smsmith 603138287Smarks if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 60467754Smsmith { 60567754Smsmith /* 60685756Smsmith * There is at least one child of this node, 60785756Smsmith * visit the node 60867754Smsmith */ 60967754Smsmith Level++; 610138287Smarks ParentNode = ChildNode; 611138287Smarks ChildNode = NULL; 61267754Smsmith } 61367754Smsmith } 61467754Smsmith else 61567754Smsmith { 61667754Smsmith /* 61785756Smsmith * No more children of this parent node. 61885756Smsmith * Move up to the grandparent. 61967754Smsmith */ 62067754Smsmith Level--; 62167754Smsmith 62267754Smsmith /* 62367754Smsmith * Now delete all of the children of this parent 62467754Smsmith * all at the same time. 62567754Smsmith */ 62667754Smsmith AcpiNsDeleteChildren (ParentNode); 62767754Smsmith 62885756Smsmith /* New "last child" is this parent node */ 62967754Smsmith 63067754Smsmith ChildNode = ParentNode; 63167754Smsmith 63285756Smsmith /* Move up the tree to the grandparent */ 63367754Smsmith 63491116Smsmith ParentNode = AcpiNsGetParentNode (ParentNode); 63567754Smsmith } 63667754Smsmith } 63767754Smsmith 63899679Siwasaki return_VOID; 63967754Smsmith} 64067754Smsmith 64167754Smsmith 64267754Smsmith/******************************************************************************* 64367754Smsmith * 64467754Smsmith * FUNCTION: AcpiNsRemoveReference 64567754Smsmith * 64685756Smsmith * PARAMETERS: Node - Named node whose reference count is to be 64783174Smsmith * decremented 64867754Smsmith * 64967754Smsmith * RETURN: None. 65067754Smsmith * 65167754Smsmith * DESCRIPTION: Remove a Node reference. Decrements the reference count 65285756Smsmith * of all parent Nodes up to the root. Any node along 65367754Smsmith * the way that reaches zero references is freed. 65467754Smsmith * 65567754Smsmith ******************************************************************************/ 65667754Smsmith 657117521Snjlvoid 65867754SmsmithAcpiNsRemoveReference ( 65967754Smsmith ACPI_NAMESPACE_NODE *Node) 66067754Smsmith{ 66191116Smsmith ACPI_NAMESPACE_NODE *ParentNode; 66291116Smsmith ACPI_NAMESPACE_NODE *ThisNode; 66367754Smsmith 66467754Smsmith 66591116Smsmith ACPI_FUNCTION_ENTRY (); 66683174Smsmith 66783174Smsmith 66867754Smsmith /* 66985756Smsmith * Decrement the reference count(s) of this node and all 67085756Smsmith * nodes up to the root, Delete anything with zero remaining references. 67167754Smsmith */ 67291116Smsmith ThisNode = Node; 67391116Smsmith while (ThisNode) 67467754Smsmith { 67591116Smsmith /* Prepare to move up to parent */ 67667754Smsmith 67791116Smsmith ParentNode = AcpiNsGetParentNode (ThisNode); 67867754Smsmith 67991116Smsmith /* Decrement the reference count on this node */ 68091116Smsmith 68191116Smsmith ThisNode->ReferenceCount--; 68291116Smsmith 68385756Smsmith /* Delete the node if no more references */ 68467754Smsmith 68591116Smsmith if (!ThisNode->ReferenceCount) 68667754Smsmith { 68785756Smsmith /* Delete all children and delete the node */ 68867754Smsmith 68991116Smsmith AcpiNsDeleteChildren (ThisNode); 69091116Smsmith AcpiNsDeleteNode (ThisNode); 69167754Smsmith } 69267754Smsmith 69391116Smsmith ThisNode = ParentNode; 69467754Smsmith } 69567754Smsmith} 69667754Smsmith 69767754Smsmith 69867754Smsmith/******************************************************************************* 69967754Smsmith * 70067754Smsmith * FUNCTION: AcpiNsDeleteNamespaceByOwner 70167754Smsmith * 70283174Smsmith * PARAMETERS: OwnerId - All nodes with this owner will be deleted 70367754Smsmith * 70483174Smsmith * RETURN: Status 70567754Smsmith * 70667754Smsmith * DESCRIPTION: Delete entries within the namespace that are owned by a 70767754Smsmith * specific ID. Used to delete entire ACPI tables. All 70867754Smsmith * reference counts are updated. 70967754Smsmith * 71067754Smsmith ******************************************************************************/ 71167754Smsmith 71299679Siwasakivoid 71367754SmsmithAcpiNsDeleteNamespaceByOwner ( 71467754Smsmith UINT16 OwnerId) 71567754Smsmith{ 71667754Smsmith ACPI_NAMESPACE_NODE *ChildNode; 71791116Smsmith ACPI_NAMESPACE_NODE *DeletionNode; 71867754Smsmith UINT32 Level; 71967754Smsmith ACPI_NAMESPACE_NODE *ParentNode; 72067754Smsmith 72167754Smsmith 72291116Smsmith ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId); 72367754Smsmith 72467754Smsmith 72591116Smsmith ParentNode = AcpiGbl_RootNode; 72691116Smsmith ChildNode = NULL; 72791116Smsmith DeletionNode = NULL; 72891116Smsmith Level = 1; 72967754Smsmith 73067754Smsmith /* 73185756Smsmith * Traverse the tree of nodes until we bubble back up 73267754Smsmith * to where we started. 73367754Smsmith */ 73467754Smsmith while (Level > 0) 73567754Smsmith { 73691116Smsmith /* 73791116Smsmith * Get the next child of this parent node. When ChildNode is NULL, 73891116Smsmith * the first child of the parent is returned 73991116Smsmith */ 74091116Smsmith ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 74185756Smsmith 74291116Smsmith if (DeletionNode) 74391116Smsmith { 74491116Smsmith AcpiNsRemoveReference (DeletionNode); 74591116Smsmith DeletionNode = NULL; 74691116Smsmith } 74791116Smsmith 74867754Smsmith if (ChildNode) 74967754Smsmith { 75067754Smsmith if (ChildNode->OwnerId == OwnerId) 75167754Smsmith { 75291116Smsmith /* Found a matching child node - detach any attached object */ 75385756Smsmith 75485756Smsmith AcpiNsDetachObject (ChildNode); 75567754Smsmith } 75667754Smsmith 75785756Smsmith /* Check if this node has any children */ 75867754Smsmith 75991116Smsmith if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 76067754Smsmith { 76167754Smsmith /* 76285756Smsmith * There is at least one child of this node, 76385756Smsmith * visit the node 76467754Smsmith */ 76567754Smsmith Level++; 766138287Smarks ParentNode = ChildNode; 767138287Smarks ChildNode = NULL; 76867754Smsmith } 76967754Smsmith else if (ChildNode->OwnerId == OwnerId) 77067754Smsmith { 77191116Smsmith DeletionNode = ChildNode; 77267754Smsmith } 77367754Smsmith } 77467754Smsmith else 77567754Smsmith { 77667754Smsmith /* 77785756Smsmith * No more children of this parent node. 77885756Smsmith * Move up to the grandparent. 77967754Smsmith */ 78067754Smsmith Level--; 78167754Smsmith if (Level != 0) 78267754Smsmith { 78367754Smsmith if (ParentNode->OwnerId == OwnerId) 78467754Smsmith { 78591116Smsmith DeletionNode = ParentNode; 78667754Smsmith } 78767754Smsmith } 78867754Smsmith 78985756Smsmith /* New "last child" is this parent node */ 79067754Smsmith 79167754Smsmith ChildNode = ParentNode; 79267754Smsmith 79385756Smsmith /* Move up the tree to the grandparent */ 79467754Smsmith 79591116Smsmith ParentNode = AcpiNsGetParentNode (ParentNode); 79667754Smsmith } 79767754Smsmith } 79867754Smsmith 79999679Siwasaki return_VOID; 80067754Smsmith} 80167754Smsmith 80267754Smsmith 803