nsutils.c revision 83174
1/****************************************************************************** 2 * 3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4 * parents and siblings and Scope manipulation 5 * $Revision: 89 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118#define __NSUTILS_C__ 119 120#include "acpi.h" 121#include "acnamesp.h" 122#include "acinterp.h" 123#include "amlcode.h" 124#include "actables.h" 125 126#define _COMPONENT ACPI_NAMESPACE 127 MODULE_NAME ("nsutils") 128 129 130/******************************************************************************* 131 * 132 * FUNCTION: AcpiNsValidRootPrefix 133 * 134 * PARAMETERS: Prefix - Character to be checked 135 * 136 * RETURN: TRUE if a valid prefix 137 * 138 * DESCRIPTION: Check if a character is a valid ACPI Root prefix 139 * 140 ******************************************************************************/ 141 142BOOLEAN 143AcpiNsValidRootPrefix ( 144 NATIVE_CHAR Prefix) 145{ 146 147 return ((BOOLEAN) (Prefix == '\\')); 148} 149 150 151/******************************************************************************* 152 * 153 * FUNCTION: AcpiNsValidPathSeparator 154 * 155 * PARAMETERS: Sep - Character to be checked 156 * 157 * RETURN: TRUE if a valid path separator 158 * 159 * DESCRIPTION: Check if a character is a valid ACPI path separator 160 * 161 ******************************************************************************/ 162 163BOOLEAN 164AcpiNsValidPathSeparator ( 165 NATIVE_CHAR Sep) 166{ 167 168 return ((BOOLEAN) (Sep == '.')); 169} 170 171 172/******************************************************************************* 173 * 174 * FUNCTION: AcpiNsGetType 175 * 176 * PARAMETERS: Handle - Parent Node to be examined 177 * 178 * RETURN: Type field from Node whose handle is passed 179 * 180 ******************************************************************************/ 181 182ACPI_OBJECT_TYPE8 183AcpiNsGetType ( 184 ACPI_NAMESPACE_NODE *Node) 185{ 186 FUNCTION_TRACE ("NsGetType"); 187 188 189 if (!Node) 190 { 191 REPORT_WARNING (("NsGetType: Null Node ptr")); 192 return_VALUE (ACPI_TYPE_ANY); 193 } 194 195 return_VALUE (Node->Type); 196} 197 198 199/******************************************************************************* 200 * 201 * FUNCTION: AcpiNsLocal 202 * 203 * PARAMETERS: Type - A namespace object type 204 * 205 * RETURN: LOCAL if names must be found locally in objects of the 206 * passed type, 0 if enclosing scopes should be searched 207 * 208 ******************************************************************************/ 209 210UINT32 211AcpiNsLocal ( 212 ACPI_OBJECT_TYPE8 Type) 213{ 214 FUNCTION_TRACE ("NsLocal"); 215 216 217 if (!AcpiUtValidObjectType (Type)) 218 { 219 /* Type code out of range */ 220 221 REPORT_WARNING (("NsLocal: Invalid Object Type\n")); 222 return_VALUE (NSP_NORMAL); 223 } 224 225 return_VALUE ((UINT32) AcpiGbl_NsProperties[Type] & NSP_LOCAL); 226} 227 228 229/******************************************************************************* 230 * 231 * FUNCTION: AcpiNsGetInternalNameLength 232 * 233 * PARAMETERS: Info - Info struct initialized with the 234 * external name pointer. 235 * 236 * RETURN: Status 237 * 238 * DESCRIPTION: Calculate the length of the internal (AML) namestring 239 * corresponding to the external (ASL) namestring. 240 * 241 ******************************************************************************/ 242 243ACPI_STATUS 244AcpiNsGetInternalNameLength ( 245 ACPI_NAMESTRING_INFO *Info) 246{ 247 NATIVE_CHAR *NextExternalChar; 248 UINT32 i; 249 250 251 FUNCTION_ENTRY (); 252 253 254 NextExternalChar = Info->ExternalName; 255 Info->NumCarats = 0; 256 Info->NumSegments = 0; 257 Info->FullyQualified = FALSE; 258 259 /* 260 * For the internal name, the required length is 4 bytes 261 * per segment, plus 1 each for RootPrefix, MultiNamePrefixOp, 262 * segment count, trailing null (which is not really needed, 263 * but no there's harm in putting it there) 264 * 265 * strlen() + 1 covers the first NameSeg, which has no 266 * path separator 267 */ 268 if (AcpiNsValidRootPrefix (NextExternalChar[0])) 269 { 270 Info->FullyQualified = TRUE; 271 NextExternalChar++; 272 } 273 274 else 275 { 276 /* 277 * Handle Carat prefixes 278 */ 279 while (*NextExternalChar == '^') 280 { 281 Info->NumCarats++; 282 NextExternalChar++; 283 } 284 } 285 286 /* 287 * Determine the number of ACPI name "segments" by counting 288 * the number of path separators within the string. Start 289 * with one segment since the segment count is (# separators) 290 * + 1, and zero separators is ok. 291 */ 292 if (*NextExternalChar) 293 { 294 Info->NumSegments = 1; 295 for (i = 0; NextExternalChar[i]; i++) 296 { 297 if (AcpiNsValidPathSeparator (NextExternalChar[i])) 298 { 299 Info->NumSegments++; 300 } 301 } 302 } 303 304 Info->Length = (ACPI_NAME_SIZE * Info->NumSegments) + 305 4 + Info->NumCarats; 306 307 Info->NextExternalChar = NextExternalChar; 308 309 return (AE_OK); 310} 311 312 313/******************************************************************************* 314 * 315 * FUNCTION: AcpiNsBuildInternalName 316 * 317 * PARAMETERS: Info - Info struct fully initialized 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Construct the internal (AML) namestring 322 * corresponding to the external (ASL) namestring. 323 * 324 ******************************************************************************/ 325 326ACPI_STATUS 327AcpiNsBuildInternalName ( 328 ACPI_NAMESTRING_INFO *Info) 329{ 330 UINT32 NumSegments = Info->NumSegments; 331 NATIVE_CHAR *InternalName = Info->InternalName; 332 NATIVE_CHAR *ExternalName = Info->NextExternalChar; 333 NATIVE_CHAR *Result = NULL; 334 UINT32 i; 335 336 337 FUNCTION_TRACE ("NsBuildInternalName"); 338 339 340 /* Setup the correct prefixes, counts, and pointers */ 341 342 if (Info->FullyQualified) 343 { 344 InternalName[0] = '\\'; 345 346 if (NumSegments <= 1) 347 { 348 Result = &InternalName[1]; 349 } 350 else if (NumSegments == 2) 351 { 352 InternalName[1] = AML_DUAL_NAME_PREFIX; 353 Result = &InternalName[2]; 354 } 355 else 356 { 357 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 358 InternalName[2] = (char) NumSegments; 359 Result = &InternalName[3]; 360 } 361 } 362 363 else 364 { 365 /* 366 * Not fully qualified. 367 * Handle Carats first, then append the name segments 368 */ 369 i = 0; 370 if (Info->NumCarats) 371 { 372 for (i = 0; i < Info->NumCarats; i++) 373 { 374 InternalName[i] = '^'; 375 } 376 } 377 378 if (NumSegments == 1) 379 { 380 Result = &InternalName[i]; 381 } 382 383 else if (NumSegments == 2) 384 { 385 InternalName[i] = AML_DUAL_NAME_PREFIX; 386 Result = &InternalName[i+1]; 387 } 388 389 else 390 { 391 InternalName[i] = AML_MULTI_NAME_PREFIX_OP; 392 InternalName[i+1] = (char) NumSegments; 393 Result = &InternalName[i+2]; 394 } 395 } 396 397 398 /* Build the name (minus path separators) */ 399 400 for (; NumSegments; NumSegments--) 401 { 402 for (i = 0; i < ACPI_NAME_SIZE; i++) 403 { 404 if (AcpiNsValidPathSeparator (*ExternalName) || 405 (*ExternalName == 0)) 406 { 407 /* Pad the segment with underscore(s) if segment is short */ 408 409 Result[i] = '_'; 410 } 411 412 else 413 { 414 /* Convert the character to uppercase and save it */ 415 416 Result[i] = (char) TOUPPER (*ExternalName); 417 ExternalName++; 418 } 419 } 420 421 /* Now we must have a path separator, or the pathname is bad */ 422 423 if (!AcpiNsValidPathSeparator (*ExternalName) && 424 (*ExternalName != 0)) 425 { 426 return_ACPI_STATUS (AE_BAD_PARAMETER); 427 } 428 429 /* Move on the next segment */ 430 431 ExternalName++; 432 Result += ACPI_NAME_SIZE; 433 } 434 435 436 /* Terminate the string */ 437 438 *Result = 0; 439 440 if (Info->FullyQualified) 441 { 442 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (abs) \"\\%s\"\n", 443 InternalName, &InternalName[0])); 444 } 445 else 446 { 447 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "returning [%p] (rel) \"%s\"\n", 448 InternalName, &InternalName[2])); 449 } 450 451 return_ACPI_STATUS (AE_OK); 452} 453 454 455/******************************************************************************* 456 * 457 * FUNCTION: AcpiNsInternalizeName 458 * 459 * PARAMETERS: *ExternalName - External representation of name 460 * **Converted Name - Where to return the resulting 461 * internal represention of the name 462 * 463 * RETURN: Status 464 * 465 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 466 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 467 * 468 *******************************************************************************/ 469 470ACPI_STATUS 471AcpiNsInternalizeName ( 472 NATIVE_CHAR *ExternalName, 473 NATIVE_CHAR **ConvertedName) 474{ 475 NATIVE_CHAR *InternalName; 476 ACPI_NAMESTRING_INFO Info; 477 ACPI_STATUS Status; 478 479 480 FUNCTION_TRACE ("NsInternalizeName"); 481 482 483 if ((!ExternalName) || 484 (*ExternalName == 0) || 485 (!ConvertedName)) 486 { 487 return_ACPI_STATUS (AE_BAD_PARAMETER); 488 } 489 490 491 /* Get the length of the new internal name */ 492 493 Info.ExternalName = ExternalName; 494 AcpiNsGetInternalNameLength (&Info); 495 496 /* We need a segment to store the internal name */ 497 498 InternalName = ACPI_MEM_CALLOCATE (Info.Length); 499 if (!InternalName) 500 { 501 return_ACPI_STATUS (AE_NO_MEMORY); 502 } 503 504 /* Build the name */ 505 506 Info.InternalName = InternalName; 507 Status = AcpiNsBuildInternalName (&Info); 508 if (ACPI_FAILURE (Status)) 509 { 510 ACPI_MEM_FREE (InternalName); 511 return_ACPI_STATUS (Status); 512 } 513 514 *ConvertedName = InternalName; 515 return_ACPI_STATUS (AE_OK); 516} 517 518 519/******************************************************************************* 520 * 521 * FUNCTION: AcpiNsExternalizeName 522 * 523 * PARAMETERS: *InternalName - Internal representation of name 524 * **ConvertedName - Where to return the resulting 525 * external representation of name 526 * 527 * RETURN: Status 528 * 529 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 530 * to its external form (e.g. "\_PR_.CPU0") 531 * 532 ******************************************************************************/ 533 534ACPI_STATUS 535AcpiNsExternalizeName ( 536 UINT32 InternalNameLength, 537 char *InternalName, 538 UINT32 *ConvertedNameLength, 539 char **ConvertedName) 540{ 541 UINT32 PrefixLength = 0; 542 UINT32 NamesIndex = 0; 543 UINT32 NamesCount = 0; 544 UINT32 i = 0; 545 UINT32 j = 0; 546 547 548 FUNCTION_TRACE ("NsExternalizeName"); 549 550 551 if (!InternalNameLength || 552 !InternalName || 553 !ConvertedNameLength || 554 !ConvertedName) 555 { 556 return_ACPI_STATUS (AE_BAD_PARAMETER); 557 } 558 559 560 /* 561 * Check for a prefix (one '\' | one or more '^'). 562 */ 563 switch (InternalName[0]) 564 { 565 case '\\': 566 PrefixLength = 1; 567 break; 568 569 case '^': 570 for (i = 0; i < InternalNameLength; i++) 571 { 572 if (InternalName[i] != '^') 573 { 574 PrefixLength = i + 1; 575 } 576 } 577 578 if (i == InternalNameLength) 579 { 580 PrefixLength = i; 581 } 582 583 break; 584 } 585 586 /* 587 * Check for object names. Note that there could be 0-255 of these 588 * 4-byte elements. 589 */ 590 if (PrefixLength < InternalNameLength) 591 { 592 switch (InternalName[PrefixLength]) 593 { 594 595 /* <count> 4-byte names */ 596 597 case AML_MULTI_NAME_PREFIX_OP: 598 NamesIndex = PrefixLength + 2; 599 NamesCount = (UINT32) InternalName[PrefixLength + 1]; 600 break; 601 602 603 /* two 4-byte names */ 604 605 case AML_DUAL_NAME_PREFIX: 606 NamesIndex = PrefixLength + 1; 607 NamesCount = 2; 608 break; 609 610 611 /* NullName */ 612 613 case 0: 614 NamesIndex = 0; 615 NamesCount = 0; 616 break; 617 618 619 /* one 4-byte name */ 620 621 default: 622 NamesIndex = PrefixLength; 623 NamesCount = 1; 624 break; 625 } 626 } 627 628 /* 629 * Calculate the length of ConvertedName, which equals the length 630 * of the prefix, length of all object names, length of any required 631 * punctuation ('.') between object names, plus the NULL terminator. 632 */ 633 *ConvertedNameLength = PrefixLength + (4 * NamesCount) + 634 ((NamesCount > 0) ? (NamesCount - 1) : 0) + 1; 635 636 /* 637 * Check to see if we're still in bounds. If not, there's a problem 638 * with InternalName (invalid format). 639 */ 640 if (*ConvertedNameLength > InternalNameLength) 641 { 642 REPORT_ERROR (("NsExternalizeName: Invalid internal name\n")); 643 return_ACPI_STATUS (AE_BAD_PATHNAME); 644 } 645 646 /* 647 * Build ConvertedName... 648 */ 649 650 (*ConvertedName) = ACPI_MEM_CALLOCATE (*ConvertedNameLength); 651 if (!(*ConvertedName)) 652 { 653 return_ACPI_STATUS (AE_NO_MEMORY); 654 } 655 656 j = 0; 657 658 for (i = 0; i < PrefixLength; i++) 659 { 660 (*ConvertedName)[j++] = InternalName[i]; 661 } 662 663 if (NamesCount > 0) 664 { 665 for (i = 0; i < NamesCount; i++) 666 { 667 if (i > 0) 668 { 669 (*ConvertedName)[j++] = '.'; 670 } 671 672 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 673 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 674 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 675 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 676 } 677 } 678 679 return_ACPI_STATUS (AE_OK); 680} 681 682 683/******************************************************************************* 684 * 685 * FUNCTION: AcpiNsConvertHandleToEntry 686 * 687 * PARAMETERS: Handle - Handle to be converted to an Node 688 * 689 * RETURN: A Name table entry pointer 690 * 691 * DESCRIPTION: Convert a namespace handle to a real Node 692 * 693 ******************************************************************************/ 694 695ACPI_NAMESPACE_NODE * 696AcpiNsConvertHandleToEntry ( 697 ACPI_HANDLE Handle) 698{ 699 700 FUNCTION_ENTRY (); 701 702 703 /* 704 * Simple implementation for now; 705 * TBD: [Future] Real integer handles allow for more verification 706 * and keep all pointers within this subsystem! 707 */ 708 if (!Handle) 709 { 710 return (NULL); 711 } 712 713 if (Handle == ACPI_ROOT_OBJECT) 714 { 715 return (AcpiGbl_RootNode); 716 } 717 718 719 /* We can at least attempt to verify the handle */ 720 721 if (!VALID_DESCRIPTOR_TYPE (Handle, ACPI_DESC_TYPE_NAMED)) 722 { 723 return (NULL); 724 } 725 726 return ((ACPI_NAMESPACE_NODE *) Handle); 727} 728 729 730/******************************************************************************* 731 * 732 * FUNCTION: AcpiNsConvertEntryToHandle 733 * 734 * PARAMETERS: Node - Node to be converted to a Handle 735 * 736 * RETURN: An USER ACPI_HANDLE 737 * 738 * DESCRIPTION: Convert a real Node to a namespace handle 739 * 740 ******************************************************************************/ 741 742ACPI_HANDLE 743AcpiNsConvertEntryToHandle ( 744 ACPI_NAMESPACE_NODE *Node) 745{ 746 747 748 /* 749 * Simple implementation for now; 750 * TBD: [Future] Real integer handles allow for more verification 751 * and keep all pointers within this subsystem! 752 */ 753 return ((ACPI_HANDLE) Node); 754 755 756/* --------------------------------------------------- 757 758 if (!Node) 759 { 760 return (NULL); 761 } 762 763 if (Node == AcpiGbl_RootNode) 764 { 765 return (ACPI_ROOT_OBJECT); 766 } 767 768 769 return ((ACPI_HANDLE) Node); 770------------------------------------------------------*/ 771} 772 773 774/******************************************************************************* 775 * 776 * FUNCTION: AcpiNsTerminate 777 * 778 * PARAMETERS: none 779 * 780 * RETURN: none 781 * 782 * DESCRIPTION: free memory allocated for table storage. 783 * 784 ******************************************************************************/ 785 786void 787AcpiNsTerminate (void) 788{ 789 ACPI_OPERAND_OBJECT *ObjDesc; 790 ACPI_NAMESPACE_NODE *ThisNode; 791 792 793 FUNCTION_TRACE ("NsTerminate"); 794 795 796 ThisNode = AcpiGbl_RootNode; 797 798 /* 799 * 1) Free the entire namespace -- all objects, tables, and stacks 800 * 801 * Delete all objects linked to the root 802 * (additional table descriptors) 803 */ 804 AcpiNsDeleteNamespaceSubtree (ThisNode); 805 806 /* Detach any object(s) attached to the root */ 807 808 ObjDesc = AcpiNsGetAttachedObject (ThisNode); 809 if (ObjDesc) 810 { 811 AcpiNsDetachObject (ThisNode); 812 AcpiUtRemoveReference (ObjDesc); 813 } 814 815 AcpiNsDeleteChildren (ThisNode); 816 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); 817 818 819 /* 820 * 2) Now we can delete the ACPI tables 821 */ 822 AcpiTbDeleteAcpiTables (); 823 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 824 825 return_VOID; 826} 827 828 829/******************************************************************************* 830 * 831 * FUNCTION: AcpiNsOpensScope 832 * 833 * PARAMETERS: Type - A valid namespace type 834 * 835 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 836 * to the ACPI specification, else 0 837 * 838 ******************************************************************************/ 839 840UINT32 841AcpiNsOpensScope ( 842 ACPI_OBJECT_TYPE8 Type) 843{ 844 FUNCTION_TRACE_U32 ("NsOpensScope", Type); 845 846 847 if (!AcpiUtValidObjectType (Type)) 848 { 849 /* type code out of range */ 850 851 REPORT_WARNING (("NsOpensScope: Invalid Object Type\n")); 852 return_VALUE (NSP_NORMAL); 853 } 854 855 return_VALUE (((UINT32) AcpiGbl_NsProperties[Type]) & NSP_NEWSCOPE); 856} 857 858 859/******************************************************************************* 860 * 861 * FUNCTION: AcpiNsGetNode 862 * 863 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 864 * \ (backslash) and ^ (carat) prefixes, and the 865 * . (period) to separate segments are supported. 866 * StartNode - Root of subtree to be searched, or NS_ALL for the 867 * root of the name space. If Name is fully 868 * qualified (first INT8 is '\'), the passed value 869 * of Scope will not be accessed. 870 * ReturnNode - Where the Node is returned 871 * 872 * DESCRIPTION: Look up a name relative to a given scope and return the 873 * corresponding Node. NOTE: Scope can be null. 874 * 875 * MUTEX: Locks namespace 876 * 877 ******************************************************************************/ 878 879ACPI_STATUS 880AcpiNsGetNode ( 881 NATIVE_CHAR *Pathname, 882 ACPI_NAMESPACE_NODE *StartNode, 883 ACPI_NAMESPACE_NODE **ReturnNode) 884{ 885 ACPI_GENERIC_STATE ScopeInfo; 886 ACPI_STATUS Status; 887 NATIVE_CHAR *InternalPath = NULL; 888 889 890 FUNCTION_TRACE_PTR ("NsGetNode", Pathname); 891 892 893 /* Ensure that the namespace has been initialized */ 894 895 if (!AcpiGbl_RootNode) 896 { 897 return_ACPI_STATUS (AE_NO_NAMESPACE); 898 } 899 900 if (!Pathname) 901 { 902 return_ACPI_STATUS (AE_BAD_PARAMETER); 903 } 904 905 906 /* Convert path to internal representation */ 907 908 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 909 if (ACPI_FAILURE (Status)) 910 { 911 return_ACPI_STATUS (Status); 912 } 913 914 915 AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 916 917 /* Setup lookup scope (search starting point) */ 918 919 ScopeInfo.Scope.Node = StartNode; 920 921 /* Lookup the name in the namespace */ 922 923 Status = AcpiNsLookup (&ScopeInfo, InternalPath, 924 ACPI_TYPE_ANY, IMODE_EXECUTE, 925 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, 926 NULL, ReturnNode); 927 928 if (ACPI_FAILURE (Status)) 929 { 930 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s, %s\n", 931 InternalPath, AcpiFormatException (Status))); 932 } 933 934 935 AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 936 937 /* Cleanup */ 938 939 ACPI_MEM_FREE (InternalPath); 940 return_ACPI_STATUS (Status); 941} 942 943 944/******************************************************************************* 945 * 946 * FUNCTION: AcpiNsFindParentName 947 * 948 * PARAMETERS: *ChildNode - Named Obj whose name is to be found 949 * 950 * RETURN: The ACPI name 951 * 952 * DESCRIPTION: Search for the given obj in its parent scope and return the 953 * name segment, or "????" if the parent name can't be found 954 * (which "should not happen"). 955 * 956 ******************************************************************************/ 957 958ACPI_NAME 959AcpiNsFindParentName ( 960 ACPI_NAMESPACE_NODE *ChildNode) 961{ 962 ACPI_NAMESPACE_NODE *ParentNode; 963 964 965 FUNCTION_TRACE ("NsFindParentName"); 966 967 968 if (ChildNode) 969 { 970 /* Valid entry. Get the parent Node */ 971 972 ParentNode = AcpiNsGetParentObject (ChildNode); 973 if (ParentNode) 974 { 975 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Parent of %p [%4.4s] is %p [%4.4s]\n", 976 ChildNode, &ChildNode->Name, ParentNode, &ParentNode->Name)); 977 978 if (ParentNode->Name) 979 { 980 return_VALUE (ParentNode->Name); 981 } 982 } 983 984 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "unable to find parent of %p (%4.4s)\n", 985 ChildNode, &ChildNode->Name)); 986 } 987 988 return_VALUE (ACPI_UNKNOWN_NAME); 989} 990 991 992#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) 993 994/******************************************************************************* 995 * 996 * FUNCTION: AcpiNsExistDownstreamSibling 997 * 998 * PARAMETERS: *Node - pointer to first Node to examine 999 * 1000 * RETURN: TRUE if sibling is found, FALSE otherwise 1001 * 1002 * DESCRIPTION: Searches remainder of scope being processed to determine 1003 * whether there is a downstream sibling to the current 1004 * object. This function is used to determine what type of 1005 * line drawing character to use when displaying namespace 1006 * trees. 1007 * 1008 ******************************************************************************/ 1009 1010BOOLEAN 1011AcpiNsExistDownstreamSibling ( 1012 ACPI_NAMESPACE_NODE *Node) 1013{ 1014 1015 if (!Node) 1016 { 1017 return (FALSE); 1018 } 1019 1020 if (Node->Name) 1021 { 1022 return (TRUE); 1023 } 1024 1025 return (FALSE); 1026} 1027 1028#endif /* ACPI_DEBUG */ 1029 1030 1031/******************************************************************************* 1032 * 1033 * FUNCTION: AcpiNsGetParentObject 1034 * 1035 * PARAMETERS: Node - Current table entry 1036 * 1037 * RETURN: Parent entry of the given entry 1038 * 1039 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. 1040 * 1041 ******************************************************************************/ 1042 1043 1044ACPI_NAMESPACE_NODE * 1045AcpiNsGetParentObject ( 1046 ACPI_NAMESPACE_NODE *Node) 1047{ 1048 1049 1050 FUNCTION_ENTRY (); 1051 1052 1053 if (!Node) 1054 { 1055 return (NULL); 1056 } 1057 1058 /* 1059 * Walk to the end of this peer list. 1060 * The last entry is marked with a flag and the peer 1061 * pointer is really a pointer back to the parent. 1062 * This saves putting a parent back pointer in each and 1063 * every named object! 1064 */ 1065 while (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 1066 { 1067 Node = Node->Peer; 1068 } 1069 1070 1071 return (Node->Peer); 1072} 1073 1074 1075/******************************************************************************* 1076 * 1077 * FUNCTION: AcpiNsGetNextValidObject 1078 * 1079 * PARAMETERS: Node - Current table entry 1080 * 1081 * RETURN: Next valid object in the table. NULL if no more valid 1082 * objects 1083 * 1084 * DESCRIPTION: Find the next valid object within a name table. 1085 * Useful for implementing NULL-end-of-list loops. 1086 * 1087 ******************************************************************************/ 1088 1089 1090ACPI_NAMESPACE_NODE * 1091AcpiNsGetNextValidObject ( 1092 ACPI_NAMESPACE_NODE *Node) 1093{ 1094 1095 /* If we are at the end of this peer list, return NULL */ 1096 1097 if (Node->Flags & ANOBJ_END_OF_PEER_LIST) 1098 { 1099 return NULL; 1100 } 1101 1102 /* Otherwise just return the next peer */ 1103 1104 return (Node->Peer); 1105} 1106 1107 1108