nsutils.c revision 67754
1/****************************************************************************** 2 * 3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4 * parents and siblings and Scope manipulation 5 * $Revision: 71 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 14 * 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 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 182OBJECT_TYPE_INTERNAL 183AcpiNsGetType ( 184 ACPI_HANDLE handle) 185{ 186 FUNCTION_TRACE ("NsGetType"); 187 188 189 if (!handle) 190 { 191 REPORT_WARNING (("NsGetType: Null handle\n")); 192 return_VALUE (ACPI_TYPE_ANY); 193 } 194 195 return_VALUE (((ACPI_NAMESPACE_NODE *) handle)->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 OBJECT_TYPE_INTERNAL Type) 213{ 214 FUNCTION_TRACE ("NsLocal"); 215 216 217 if (!AcpiCmValidObjectType (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: AcpiNsInternalizeName 232 * 233 * PARAMETERS: *ExternalName - External representation of name 234 * **Converted Name - Where to return the resulting 235 * internal represention of the name 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 240 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 241 * 242 ****************************************************************************/ 243 244ACPI_STATUS 245AcpiNsInternalizeName ( 246 NATIVE_CHAR *ExternalName, 247 NATIVE_CHAR **ConvertedName) 248{ 249 NATIVE_CHAR *Result = NULL; 250 NATIVE_CHAR *InternalName; 251 UINT32 NumSegments; 252 BOOLEAN FullyQualified = FALSE; 253 UINT32 i; 254 255 256 FUNCTION_TRACE ("NsInternalizeName"); 257 258 259 if ((!ExternalName) || 260 (*ExternalName == 0) || 261 (!ConvertedName)) 262 { 263 return_ACPI_STATUS (AE_BAD_PARAMETER); 264 } 265 266 267 /* 268 * For the internal name, the required length is 4 bytes 269 * per segment, plus 1 each for RootPrefix, MultiNamePrefixOp, 270 * segment count, trailing null (which is not really needed, 271 * but no there's harm in putting it there) 272 * 273 * strlen() + 1 covers the first NameSeg, which has no 274 * path separator 275 */ 276 277 if (AcpiNsValidRootPrefix (ExternalName[0])) 278 { 279 FullyQualified = TRUE; 280 ExternalName++; 281 } 282 283 284 /* 285 * Determine the number of ACPI name "segments" by counting 286 * the number of path separators within the string. Start 287 * with one segment since the segment count is (# separators) 288 * + 1, and zero separators is ok. 289 */ 290 291 NumSegments = 1; 292 for (i = 0; ExternalName[i]; i++) 293 { 294 if (AcpiNsValidPathSeparator (ExternalName[i])) 295 { 296 NumSegments++; 297 } 298 } 299 300 301 /* We need a segment to store the internal version of the name */ 302 303 InternalName = AcpiCmCallocate ((ACPI_NAME_SIZE * NumSegments) + 4); 304 if (!InternalName) 305 { 306 return_ACPI_STATUS (AE_NO_MEMORY); 307 } 308 309 310 /* Setup the correct prefixes, counts, and pointers */ 311 312 if (FullyQualified) 313 { 314 InternalName[0] = '\\'; 315 InternalName[1] = AML_MULTI_NAME_PREFIX_OP; 316 InternalName[2] = (char) NumSegments; 317 Result = &InternalName[3]; 318 } 319 else 320 { 321 InternalName[0] = AML_MULTI_NAME_PREFIX_OP; 322 InternalName[1] = (char) NumSegments; 323 Result = &InternalName[2]; 324 } 325 326 327 /* Build the name (minus path separators) */ 328 329 for (; NumSegments; NumSegments--) 330 { 331 for (i = 0; i < ACPI_NAME_SIZE; i++) 332 { 333 if (AcpiNsValidPathSeparator (*ExternalName) || 334 (*ExternalName == 0)) 335 { 336 /* 337 * Pad the segment with underscore(s) if 338 * segment is short 339 */ 340 341 Result[i] = '_'; 342 } 343 344 else 345 { 346 /* Convert INT8 to uppercase and save it */ 347 348 Result[i] = (char) TOUPPER (*ExternalName); 349 ExternalName++; 350 } 351 352 } 353 354 /* Now we must have a path separator, or the pathname is bad */ 355 356 if (!AcpiNsValidPathSeparator (*ExternalName) && 357 (*ExternalName != 0)) 358 { 359 AcpiCmFree (InternalName); 360 return_ACPI_STATUS (AE_BAD_PARAMETER); 361 } 362 363 /* Move on the next segment */ 364 365 ExternalName++; 366 Result += ACPI_NAME_SIZE; 367 } 368 369 370 /* Return the completed name */ 371 372 /* Terminate the string! */ 373 *Result = 0; 374 *ConvertedName = InternalName; 375 376 377 if (FullyQualified) 378 { 379 DEBUG_PRINT (TRACE_EXEC, 380 ("NsInternalizeName: returning [%p] (abs) \"\\%s\"\n", 381 InternalName, &InternalName[3])); 382 } 383 else 384 { 385 DEBUG_PRINT (TRACE_EXEC, 386 ("NsInternalizeName: returning [%p] (rel) \"%s\"\n", 387 InternalName, &InternalName[2])); 388 } 389 390 return_ACPI_STATUS (AE_OK); 391} 392 393 394/**************************************************************************** 395 * 396 * FUNCTION: AcpiNsExternalizeName 397 * 398 * PARAMETERS: *InternalName - Internal representation of name 399 * **ConvertedName - Where to return the resulting 400 * external representation of name 401 * 402 * RETURN: Status 403 * 404 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 405 * to its external form (e.g. "\_PR_.CPU0") 406 * 407 ****************************************************************************/ 408 409ACPI_STATUS 410AcpiNsExternalizeName ( 411 UINT32 InternalNameLength, 412 char *InternalName, 413 UINT32 *ConvertedNameLength, 414 char **ConvertedName) 415{ 416 UINT32 PrefixLength = 0; 417 UINT32 NamesIndex = 0; 418 UINT32 NamesCount = 0; 419 UINT32 i = 0; 420 UINT32 j = 0; 421 422 423 FUNCTION_TRACE ("NsExternalizeName"); 424 425 426 if (!InternalNameLength || 427 !InternalName || 428 !ConvertedNameLength || 429 !ConvertedName) 430 { 431 return_ACPI_STATUS (AE_BAD_PARAMETER); 432 } 433 434 435 /* 436 * Check for a prefix (one '\' | one or more '^'). 437 */ 438 switch (InternalName[0]) 439 { 440 case '\\': 441 PrefixLength = 1; 442 break; 443 444 case '^': 445 for (i = 0; i < InternalNameLength; i++) 446 { 447 if (InternalName[i] != '^') 448 { 449 PrefixLength = i + 1; 450 } 451 } 452 453 if (i == InternalNameLength) 454 { 455 PrefixLength = i; 456 } 457 458 break; 459 } 460 461 /* 462 * Check for object names. Note that there could be 0-255 of these 463 * 4-byte elements. 464 */ 465 if (PrefixLength < InternalNameLength) 466 { 467 switch (InternalName[PrefixLength]) 468 { 469 470 /* <count> 4-byte names */ 471 472 case AML_MULTI_NAME_PREFIX_OP: 473 NamesIndex = PrefixLength + 2; 474 NamesCount = (UINT32) InternalName[PrefixLength + 1]; 475 break; 476 477 478 /* two 4-byte names */ 479 480 case AML_DUAL_NAME_PREFIX: 481 NamesIndex = PrefixLength + 1; 482 NamesCount = 2; 483 break; 484 485 486 /* NullName */ 487 488 case 0: 489 NamesIndex = 0; 490 NamesCount = 0; 491 break; 492 493 494 /* one 4-byte name */ 495 496 default: 497 NamesIndex = PrefixLength; 498 NamesCount = 1; 499 break; 500 } 501 } 502 503 /* 504 * Calculate the length of ConvertedName, which equals the length 505 * of the prefix, length of all object names, length of any required 506 * punctuation ('.') between object names, plus the NULL terminator. 507 */ 508 *ConvertedNameLength = PrefixLength + (4 * NamesCount) + 509 ((NamesCount > 0) ? (NamesCount - 1) : 0) + 1; 510 511 /* 512 * Check to see if we're still in bounds. If not, there's a problem 513 * with InternalName (invalid format). 514 */ 515 if (*ConvertedNameLength > InternalNameLength) 516 { 517 REPORT_ERROR (("NsExternalizeName: Invalid internal name\n")); 518 return_ACPI_STATUS (AE_BAD_PATHNAME); 519 } 520 521 /* 522 * Build ConvertedName... 523 */ 524 525 (*ConvertedName) = AcpiCmCallocate (*ConvertedNameLength); 526 if (!(*ConvertedName)) 527 { 528 return_ACPI_STATUS (AE_NO_MEMORY); 529 } 530 531 j = 0; 532 533 for (i = 0; i < PrefixLength; i++) 534 { 535 (*ConvertedName)[j++] = InternalName[i]; 536 } 537 538 if (NamesCount > 0) 539 { 540 for (i = 0; i < NamesCount; i++) 541 { 542 if (i > 0) 543 { 544 (*ConvertedName)[j++] = '.'; 545 } 546 547 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 548 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 549 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 550 (*ConvertedName)[j++] = InternalName[NamesIndex++]; 551 } 552 } 553 554 return_ACPI_STATUS (AE_OK); 555} 556 557 558/**************************************************************************** 559 * 560 * FUNCTION: AcpiNsConvertHandleToEntry 561 * 562 * PARAMETERS: Handle - Handle to be converted to an Node 563 * 564 * RETURN: A Name table entry pointer 565 * 566 * DESCRIPTION: Convert a namespace handle to a real Node 567 * 568 ****************************************************************************/ 569 570ACPI_NAMESPACE_NODE * 571AcpiNsConvertHandleToEntry ( 572 ACPI_HANDLE Handle) 573{ 574 575 /* 576 * Simple implementation for now; 577 * TBD: [Future] Real integer handles allow for more verification 578 * and keep all pointers within this subsystem! 579 */ 580 581 if (!Handle) 582 { 583 return (NULL); 584 } 585 586 if (Handle == ACPI_ROOT_OBJECT) 587 { 588 return (AcpiGbl_RootNode); 589 } 590 591 592 /* We can at least attempt to verify the handle */ 593 594 if (!VALID_DESCRIPTOR_TYPE (Handle, ACPI_DESC_TYPE_NAMED)) 595 { 596 return (NULL); 597 } 598 599 return ((ACPI_NAMESPACE_NODE *) Handle); 600} 601 602 603/**************************************************************************** 604 * 605 * FUNCTION: AcpiNsConvertEntryToHandle 606 * 607 * PARAMETERS: Node - Node to be converted to a Handle 608 * 609 * RETURN: An USER ACPI_HANDLE 610 * 611 * DESCRIPTION: Convert a real Node to a namespace handle 612 * 613 ****************************************************************************/ 614 615ACPI_HANDLE 616AcpiNsConvertEntryToHandle ( 617 ACPI_NAMESPACE_NODE *Node) 618{ 619 620 621 /* 622 * Simple implementation for now; 623 * TBD: [Future] Real integer handles allow for more verification 624 * and keep all pointers within this subsystem! 625 */ 626 627 return ((ACPI_HANDLE) Node); 628 629 630/* --------------------------------------------------- 631 632 if (!Node) 633 { 634 return (NULL); 635 } 636 637 if (Node == AcpiGbl_RootNode) 638 { 639 return (ACPI_ROOT_OBJECT); 640 } 641 642 643 return ((ACPI_HANDLE) Node); 644------------------------------------------------------*/ 645} 646 647 648/****************************************************************************** 649 * 650 * FUNCTION: AcpiNsTerminate 651 * 652 * PARAMETERS: none 653 * 654 * RETURN: none 655 * 656 * DESCRIPTION: free memory allocated for table storage. 657 * 658 ******************************************************************************/ 659 660void 661AcpiNsTerminate (void) 662{ 663 ACPI_OPERAND_OBJECT *ObjDesc; 664 ACPI_NAMESPACE_NODE *ThisNode; 665 666 667 FUNCTION_TRACE ("NsTerminate"); 668 669 670 ThisNode = AcpiGbl_RootNode; 671 672 /* 673 * 1) Free the entire namespace -- all objects, tables, and stacks 674 */ 675 /* 676 * Delete all objects linked to the root 677 * (additional table descriptors) 678 */ 679 680 AcpiNsDeleteNamespaceSubtree (ThisNode); 681 682 /* Detach any object(s) attached to the root */ 683 684 ObjDesc = AcpiNsGetAttachedObject (ThisNode); 685 if (ObjDesc) 686 { 687 AcpiNsDetachObject (ThisNode); 688 AcpiCmRemoveReference (ObjDesc); 689 } 690 691 AcpiNsDeleteChildren (ThisNode); 692 693 DEBUG_PRINT (ACPI_INFO, ("NsTerminate: Namespace freed\n")); 694 695 696 /* 697 * 2) Now we can delete the ACPI tables 698 */ 699 700 AcpiTbDeleteAcpiTables (); 701 702 DEBUG_PRINT (ACPI_INFO, ("NsTerminate: ACPI Tables freed\n")); 703 704 return_VOID; 705} 706 707 708/**************************************************************************** 709 * 710 * FUNCTION: AcpiNsOpensScope 711 * 712 * PARAMETERS: Type - A valid namespace type 713 * 714 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 715 * to the ACPI specification, else 0 716 * 717 ***************************************************************************/ 718 719UINT32 720AcpiNsOpensScope ( 721 OBJECT_TYPE_INTERNAL Type) 722{ 723 FUNCTION_TRACE_U32 ("NsOpensScope", Type); 724 725 726 if (!AcpiCmValidObjectType (Type)) 727 { 728 /* type code out of range */ 729 730 REPORT_WARNING (("NsOpensScope: Invalid Object Type\n")); 731 return_VALUE (NSP_NORMAL); 732 } 733 734 return_VALUE (((UINT32) AcpiGbl_NsProperties[Type]) & NSP_NEWSCOPE); 735} 736 737 738/**************************************************************************** 739 * 740 * FUNCTION: AcpiNsGetNode 741 * 742 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 743 * \ (backslash) and ^ (carat) prefixes, and the 744 * . (period) to separate segments are supported. 745 * StartNode - Root of subtree to be searched, or NS_ALL for the 746 * root of the name space. If Name is fully 747 * qualified (first INT8 is '\'), the passed value 748 * of Scope will not be accessed. 749 * ReturnNode - Where the Node is returned 750 * 751 * DESCRIPTION: Look up a name relative to a given scope and return the 752 * corresponding Node. NOTE: Scope can be null. 753 * 754 * MUTEX: Locks namespace 755 * 756 ***************************************************************************/ 757 758ACPI_STATUS 759AcpiNsGetNode ( 760 NATIVE_CHAR *Pathname, 761 ACPI_NAMESPACE_NODE *StartNode, 762 ACPI_NAMESPACE_NODE **ReturnNode) 763{ 764 ACPI_GENERIC_STATE ScopeInfo; 765 ACPI_STATUS Status; 766 NATIVE_CHAR *InternalPath = NULL; 767 768 769 FUNCTION_TRACE_PTR ("NsGetNte", Pathname); 770 771 772 ScopeInfo.Scope.Node = StartNode; 773 774 /* Ensure that the namespace has been initialized */ 775 776 if (!AcpiGbl_RootNode) 777 { 778 return_ACPI_STATUS (AE_NO_NAMESPACE); 779 } 780 781 if (!Pathname) 782 { 783 return_ACPI_STATUS (AE_BAD_PARAMETER); 784 } 785 786 787 /* Convert path to internal representation */ 788 789 Status = AcpiNsInternalizeName (Pathname, &InternalPath); 790 if (ACPI_FAILURE (Status)) 791 { 792 return_ACPI_STATUS (Status); 793 } 794 795 796 AcpiCmAcquireMutex (ACPI_MTX_NAMESPACE); 797 798 /* NS_ALL means start from the root */ 799 800 if (NS_ALL == ScopeInfo.Scope.Node) 801 { 802 ScopeInfo.Scope.Node = AcpiGbl_RootNode; 803 } 804 805 else 806 { 807 ScopeInfo.Scope.Node = StartNode; 808 if (!ScopeInfo.Scope.Node) 809 { 810 Status = AE_BAD_PARAMETER; 811 goto UnlockAndExit; 812 } 813 } 814 815 /* Lookup the name in the namespace */ 816 817 Status = AcpiNsLookup (&ScopeInfo, InternalPath, 818 ACPI_TYPE_ANY, IMODE_EXECUTE, 819 NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, 820 NULL, ReturnNode); 821 822 if (ACPI_FAILURE (Status)) 823 { 824 DEBUG_PRINT (ACPI_INFO, ("NsGetNte: %s, %s\n", 825 InternalPath, AcpiCmFormatException (Status))); 826 } 827 828 829UnlockAndExit: 830 831 AcpiCmReleaseMutex (ACPI_MTX_NAMESPACE); 832 833 /* Cleanup */ 834 835 AcpiCmFree (InternalPath); 836 837 return_ACPI_STATUS (Status); 838} 839 840 841/**************************************************************************** 842 * 843 * FUNCTION: AcpiNsFindParentName 844 * 845 * PARAMETERS: *ChildNode - Named Obj whose name is to be found 846 * 847 * RETURN: The ACPI name 848 * 849 * DESCRIPTION: Search for the given obj in its parent scope and return the 850 * name segment, or "????" if the parent name can't be found 851 * (which "should not happen"). 852 * 853 ***************************************************************************/ 854 855ACPI_NAME 856AcpiNsFindParentName ( 857 ACPI_NAMESPACE_NODE *ChildNode) 858{ 859 ACPI_NAMESPACE_NODE *ParentNode; 860 861 862 FUNCTION_TRACE ("FindParentName"); 863 864 865 if (ChildNode) 866 { 867 /* Valid entry. Get the parent Node */ 868 869 ParentNode = AcpiNsGetParentObject (ChildNode); 870 if (ParentNode) 871 { 872 DEBUG_PRINT (TRACE_EXEC, 873 ("Parent of %p [%4.4s] is %p [%4.4s]\n", 874 ChildNode, &ChildNode->Name, ParentNode, 875 &ParentNode->Name)); 876 877 if (ParentNode->Name) 878 { 879 return_VALUE (ParentNode->Name); 880 } 881 } 882 883 DEBUG_PRINT (TRACE_EXEC, 884 ("FindParentName: unable to find parent of %p (%4.4s)\n", 885 ChildNode, &ChildNode->Name)); 886 } 887 888 889 return_VALUE (ACPI_UNKNOWN_NAME); 890} 891 892 893#ifdef ACPI_DEBUG 894 895/**************************************************************************** 896 * 897 * FUNCTION: AcpiNsExistDownstreamSibling 898 * 899 * PARAMETERS: *Node - pointer to first Node to examine 900 * 901 * RETURN: TRUE if sibling is found, FALSE otherwise 902 * 903 * DESCRIPTION: Searches remainder of scope being processed to determine 904 * whether there is a downstream sibling to the current 905 * object. This function is used to determine what type of 906 * line drawing character to use when displaying namespace 907 * trees. 908 * 909 ***************************************************************************/ 910 911BOOLEAN 912AcpiNsExistDownstreamSibling ( 913 ACPI_NAMESPACE_NODE *Node) 914{ 915 916 if (!Node) 917 { 918 return (FALSE); 919 } 920 921 if (Node->Name) 922 { 923 return (TRUE); 924 } 925 926 return (FALSE); 927} 928 929#endif /* ACPI_DEBUG */ 930 931 932/**************************************************************************** 933 * 934 * FUNCTION: AcpiNsGetParentObject 935 * 936 * PARAMETERS: Node - Current table entry 937 * 938 * RETURN: Parent entry of the given entry 939 * 940 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. 941 * 942 ***************************************************************************/ 943 944 945ACPI_NAMESPACE_NODE * 946AcpiNsGetParentObject ( 947 ACPI_NAMESPACE_NODE *Node) 948{ 949 950 951 /* 952 * Walk to the end of this peer list. 953 * The last entry is marked with a flag and the peer 954 * pointer is really a pointer back to the parent. 955 * This saves putting a parent back pointer in each and 956 * every named object! 957 */ 958 959 while (!(Node->Flags & ANOBJ_END_OF_PEER_LIST)) 960 { 961 Node = Node->Peer; 962 } 963 964 965 return (Node->Peer); 966} 967 968 969/**************************************************************************** 970 * 971 * FUNCTION: AcpiNsGetNextValidObject 972 * 973 * PARAMETERS: Node - Current table entry 974 * 975 * RETURN: Next valid object in the table. NULL if no more valid 976 * objects 977 * 978 * DESCRIPTION: Find the next valid object within a name table. 979 * Useful for implementing NULL-end-of-list loops. 980 * 981 ***************************************************************************/ 982 983 984ACPI_NAMESPACE_NODE * 985AcpiNsGetNextValidObject ( 986 ACPI_NAMESPACE_NODE *Node) 987{ 988 989 /* If we are at the end of this peer list, return NULL */ 990 991 if (Node->Flags & ANOBJ_END_OF_PEER_LIST) 992 { 993 return NULL; 994 } 995 996 /* Otherwise just return the next peer */ 997 998 return (Node->Peer); 999} 1000 1001 1002