nsalloc.c revision 107325
1230557Sjimharris/******************************************************************************* 2230557Sjimharris * 3230557Sjimharris * Module Name: nsalloc - Namespace allocation and deletion utilities 4230557Sjimharris * $Revision: 77 $ 5230557Sjimharris * 6230557Sjimharris ******************************************************************************/ 7230557Sjimharris 8230557Sjimharris/****************************************************************************** 9230557Sjimharris * 10230557Sjimharris * 1. Copyright Notice 11230557Sjimharris * 12230557Sjimharris * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 13230557Sjimharris * All rights reserved. 14230557Sjimharris * 15230557Sjimharris * 2. License 16230557Sjimharris * 17230557Sjimharris * 2.1. This is your license from Intel Corp. under its intellectual property 18230557Sjimharris * rights. You may have additional license terms from the party that provided 19230557Sjimharris * you this software, covering your right to use that party's intellectual 20230557Sjimharris * property rights. 21230557Sjimharris * 22230557Sjimharris * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23230557Sjimharris * copy of the source code appearing in this file ("Covered Code") an 24230557Sjimharris * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25230557Sjimharris * base code distributed originally by Intel ("Original Intel Code") to copy, 26230557Sjimharris * make derivatives, distribute, use and display any portion of the Covered 27230557Sjimharris * Code in any form, with the right to sublicense such rights; and 28230557Sjimharris * 29230557Sjimharris * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30230557Sjimharris * license (with the right to sublicense), under only those claims of Intel 31230557Sjimharris * patents that are infringed by the Original Intel Code, to make, use, sell, 32230557Sjimharris * offer to sell, and import the Covered Code and derivative works thereof 33230557Sjimharris * solely to the minimum extent necessary to exercise the above copyright 34230557Sjimharris * license, and in no event shall the patent license extend to any additions 35230557Sjimharris * to or modifications of the Original Intel Code. No other license or right 36230557Sjimharris * is granted directly or by implication, estoppel or otherwise; 37230557Sjimharris * 38230557Sjimharris * The above copyright and patent license is granted only if the following 39230557Sjimharris * conditions are met: 40230557Sjimharris * 41230557Sjimharris * 3. Conditions 42230557Sjimharris * 43230557Sjimharris * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44230557Sjimharris * Redistribution of source code of any substantial portion of the Covered 45230557Sjimharris * Code or modification with rights to further distribute source must include 46230557Sjimharris * the above Copyright Notice, the above License, this list of Conditions, 47230557Sjimharris * and the following Disclaimer and Export Compliance provision. In addition, 48230557Sjimharris * Licensee must cause all Covered Code to which Licensee contributes to 49230557Sjimharris * contain a file documenting the changes Licensee made to create that Covered 50230557Sjimharris * Code and the date of any change. Licensee must include in that file the 51230557Sjimharris * documentation of any changes made by any predecessor Licensee. Licensee 52230557Sjimharris * must include a prominent statement that the modification is derived, 53230557Sjimharris * directly or indirectly, from Original Intel Code. 54230557Sjimharris * 55230557Sjimharris * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56230557Sjimharris * Redistribution of source code of any substantial portion of the Covered 57230557Sjimharris * Code or modification without rights to further distribute source must 58230557Sjimharris * include the following Disclaimer and Export Compliance provision in the 59230557Sjimharris * documentation and/or other materials provided with distribution. In 60230557Sjimharris * addition, Licensee may not authorize further sublicense of source of any 61230557Sjimharris * portion of the Covered Code, and must include terms to the effect that the 62230557Sjimharris * license from Licensee to its licensee is limited to the intellectual 63230557Sjimharris * property embodied in the software Licensee provides to its licensee, and 64230557Sjimharris * not to intellectual property embodied in modifications its licensee may 65230557Sjimharris * make. 66230557Sjimharris * 67230557Sjimharris * 3.3. Redistribution of Executable. Redistribution in executable form of any 68230557Sjimharris * substantial portion of the Covered Code or modification must reproduce the 69230557Sjimharris * above Copyright Notice, and the following Disclaimer and Export Compliance 70230557Sjimharris * provision in the documentation and/or other materials provided with the 71230557Sjimharris * distribution. 72230557Sjimharris * 73230557Sjimharris * 3.4. Intel retains all right, title, and interest in and to the Original 74230557Sjimharris * Intel Code. 75230557Sjimharris * 76230557Sjimharris * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77230557Sjimharris * Intel shall be used in advertising or otherwise to promote the sale, use or 78230557Sjimharris * other dealings in products derived from or relating to the Covered Code 79230557Sjimharris * without prior written authorization from Intel. 80230557Sjimharris * 81230557Sjimharris * 4. Disclaimer and Export Compliance 82230557Sjimharris * 83230557Sjimharris * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84230557Sjimharris * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85230557Sjimharris * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86230557Sjimharris * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87230557Sjimharris * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88230557Sjimharris * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89230557Sjimharris * PARTICULAR PURPOSE. 90230557Sjimharris * 91230557Sjimharris * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92230557Sjimharris * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93230557Sjimharris * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94230557Sjimharris * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95230557Sjimharris * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96230557Sjimharris * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97230557Sjimharris * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98230557Sjimharris * LIMITED REMEDY. 99230557Sjimharris * 100230557Sjimharris * 4.3. Licensee shall not export, either directly or indirectly, any of this 101230557Sjimharris * software or system incorporating such software without first obtaining any 102230557Sjimharris * required license or other approval from the U. S. Department of Commerce or 103230557Sjimharris * any other agency or department of the United States Government. In the 104230557Sjimharris * event Licensee exports any such software from the United States or 105230557Sjimharris * re-exports any such software from a foreign destination, Licensee shall 106230557Sjimharris * ensure that the distribution and export/re-export of the software is in 107230557Sjimharris * compliance with all laws, regulations, orders, or other restrictions of the 108230557Sjimharris * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109230557Sjimharris * any of its subsidiaries will export/re-export any technical data, process, 110230557Sjimharris * software, or service, directly or indirectly, to any country for which the 111230557Sjimharris * United States government or any agency thereof requires an export license, 112230557Sjimharris * other governmental approval, or letter of assurance, without first obtaining 113230557Sjimharris * such license, approval or letter. 114230557Sjimharris * 115230557Sjimharris *****************************************************************************/ 116230557Sjimharris 117230557Sjimharris 118230557Sjimharris#define __NSALLOC_C__ 119230557Sjimharris 120230557Sjimharris#include "acpi.h" 121230557Sjimharris#include "acnamesp.h" 122230557Sjimharris 123230557Sjimharris 124230557Sjimharris#define _COMPONENT ACPI_NAMESPACE 125230557Sjimharris ACPI_MODULE_NAME ("nsalloc") 126230557Sjimharris 127230557Sjimharris 128230557Sjimharris/******************************************************************************* 129230557Sjimharris * 130230557Sjimharris * FUNCTION: AcpiNsCreateNode 131230557Sjimharris * 132230557Sjimharris * PARAMETERS: AcpiName - Name of the new node 133230557Sjimharris * 134230557Sjimharris * RETURN: None 135230557Sjimharris * 136230557Sjimharris * DESCRIPTION: Create a namespace node 137230557Sjimharris * 138230557Sjimharris ******************************************************************************/ 139230557Sjimharris 140230557SjimharrisACPI_NAMESPACE_NODE * 141230557SjimharrisAcpiNsCreateNode ( 142230557Sjimharris UINT32 Name) 143230557Sjimharris{ 144230557Sjimharris ACPI_NAMESPACE_NODE *Node; 145230557Sjimharris 146230557Sjimharris 147230557Sjimharris ACPI_FUNCTION_TRACE ("NsCreateNode"); 148230557Sjimharris 149230557Sjimharris 150230557Sjimharris Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); 151230557Sjimharris if (!Node) 152230557Sjimharris { 153230557Sjimharris return_PTR (NULL); 154230557Sjimharris } 155230557Sjimharris 156230557Sjimharris ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++); 157230557Sjimharris 158230557Sjimharris Node->Name.Integer = Name; 159230557Sjimharris Node->ReferenceCount = 1; 160230557Sjimharris ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 161230557Sjimharris 162230557Sjimharris return_PTR (Node); 163230557Sjimharris} 164230557Sjimharris 165230557Sjimharris 166230557Sjimharris/******************************************************************************* 167230557Sjimharris * 168230557Sjimharris * FUNCTION: AcpiNsDeleteNode 169230557Sjimharris * 170230557Sjimharris * PARAMETERS: Node - Node to be deleted 171230557Sjimharris * 172230557Sjimharris * RETURN: None 173230557Sjimharris * 174230557Sjimharris * DESCRIPTION: Delete a namespace node 175230557Sjimharris * 176230557Sjimharris ******************************************************************************/ 177230557Sjimharris 178230557Sjimharrisvoid 179230557SjimharrisAcpiNsDeleteNode ( 180230557Sjimharris ACPI_NAMESPACE_NODE *Node) 181230557Sjimharris{ 182230557Sjimharris ACPI_NAMESPACE_NODE *ParentNode; 183230557Sjimharris ACPI_NAMESPACE_NODE *PrevNode; 184230557Sjimharris ACPI_NAMESPACE_NODE *NextNode; 185230557Sjimharris 186230557Sjimharris 187230557Sjimharris ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node); 188230557Sjimharris 189230557Sjimharris 190230557Sjimharris ParentNode = AcpiNsGetParentNode (Node); 191230557Sjimharris 192230557Sjimharris PrevNode = NULL; 193230557Sjimharris NextNode = ParentNode->Child; 194230557Sjimharris 195230557Sjimharris while (NextNode != Node) 196230557Sjimharris { 197230557Sjimharris PrevNode = NextNode; 198230557Sjimharris NextNode = PrevNode->Peer; 199230557Sjimharris } 200230557Sjimharris 201230557Sjimharris if (PrevNode) 202230557Sjimharris { 203230557Sjimharris PrevNode->Peer = NextNode->Peer; 204230557Sjimharris if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 205230557Sjimharris { 206230557Sjimharris PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 207230557Sjimharris } 208230557Sjimharris } 209230557Sjimharris else 210230557Sjimharris { 211230557Sjimharris ParentNode->Child = NextNode->Peer; 212230557Sjimharris } 213230557Sjimharris 214230557Sjimharris 215230557Sjimharris ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 216230557Sjimharris 217230557Sjimharris /* 218230557Sjimharris * Detach an object if there is one then delete the node 219230557Sjimharris */ 220230557Sjimharris AcpiNsDetachObject (Node); 221230557Sjimharris ACPI_MEM_FREE (Node); 222230557Sjimharris return_VOID; 223230557Sjimharris} 224230557Sjimharris 225230557Sjimharris 226230557Sjimharris#ifdef ACPI_ALPHABETIC_NAMESPACE 227230557Sjimharris/******************************************************************************* 228230557Sjimharris * 229230557Sjimharris * FUNCTION: AcpiNsCompareNames 230230557Sjimharris * 231230557Sjimharris * PARAMETERS: Name1 - First name to compare 232230557Sjimharris * Name2 - Second name to compare 233230557Sjimharris * 234230557Sjimharris * RETURN: value from strncmp 235230557Sjimharris * 236230557Sjimharris * DESCRIPTION: Compare two ACPI names. Names that are prefixed with an 237230557Sjimharris * underscore are forced to be alphabetically first. 238230557Sjimharris * 239230557Sjimharris ******************************************************************************/ 240230557Sjimharris 241230557Sjimharrisint 242230557SjimharrisAcpiNsCompareNames ( 243230557Sjimharris char *Name1, 244230557Sjimharris char *Name2) 245230557Sjimharris{ 246230557Sjimharris char ReversedName1[ACPI_NAME_SIZE]; 247230557Sjimharris char ReversedName2[ACPI_NAME_SIZE]; 248230557Sjimharris UINT32 i; 249230557Sjimharris UINT32 j; 250230557Sjimharris 251230557Sjimharris 252230557Sjimharris /* 253230557Sjimharris * Replace all instances of "underscore" with a value that is smaller so 254230557Sjimharris * that all names that are prefixed with underscore(s) are alphabetically 255230557Sjimharris * first. 256230557Sjimharris * 257230557Sjimharris * Reverse the name bytewise so we can just do a 32-bit compare instead 258230557Sjimharris * of a strncmp. 259230557Sjimharris */ 260230557Sjimharris for (i = 0, j= (ACPI_NAME_SIZE - 1); i < ACPI_NAME_SIZE; i++, j--) 261230557Sjimharris { 262230557Sjimharris ReversedName1[j] = Name1[i]; 263230557Sjimharris if (Name1[i] == '_') 264230557Sjimharris { 265230557Sjimharris ReversedName1[j] = '*'; 266230557Sjimharris } 267230557Sjimharris 268230557Sjimharris ReversedName2[j] = Name2[i]; 269230557Sjimharris if (Name2[i] == '_') 270230557Sjimharris { 271230557Sjimharris ReversedName2[j] = '*'; 272230557Sjimharris } 273230557Sjimharris } 274230557Sjimharris 275230557Sjimharris return (*(int *) ReversedName1 - *(int *) ReversedName2); 276230557Sjimharris} 277230557Sjimharris#endif 278230557Sjimharris 279230557Sjimharris 280230557Sjimharris/******************************************************************************* 281230557Sjimharris * 282230557Sjimharris * FUNCTION: AcpiNsInstallNode 283230557Sjimharris * 284230557Sjimharris * PARAMETERS: WalkState - Current state of the walk 285230557Sjimharris * ParentNode - The parent of the new Node 286230557Sjimharris * Node - The new Node to install 287230557Sjimharris * Type - ACPI object type of the new Node 288230557Sjimharris * 289230557Sjimharris * RETURN: None 290230557Sjimharris * 291230557Sjimharris * DESCRIPTION: Initialize a new namespace node and install it amongst 292230557Sjimharris * its peers. 293230557Sjimharris * 294230557Sjimharris * Note: Current namespace lookup is linear search. However, the 295230557Sjimharris * nodes are linked in alphabetical order to 1) put all reserved 296230557Sjimharris * names (start with underscore) first, and to 2) make a readable 297230557Sjimharris * namespace dump. 298230557Sjimharris * 299230557Sjimharris ******************************************************************************/ 300230557Sjimharris 301230557Sjimharrisvoid 302230557SjimharrisAcpiNsInstallNode ( 303230557Sjimharris ACPI_WALK_STATE *WalkState, 304230557Sjimharris ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 305230557Sjimharris ACPI_NAMESPACE_NODE *Node, /* New Child*/ 306230557Sjimharris ACPI_OBJECT_TYPE Type) 307230557Sjimharris{ 308230557Sjimharris UINT16 OwnerId = TABLE_ID_DSDT; 309230557Sjimharris ACPI_NAMESPACE_NODE *ChildNode; 310230557Sjimharris#ifdef ACPI_ALPHABETIC_NAMESPACE 311230557Sjimharris 312230557Sjimharris ACPI_NAMESPACE_NODE *PreviousChildNode; 313230557Sjimharris#endif 314230557Sjimharris 315230557Sjimharris 316230557Sjimharris ACPI_FUNCTION_TRACE ("NsInstallNode"); 317230557Sjimharris 318230557Sjimharris 319230557Sjimharris /* 320230557Sjimharris * Get the owner ID from the Walk state 321230557Sjimharris * The owner ID is used to track table deletion and 322230557Sjimharris * deletion of objects created by methods 323230557Sjimharris */ 324230557Sjimharris if (WalkState) 325230557Sjimharris { 326230557Sjimharris OwnerId = WalkState->OwnerId; 327230557Sjimharris } 328230557Sjimharris 329230557Sjimharris /* Link the new entry into the parent and existing children */ 330230557Sjimharris 331230557Sjimharris ChildNode = ParentNode->Child; 332230557Sjimharris if (!ChildNode) 333230557Sjimharris { 334230557Sjimharris ParentNode->Child = Node; 335230557Sjimharris Node->Flags |= ANOBJ_END_OF_PEER_LIST; 336230557Sjimharris Node->Peer = ParentNode; 337230557Sjimharris } 338230557Sjimharris else 339230557Sjimharris { 340230557Sjimharris#ifdef ACPI_ALPHABETIC_NAMESPACE 341230557Sjimharris /* 342230557Sjimharris * Walk the list whilst searching for the the correct 343230557Sjimharris * alphabetic placement. 344230557Sjimharris */ 345230557Sjimharris PreviousChildNode = NULL; 346230557Sjimharris while (AcpiNsCompareNames (ChildNode->Name.Ascii, Node->Name.Ascii) < 0) 347230557Sjimharris { 348230557Sjimharris if (ChildNode->Flags & ANOBJ_END_OF_PEER_LIST) 349230557Sjimharris { 350230557Sjimharris /* Last peer; Clear end-of-list flag */ 351230557Sjimharris 352230557Sjimharris ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 353230557Sjimharris 354230557Sjimharris /* This node is the new peer to the child node */ 355230557Sjimharris 356230557Sjimharris ChildNode->Peer = Node; 357230557Sjimharris 358230557Sjimharris /* This node is the new end-of-list */ 359230557Sjimharris 360230557Sjimharris Node->Flags |= ANOBJ_END_OF_PEER_LIST; 361230557Sjimharris Node->Peer = ParentNode; 362230557Sjimharris break; 363230557Sjimharris } 364230557Sjimharris 365230557Sjimharris /* Get next peer */ 366230557Sjimharris 367230557Sjimharris PreviousChildNode = ChildNode; 368230557Sjimharris ChildNode = ChildNode->Peer; 369230557Sjimharris } 370230557Sjimharris 371230557Sjimharris /* Did the node get inserted at the end-of-list? */ 372230557Sjimharris 373230557Sjimharris if (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 374230557Sjimharris { 375230557Sjimharris /* 376230557Sjimharris * Loop above terminated without reaching the end-of-list. 377230557Sjimharris * Insert the new node at the current location 378230557Sjimharris */ 379230557Sjimharris if (PreviousChildNode) 380230557Sjimharris { 381230557Sjimharris /* Insert node alphabetically */ 382230557Sjimharris 383230557Sjimharris Node->Peer = ChildNode; 384230557Sjimharris PreviousChildNode->Peer = Node; 385230557Sjimharris } 386230557Sjimharris else 387230557Sjimharris { 388230557Sjimharris /* Insert node alphabetically at start of list */ 389230557Sjimharris 390230557Sjimharris Node->Peer = ChildNode; 391230557Sjimharris ParentNode->Child = Node; 392230557Sjimharris } 393230557Sjimharris } 394230557Sjimharris#else 395230557Sjimharris while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 396230557Sjimharris { 397230557Sjimharris ChildNode = ChildNode->Peer; 398230557Sjimharris } 399230557Sjimharris 400230557Sjimharris ChildNode->Peer = Node; 401230557Sjimharris 402230557Sjimharris /* Clear end-of-list flag */ 403230557Sjimharris 404230557Sjimharris ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 405 Node->Flags |= ANOBJ_END_OF_PEER_LIST; 406 Node->Peer = ParentNode; 407#endif 408 } 409 410 /* Init the new entry */ 411 412 Node->OwnerId = OwnerId; 413 Node->Type = (UINT8) Type; 414 415 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n", 416 Node->Name.Ascii, AcpiUtGetTypeName (Node->Type), 417 ParentNode->Name.Ascii, AcpiUtGetTypeName (ParentNode->Type), ParentNode, Node)); 418 419 /* 420 * Increment the reference count(s) of all parents up to 421 * the root! 422 */ 423 while ((Node = AcpiNsGetParentNode (Node)) != NULL) 424 { 425 Node->ReferenceCount++; 426 } 427 428 return_VOID; 429} 430 431 432/******************************************************************************* 433 * 434 * FUNCTION: AcpiNsDeleteChildren 435 * 436 * PARAMETERS: ParentNode - Delete this objects children 437 * 438 * RETURN: None. 439 * 440 * DESCRIPTION: Delete all children of the parent object. In other words, 441 * deletes a "scope". 442 * 443 ******************************************************************************/ 444 445void 446AcpiNsDeleteChildren ( 447 ACPI_NAMESPACE_NODE *ParentNode) 448{ 449 ACPI_NAMESPACE_NODE *ChildNode; 450 ACPI_NAMESPACE_NODE *NextNode; 451 UINT8 Flags; 452 453 454 ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode); 455 456 457 if (!ParentNode) 458 { 459 return_VOID; 460 } 461 462 /* If no children, all done! */ 463 464 ChildNode = ParentNode->Child; 465 if (!ChildNode) 466 { 467 return_VOID; 468 } 469 470 /* 471 * Deallocate all children at this level 472 */ 473 do 474 { 475 /* Get the things we need */ 476 477 NextNode = ChildNode->Peer; 478 Flags = ChildNode->Flags; 479 480 /* Grandchildren should have all been deleted already */ 481 482 if (ChildNode->Child) 483 { 484 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 485 ParentNode, ChildNode)); 486 } 487 488 /* Now we can free this child object */ 489 490 ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 491 492 ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 493 ChildNode, AcpiGbl_CurrentNodeCount)); 494 495 /* 496 * Detach an object if there is one, then free the child node 497 */ 498 AcpiNsDetachObject (ChildNode); 499 ACPI_MEM_FREE (ChildNode); 500 501 /* And move on to the next child in the list */ 502 503 ChildNode = NextNode; 504 505 } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 506 507 508 /* Clear the parent's child pointer */ 509 510 ParentNode->Child = NULL; 511 512 return_VOID; 513} 514 515 516/******************************************************************************* 517 * 518 * FUNCTION: AcpiNsDeleteNamespaceSubtree 519 * 520 * PARAMETERS: ParentNode - Root of the subtree to be deleted 521 * 522 * RETURN: None. 523 * 524 * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 525 * stored within the subtree. 526 * 527 ******************************************************************************/ 528 529void 530AcpiNsDeleteNamespaceSubtree ( 531 ACPI_NAMESPACE_NODE *ParentNode) 532{ 533 ACPI_NAMESPACE_NODE *ChildNode = NULL; 534 UINT32 Level = 1; 535 536 537 ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree"); 538 539 540 if (!ParentNode) 541 { 542 return_VOID; 543 } 544 545 /* 546 * Traverse the tree of objects until we bubble back up 547 * to where we started. 548 */ 549 while (Level > 0) 550 { 551 /* Get the next node in this scope (NULL if none) */ 552 553 ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, 554 ChildNode); 555 if (ChildNode) 556 { 557 /* Found a child node - detach any attached object */ 558 559 AcpiNsDetachObject (ChildNode); 560 561 /* Check if this node has any children */ 562 563 if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0)) 564 { 565 /* 566 * There is at least one child of this node, 567 * visit the node 568 */ 569 Level++; 570 ParentNode = ChildNode; 571 ChildNode = 0; 572 } 573 } 574 else 575 { 576 /* 577 * No more children of this parent node. 578 * Move up to the grandparent. 579 */ 580 Level--; 581 582 /* 583 * Now delete all of the children of this parent 584 * all at the same time. 585 */ 586 AcpiNsDeleteChildren (ParentNode); 587 588 /* New "last child" is this parent node */ 589 590 ChildNode = ParentNode; 591 592 /* Move up the tree to the grandparent */ 593 594 ParentNode = AcpiNsGetParentNode (ParentNode); 595 } 596 } 597 598 return_VOID; 599} 600 601 602/******************************************************************************* 603 * 604 * FUNCTION: AcpiNsRemoveReference 605 * 606 * PARAMETERS: Node - Named node whose reference count is to be 607 * decremented 608 * 609 * RETURN: None. 610 * 611 * DESCRIPTION: Remove a Node reference. Decrements the reference count 612 * of all parent Nodes up to the root. Any node along 613 * the way that reaches zero references is freed. 614 * 615 ******************************************************************************/ 616 617static void 618AcpiNsRemoveReference ( 619 ACPI_NAMESPACE_NODE *Node) 620{ 621 ACPI_NAMESPACE_NODE *ParentNode; 622 ACPI_NAMESPACE_NODE *ThisNode; 623 624 625 ACPI_FUNCTION_ENTRY (); 626 627 628 /* 629 * Decrement the reference count(s) of this node and all 630 * nodes up to the root, Delete anything with zero remaining references. 631 */ 632 ThisNode = Node; 633 while (ThisNode) 634 { 635 /* Prepare to move up to parent */ 636 637 ParentNode = AcpiNsGetParentNode (ThisNode); 638 639 /* Decrement the reference count on this node */ 640 641 ThisNode->ReferenceCount--; 642 643 /* Delete the node if no more references */ 644 645 if (!ThisNode->ReferenceCount) 646 { 647 /* Delete all children and delete the node */ 648 649 AcpiNsDeleteChildren (ThisNode); 650 AcpiNsDeleteNode (ThisNode); 651 } 652 653 ThisNode = ParentNode; 654 } 655} 656 657 658/******************************************************************************* 659 * 660 * FUNCTION: AcpiNsDeleteNamespaceByOwner 661 * 662 * PARAMETERS: OwnerId - All nodes with this owner will be deleted 663 * 664 * RETURN: Status 665 * 666 * DESCRIPTION: Delete entries within the namespace that are owned by a 667 * specific ID. Used to delete entire ACPI tables. All 668 * reference counts are updated. 669 * 670 ******************************************************************************/ 671 672void 673AcpiNsDeleteNamespaceByOwner ( 674 UINT16 OwnerId) 675{ 676 ACPI_NAMESPACE_NODE *ChildNode; 677 ACPI_NAMESPACE_NODE *DeletionNode; 678 UINT32 Level; 679 ACPI_NAMESPACE_NODE *ParentNode; 680 681 682 ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId); 683 684 685 ParentNode = AcpiGbl_RootNode; 686 ChildNode = NULL; 687 DeletionNode = NULL; 688 Level = 1; 689 690 /* 691 * Traverse the tree of nodes until we bubble back up 692 * to where we started. 693 */ 694 while (Level > 0) 695 { 696 /* 697 * Get the next child of this parent node. When ChildNode is NULL, 698 * the first child of the parent is returned 699 */ 700 ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 701 702 if (DeletionNode) 703 { 704 AcpiNsRemoveReference (DeletionNode); 705 DeletionNode = NULL; 706 } 707 708 if (ChildNode) 709 { 710 if (ChildNode->OwnerId == OwnerId) 711 { 712 /* Found a matching child node - detach any attached object */ 713 714 AcpiNsDetachObject (ChildNode); 715 } 716 717 /* Check if this node has any children */ 718 719 if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 720 { 721 /* 722 * There is at least one child of this node, 723 * visit the node 724 */ 725 Level++; 726 ParentNode = ChildNode; 727 ChildNode = NULL; 728 } 729 else if (ChildNode->OwnerId == OwnerId) 730 { 731 DeletionNode = ChildNode; 732 } 733 } 734 else 735 { 736 /* 737 * No more children of this parent node. 738 * Move up to the grandparent. 739 */ 740 Level--; 741 if (Level != 0) 742 { 743 if (ParentNode->OwnerId == OwnerId) 744 { 745 DeletionNode = ParentNode; 746 } 747 } 748 749 /* New "last child" is this parent node */ 750 751 ChildNode = ParentNode; 752 753 /* Move up the tree to the grandparent */ 754 755 ParentNode = AcpiNsGetParentNode (ParentNode); 756 } 757 } 758 759 return_VOID; 760} 761 762 763