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