nsalloc.c revision 99679
1193323Sed/******************************************************************************* 2193323Sed * 3193323Sed * Module Name: nsalloc - Namespace allocation and deletion utilities 4193323Sed * $Revision: 74 $ 5193323Sed * 6193323Sed ******************************************************************************/ 7193323Sed 8193323Sed/****************************************************************************** 9193323Sed * 10193323Sed * 1. Copyright Notice 11193323Sed * 12193323Sed * Some or all of this work - Copyright (c) 1999 - 2002, Intel Corp. 13193323Sed * All rights reserved. 14193323Sed * 15193323Sed * 2. License 16249423Sdim * 17249423Sdim * 2.1. This is your license from Intel Corp. under its intellectual property 18249423Sdim * rights. You may have additional license terms from the party that provided 19249423Sdim * you this software, covering your right to use that party's intellectual 20288943Sdim * property rights. 21249423Sdim * 22276479Sdim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23249423Sdim * copy of the source code appearing in this file ("Covered Code") an 24193323Sed * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25193323Sed * base code distributed originally by Intel ("Original Intel Code") to copy, 26193323Sed * make derivatives, distribute, use and display any portion of the Covered 27218885Sdim * Code in any form, with the right to sublicense such rights; and 28218885Sdim * 29249423Sdim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30249423Sdim * license (with the right to sublicense), under only those claims of Intel 31249423Sdim * patents that are infringed by the Original Intel Code, to make, use, sell, 32249423Sdim * offer to sell, and import the Covered Code and derivative works thereof 33249423Sdim * solely to the minimum extent necessary to exercise the above copyright 34193323Sed * license, and in no event shall the patent license extend to any additions 35193323Sed * to or modifications of the Original Intel Code. No other license or right 36193323Sed * is granted directly or by implication, estoppel or otherwise; 37276479Sdim * 38276479Sdim * The above copyright and patent license is granted only if the following 39193323Sed * conditions are met: 40193323Sed * 41198090Srdivacky * 3. Conditions 42193323Sed * 43193323Sed * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44193323Sed * Redistribution of source code of any substantial portion of the Covered 45193323Sed * Code or modification with rights to further distribute source must include 46193323Sed * the above Copyright Notice, the above License, this list of Conditions, 47193323Sed * and the following Disclaimer and Export Compliance provision. In addition, 48193323Sed * Licensee must cause all Covered Code to which Licensee contributes to 49193323Sed * contain a file documenting the changes Licensee made to create that Covered 50193323Sed * Code and the date of any change. Licensee must include in that file the 51193323Sed * documentation of any changes made by any predecessor Licensee. Licensee 52234353Sdim * must include a prominent statement that the modification is derived, 53234353Sdim * directly or indirectly, from Original Intel Code. 54276479Sdim * 55234353Sdim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56234353Sdim * Redistribution of source code of any substantial portion of the Covered 57234353Sdim * Code or modification without rights to further distribute source must 58234353Sdim * include the following Disclaimer and Export Compliance provision in the 59234353Sdim * documentation and/or other materials provided with distribution. In 60234353Sdim * addition, Licensee may not authorize further sublicense of source of any 61234353Sdim * portion of the Covered Code, and must include terms to the effect that the 62234353Sdim * license from Licensee to its licensee is limited to the intellectual 63234353Sdim * property embodied in the software Licensee provides to its licensee, and 64234353Sdim * not to intellectual property embodied in modifications its licensee may 65234353Sdim * make. 66234353Sdim * 67234353Sdim * 3.3. Redistribution of Executable. Redistribution in executable form of any 68234353Sdim * substantial portion of the Covered Code or modification must reproduce the 69234353Sdim * above Copyright Notice, and the following Disclaimer and Export Compliance 70234353Sdim * provision in the documentation and/or other materials provided with the 71234353Sdim * distribution. 72234353Sdim * 73234353Sdim * 3.4. Intel retains all right, title, and interest in and to the Original 74234353Sdim * Intel Code. 75234353Sdim * 76234353Sdim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77234353Sdim * Intel shall be used in advertising or otherwise to promote the sale, use or 78234353Sdim * other dealings in products derived from or relating to the Covered Code 79234353Sdim * without prior written authorization from Intel. 80234353Sdim * 81276479Sdim * 4. Disclaimer and Export Compliance 82234353Sdim * 83234353Sdim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84234353Sdim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85280031Sdim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86280031Sdim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87280031Sdim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88212793Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89296417Sdim * PARTICULAR PURPOSE. 90193323Sed * 91193323Sed * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92193323Sed * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93193323Sed * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94212793Sdim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95193323Sed * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96193323Sed * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97193323Sed * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98193323Sed * LIMITED REMEDY. 99193323Sed * 100193323Sed * 4.3. Licensee shall not export, either directly or indirectly, any of this 101193323Sed * software or system incorporating such software without first obtaining any 102193323Sed * required license or other approval from the U. S. Department of Commerce or 103296417Sdim * any other agency or department of the United States Government. In the 104193323Sed * event Licensee exports any such software from the United States or 105193323Sed * re-exports any such software from a foreign destination, Licensee shall 106210006Srdivacky * ensure that the distribution and export/re-export of the software is in 107193323Sed * compliance with all laws, regulations, orders, or other restrictions of the 108193323Sed * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109193323Sed * any of its subsidiaries will export/re-export any technical data, process, 110193323Sed * software, or service, directly or indirectly, to any country for which the 111193323Sed * United States government or any agency thereof requires an export license, 112193323Sed * other governmental approval, or letter of assurance, without first obtaining 113212793Sdim * such license, approval or letter. 114193323Sed * 115212793Sdim *****************************************************************************/ 116193323Sed 117212793Sdim 118193323Sed#define __NSALLOC_C__ 119212793Sdim 120193323Sed#include "acpi.h" 121212793Sdim#include "acnamesp.h" 122280031Sdim 123212793Sdim 124212793Sdim#define _COMPONENT ACPI_NAMESPACE 125212793Sdim ACPI_MODULE_NAME ("nsalloc") 126212793Sdim 127212793Sdim 128212793Sdim/******************************************************************************* 129193323Sed * 130193323Sed * FUNCTION: AcpiNsCreateNode 131280031Sdim * 132280031Sdim * PARAMETERS: AcpiName - Name of the new node 133193323Sed * 134193323Sed * RETURN: None 135193323Sed * 136193323Sed * DESCRIPTION: Create a namespace node 137212793Sdim * 138212793Sdim ******************************************************************************/ 139193323Sed 140193323SedACPI_NAMESPACE_NODE * 141212793SdimAcpiNsCreateNode ( 142193323Sed UINT32 Name) 143212793Sdim{ 144193323Sed ACPI_NAMESPACE_NODE *Node; 145280031Sdim 146276479Sdim 147198090Srdivacky ACPI_FUNCTION_TRACE ("NsCreateNode"); 148280031Sdim 149193323Sed 150193323Sed Node = ACPI_MEM_CALLOCATE (sizeof (ACPI_NAMESPACE_NODE)); 151193323Sed if (!Node) 152193323Sed { 153193323Sed return_PTR (NULL); 154280031Sdim } 155212793Sdim 156212793Sdim ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalAllocated++); 157193323Sed 158280031Sdim Node->Name.Integer = Name; 159276479Sdim Node->ReferenceCount = 1; 160198090Srdivacky ACPI_SET_DESCRIPTOR_TYPE (Node, ACPI_DESC_TYPE_NAMED); 161212793Sdim 162198090Srdivacky return_PTR (Node); 163276479Sdim} 164193323Sed 165193323Sed 166193323Sed/******************************************************************************* 167193323Sed * 168193323Sed * FUNCTION: AcpiNsDeleteNode 169193323Sed * 170193323Sed * PARAMETERS: Node - Node to be deleted 171276479Sdim * 172193323Sed * RETURN: None 173193323Sed * 174193323Sed * DESCRIPTION: Delete a namespace node 175193323Sed * 176193323Sed ******************************************************************************/ 177193323Sed 178193323Sedvoid 179193323SedAcpiNsDeleteNode ( 180193323Sed ACPI_NAMESPACE_NODE *Node) 181193323Sed{ 182296417Sdim ACPI_NAMESPACE_NODE *ParentNode; 183296417Sdim ACPI_NAMESPACE_NODE *PrevNode; 184296417Sdim ACPI_NAMESPACE_NODE *NextNode; 185296417Sdim 186296417Sdim 187296417Sdim ACPI_FUNCTION_TRACE_PTR ("NsDeleteNode", Node); 188296417Sdim 189296417Sdim 190296417Sdim ParentNode = AcpiNsGetParentNode (Node); 191296417Sdim 192296417Sdim PrevNode = NULL; 193296417Sdim NextNode = ParentNode->Child; 194296417Sdim 195296417Sdim while (NextNode != Node) 196296417Sdim { 197296417Sdim PrevNode = NextNode; 198296417Sdim NextNode = PrevNode->Peer; 199296417Sdim } 200296417Sdim 201296417Sdim if (PrevNode) 202296417Sdim { 203193323Sed PrevNode->Peer = NextNode->Peer; 204296417Sdim if (NextNode->Flags & ANOBJ_END_OF_PEER_LIST) 205296417Sdim { 206296417Sdim PrevNode->Flags |= ANOBJ_END_OF_PEER_LIST; 207296417Sdim } 208296417Sdim } 209296417Sdim else 210296417Sdim { 211296417Sdim ParentNode->Child = NextNode->Peer; 212296417Sdim } 213193323Sed 214193323Sed 215193323Sed ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 216193323Sed 217296417Sdim /* 218296417Sdim * Detach an object if there is one then delete the node 219193323Sed */ 220193323Sed AcpiNsDetachObject (Node); 221193323Sed ACPI_MEM_FREE (Node); 222193323Sed return_VOID; 223193323Sed} 224193323Sed 225193323Sed 226193323Sed/******************************************************************************* 227193323Sed * 228193323Sed * FUNCTION: AcpiNsInstallNode 229224133Sdim * 230288943Sdim * PARAMETERS: WalkState - Current state of the walk 231226584Sdim * ParentNode - The parent of the new Node 232288943Sdim * Node - The new Node to install 233193323Sed * Type - ACPI object type of the new Node 234224133Sdim * 235224133Sdim * RETURN: None 236224133Sdim * 237224133Sdim * DESCRIPTION: Initialize a new namespace node and install it amongst 238224133Sdim * its peers. 239193323Sed * 240193323Sed * Note: Current namespace lookup is linear search, so the nodes 241193323Sed * are not linked in any particular order. 242193323Sed * 243193323Sed ******************************************************************************/ 244193323Sed 245193323Sedvoid 246193323SedAcpiNsInstallNode ( 247193323Sed ACPI_WALK_STATE *WalkState, 248193323Sed ACPI_NAMESPACE_NODE *ParentNode, /* Parent */ 249193323Sed ACPI_NAMESPACE_NODE *Node, /* New Child*/ 250218885Sdim ACPI_OBJECT_TYPE Type) 251193323Sed{ 252193323Sed UINT16 OwnerId = TABLE_ID_DSDT; 253193323Sed ACPI_NAMESPACE_NODE *ChildNode; 254193323Sed 255193323Sed 256193323Sed ACPI_FUNCTION_TRACE ("NsInstallNode"); 257193323Sed 258193323Sed 259193323Sed /* 260193323Sed * Get the owner ID from the Walk state 261193323Sed * The owner ID is used to track table deletion and 262193323Sed * deletion of objects created by methods 263193323Sed */ 264193323Sed if (WalkState) 265193323Sed { 266193323Sed OwnerId = WalkState->OwnerId; 267193323Sed } 268193323Sed 269193323Sed /* Link the new entry into the parent and existing children */ 270193323Sed 271193323Sed ChildNode = ParentNode->Child; 272193323Sed if (!ChildNode) 273193323Sed { 274193323Sed ParentNode->Child = Node; 275193323Sed } 276193323Sed else 277193323Sed { 278210006Srdivacky while (!(ChildNode->Flags & ANOBJ_END_OF_PEER_LIST)) 279193323Sed { 280193323Sed ChildNode = ChildNode->Peer; 281193323Sed } 282193323Sed 283193323Sed ChildNode->Peer = Node; 284193323Sed 285193323Sed /* Clear end-of-list flag */ 286193323Sed 287193323Sed ChildNode->Flags &= ~ANOBJ_END_OF_PEER_LIST; 288198090Srdivacky } 289198090Srdivacky 290198090Srdivacky /* Init the new entry */ 291193323Sed 292193323Sed Node->OwnerId = OwnerId; 293193323Sed Node->Flags |= ANOBJ_END_OF_PEER_LIST; 294193323Sed Node->Peer = ParentNode; 295193323Sed 296193323Sed 297193323Sed /* 298193323Sed * If adding a name with unknown type, or having to 299193323Sed * add the region in order to define fields in it, we 300198090Srdivacky * have a forward reference. 301198090Srdivacky */ 302198090Srdivacky if ((ACPI_TYPE_ANY == Type) || 303193323Sed (INTERNAL_TYPE_FIELD_DEFN == Type) || 304193323Sed (INTERNAL_TYPE_BANK_FIELD_DEFN == Type)) 305193323Sed { 306296417Sdim /* 307296417Sdim * We don't want to abort here, however! 308218885Sdim * We will fill in the actual type when the 309193323Sed * real definition is found later. 310193323Sed */ 311193323Sed ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "[%4.4s] is a forward reference\n", 312193323Sed Node->Name.Ascii)); 313193323Sed } 314193323Sed 315198090Srdivacky /* 316198090Srdivacky * The DefFieldDefn and BankFieldDefn cases are actually 317193323Sed * looking up the Region in which the field will be defined 318193323Sed */ 319193323Sed if ((INTERNAL_TYPE_FIELD_DEFN == Type) || 320218885Sdim (INTERNAL_TYPE_BANK_FIELD_DEFN == Type)) 321296417Sdim { 322193323Sed Type = ACPI_TYPE_REGION; 323193323Sed } 324193323Sed 325193323Sed /* 326210006Srdivacky * Scope, DefAny, and IndexFieldDefn are bogus "types" which do 327198090Srdivacky * not actually have anything to do with the type of the name 328276479Sdim * being looked up. Save any other value of Type as the type of 329198090Srdivacky * the entry. 330210006Srdivacky */ 331193323Sed if ((Type != INTERNAL_TYPE_SCOPE) && 332193323Sed (Type != INTERNAL_TYPE_DEF_ANY) && 333193323Sed (Type != INTERNAL_TYPE_INDEX_FIELD_DEFN)) 334193323Sed { 335193323Sed Node->Type = (UINT8) Type; 336296417Sdim } 337296417Sdim 338296417Sdim ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s added to %p at %p\n", 339193323Sed Node->Name.Ascii, ParentNode, Node)); 340234353Sdim 341296417Sdim /* 342296417Sdim * Increment the reference count(s) of all parents up to 343296417Sdim * the root! 344234353Sdim */ 345234353Sdim while ((Node = AcpiNsGetParentNode (Node)) != NULL) 346234353Sdim { 347276479Sdim Node->ReferenceCount++; 348234353Sdim } 349234353Sdim 350234353Sdim return_VOID; 351234353Sdim} 352234353Sdim 353296417Sdim 354234353Sdim/******************************************************************************* 355234353Sdim * 356296417Sdim * FUNCTION: AcpiNsDeleteChildren 357234353Sdim * 358234353Sdim * PARAMETERS: ParentNode - Delete this objects children 359234353Sdim * 360193323Sed * RETURN: None. 361193323Sed * 362296417Sdim * DESCRIPTION: Delete all children of the parent object. In other words, 363296417Sdim * deletes a "scope". 364296417Sdim * 365193323Sed ******************************************************************************/ 366193323Sed 367193323Sedvoid 368193323SedAcpiNsDeleteChildren ( 369193323Sed ACPI_NAMESPACE_NODE *ParentNode) 370193323Sed{ 371193323Sed ACPI_NAMESPACE_NODE *ChildNode; 372280031Sdim ACPI_NAMESPACE_NODE *NextNode; 373280031Sdim UINT8 Flags; 374280031Sdim 375261991Sdim 376261991Sdim ACPI_FUNCTION_TRACE_PTR ("NsDeleteChildren", ParentNode); 377276479Sdim 378261991Sdim 379261991Sdim if (!ParentNode) 380198090Srdivacky { 381261991Sdim return_VOID; 382212793Sdim } 383276479Sdim 384193323Sed /* If no children, all done! */ 385261991Sdim 386193323Sed ChildNode = ParentNode->Child; 387261991Sdim if (!ChildNode) 388193323Sed { 389193323Sed return_VOID; 390193323Sed } 391193323Sed 392193323Sed /* 393193323Sed * Deallocate all children at this level 394234353Sdim */ 395212793Sdim do 396193323Sed { 397212793Sdim /* Get the things we need */ 398212793Sdim 399261991Sdim NextNode = ChildNode->Peer; 400212793Sdim Flags = ChildNode->Flags; 401212793Sdim 402276479Sdim /* Grandchildren should have all been deleted already */ 403212793Sdim 404212793Sdim if (ChildNode->Child) 405193323Sed { 406261991Sdim ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", 407261991Sdim ParentNode, ChildNode)); 408203954Srdivacky } 409193323Sed 410212793Sdim /* Now we can free this child object */ 411212793Sdim 412280031Sdim ACPI_MEM_TRACKING (AcpiGbl_MemoryLists[ACPI_MEM_LIST_NSNODE].TotalFreed++); 413193323Sed 414261991Sdim ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", 415193323Sed ChildNode, AcpiGbl_CurrentNodeCount)); 416276479Sdim 417198090Srdivacky /* 418212793Sdim * Detach an object if there is one, then free the child node 419193323Sed */ 420193323Sed AcpiNsDetachObject (ChildNode); 421193323Sed ACPI_MEM_FREE (ChildNode); 422 423 /* And move on to the next child in the list */ 424 425 ChildNode = NextNode; 426 427 } while (!(Flags & ANOBJ_END_OF_PEER_LIST)); 428 429 430 /* Clear the parent's child pointer */ 431 432 ParentNode->Child = NULL; 433 434 return_VOID; 435} 436 437 438/******************************************************************************* 439 * 440 * FUNCTION: AcpiNsDeleteNamespaceSubtree 441 * 442 * PARAMETERS: ParentNode - Root of the subtree to be deleted 443 * 444 * RETURN: None. 445 * 446 * DESCRIPTION: Delete a subtree of the namespace. This includes all objects 447 * stored within the subtree. 448 * 449 ******************************************************************************/ 450 451void 452AcpiNsDeleteNamespaceSubtree ( 453 ACPI_NAMESPACE_NODE *ParentNode) 454{ 455 ACPI_NAMESPACE_NODE *ChildNode = NULL; 456 UINT32 Level = 1; 457 458 459 ACPI_FUNCTION_TRACE ("NsDeleteNamespaceSubtree"); 460 461 462 if (!ParentNode) 463 { 464 return_VOID; 465 } 466 467 /* 468 * Traverse the tree of objects until we bubble back up 469 * to where we started. 470 */ 471 while (Level > 0) 472 { 473 /* Get the next node in this scope (NULL if none) */ 474 475 ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, 476 ChildNode); 477 if (ChildNode) 478 { 479 /* Found a child node - detach any attached object */ 480 481 AcpiNsDetachObject (ChildNode); 482 483 /* Check if this node has any children */ 484 485 if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, 0)) 486 { 487 /* 488 * There is at least one child of this node, 489 * visit the node 490 */ 491 Level++; 492 ParentNode = ChildNode; 493 ChildNode = 0; 494 } 495 } 496 else 497 { 498 /* 499 * No more children of this parent node. 500 * Move up to the grandparent. 501 */ 502 Level--; 503 504 /* 505 * Now delete all of the children of this parent 506 * all at the same time. 507 */ 508 AcpiNsDeleteChildren (ParentNode); 509 510 /* New "last child" is this parent node */ 511 512 ChildNode = ParentNode; 513 514 /* Move up the tree to the grandparent */ 515 516 ParentNode = AcpiNsGetParentNode (ParentNode); 517 } 518 } 519 520 return_VOID; 521} 522 523 524/******************************************************************************* 525 * 526 * FUNCTION: AcpiNsRemoveReference 527 * 528 * PARAMETERS: Node - Named node whose reference count is to be 529 * decremented 530 * 531 * RETURN: None. 532 * 533 * DESCRIPTION: Remove a Node reference. Decrements the reference count 534 * of all parent Nodes up to the root. Any node along 535 * the way that reaches zero references is freed. 536 * 537 ******************************************************************************/ 538 539static void 540AcpiNsRemoveReference ( 541 ACPI_NAMESPACE_NODE *Node) 542{ 543 ACPI_NAMESPACE_NODE *ParentNode; 544 ACPI_NAMESPACE_NODE *ThisNode; 545 546 547 ACPI_FUNCTION_ENTRY (); 548 549 550 /* 551 * Decrement the reference count(s) of this node and all 552 * nodes up to the root, Delete anything with zero remaining references. 553 */ 554 ThisNode = Node; 555 while (ThisNode) 556 { 557 /* Prepare to move up to parent */ 558 559 ParentNode = AcpiNsGetParentNode (ThisNode); 560 561 /* Decrement the reference count on this node */ 562 563 ThisNode->ReferenceCount--; 564 565 /* Delete the node if no more references */ 566 567 if (!ThisNode->ReferenceCount) 568 { 569 /* Delete all children and delete the node */ 570 571 AcpiNsDeleteChildren (ThisNode); 572 AcpiNsDeleteNode (ThisNode); 573 } 574 575 ThisNode = ParentNode; 576 } 577} 578 579 580/******************************************************************************* 581 * 582 * FUNCTION: AcpiNsDeleteNamespaceByOwner 583 * 584 * PARAMETERS: OwnerId - All nodes with this owner will be deleted 585 * 586 * RETURN: Status 587 * 588 * DESCRIPTION: Delete entries within the namespace that are owned by a 589 * specific ID. Used to delete entire ACPI tables. All 590 * reference counts are updated. 591 * 592 ******************************************************************************/ 593 594void 595AcpiNsDeleteNamespaceByOwner ( 596 UINT16 OwnerId) 597{ 598 ACPI_NAMESPACE_NODE *ChildNode; 599 ACPI_NAMESPACE_NODE *DeletionNode; 600 UINT32 Level; 601 ACPI_NAMESPACE_NODE *ParentNode; 602 603 604 ACPI_FUNCTION_TRACE_U32 ("NsDeleteNamespaceByOwner", OwnerId); 605 606 607 ParentNode = AcpiGbl_RootNode; 608 ChildNode = NULL; 609 DeletionNode = NULL; 610 Level = 1; 611 612 /* 613 * Traverse the tree of nodes until we bubble back up 614 * to where we started. 615 */ 616 while (Level > 0) 617 { 618 /* 619 * Get the next child of this parent node. When ChildNode is NULL, 620 * the first child of the parent is returned 621 */ 622 ChildNode = AcpiNsGetNextNode (ACPI_TYPE_ANY, ParentNode, ChildNode); 623 624 if (DeletionNode) 625 { 626 AcpiNsRemoveReference (DeletionNode); 627 DeletionNode = NULL; 628 } 629 630 if (ChildNode) 631 { 632 if (ChildNode->OwnerId == OwnerId) 633 { 634 /* Found a matching child node - detach any attached object */ 635 636 AcpiNsDetachObject (ChildNode); 637 } 638 639 /* Check if this node has any children */ 640 641 if (AcpiNsGetNextNode (ACPI_TYPE_ANY, ChildNode, NULL)) 642 { 643 /* 644 * There is at least one child of this node, 645 * visit the node 646 */ 647 Level++; 648 ParentNode = ChildNode; 649 ChildNode = NULL; 650 } 651 else if (ChildNode->OwnerId == OwnerId) 652 { 653 DeletionNode = ChildNode; 654 } 655 } 656 else 657 { 658 /* 659 * No more children of this parent node. 660 * Move up to the grandparent. 661 */ 662 Level--; 663 if (Level != 0) 664 { 665 if (ParentNode->OwnerId == OwnerId) 666 { 667 DeletionNode = ParentNode; 668 } 669 } 670 671 /* New "last child" is this parent node */ 672 673 ChildNode = ParentNode; 674 675 /* Move up the tree to the grandparent */ 676 677 ParentNode = AcpiNsGetParentNode (ParentNode); 678 } 679 } 680 681 return_VOID; 682} 683 684 685