1/****************************************************************************** 2 * 3 * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing 4 * parents and siblings and Scope manipulation 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45#include <acpi/acpi.h> 46#include <acpi/acnamesp.h> 47#include <acpi/amlcode.h> 48#include <acpi/actables.h> 49 50#define _COMPONENT ACPI_NAMESPACE 51ACPI_MODULE_NAME("nsutils") 52 53/* Local prototypes */ 54static u8 acpi_ns_valid_path_separator(char sep); 55 56#ifdef ACPI_OBSOLETE_FUNCTIONS 57acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); 58#endif 59 60/******************************************************************************* 61 * 62 * FUNCTION: acpi_ns_report_error 63 * 64 * PARAMETERS: module_name - Caller's module name (for error output) 65 * line_number - Caller's line number (for error output) 66 * internal_name - Name or path of the namespace node 67 * lookup_status - Exception code from NS lookup 68 * 69 * RETURN: None 70 * 71 * DESCRIPTION: Print warning message with full pathname 72 * 73 ******************************************************************************/ 74 75void 76acpi_ns_report_error(char *module_name, 77 u32 line_number, 78 char *internal_name, acpi_status lookup_status) 79{ 80 acpi_status status; 81 u32 bad_name; 82 char *name = NULL; 83 84 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); 85 86 if (lookup_status == AE_BAD_CHARACTER) { 87 88 /* There is a non-ascii character in the name */ 89 90 ACPI_MOVE_32_TO_32(&bad_name, internal_name); 91 acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); 92 } else { 93 /* Convert path to external format */ 94 95 status = acpi_ns_externalize_name(ACPI_UINT32_MAX, 96 internal_name, NULL, &name); 97 98 /* Print target name */ 99 100 if (ACPI_SUCCESS(status)) { 101 acpi_os_printf("[%s]", name); 102 } else { 103 acpi_os_printf("[COULD NOT EXTERNALIZE NAME]"); 104 } 105 106 if (name) { 107 ACPI_FREE(name); 108 } 109 } 110 111 acpi_os_printf(" Namespace lookup failure, %s\n", 112 acpi_format_exception(lookup_status)); 113} 114 115/******************************************************************************* 116 * 117 * FUNCTION: acpi_ns_report_method_error 118 * 119 * PARAMETERS: module_name - Caller's module name (for error output) 120 * line_number - Caller's line number (for error output) 121 * Message - Error message to use on failure 122 * prefix_node - Prefix relative to the path 123 * Path - Path to the node (optional) 124 * method_status - Execution status 125 * 126 * RETURN: None 127 * 128 * DESCRIPTION: Print warning message with full pathname 129 * 130 ******************************************************************************/ 131 132void 133acpi_ns_report_method_error(char *module_name, 134 u32 line_number, 135 char *message, 136 struct acpi_namespace_node *prefix_node, 137 char *path, acpi_status method_status) 138{ 139 acpi_status status; 140 struct acpi_namespace_node *node = prefix_node; 141 142 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); 143 144 if (path) { 145 status = 146 acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH, 147 &node); 148 if (ACPI_FAILURE(status)) { 149 acpi_os_printf("[Could not get node by pathname]"); 150 } 151 } 152 153 acpi_ns_print_node_pathname(node, message); 154 acpi_os_printf(", %s\n", acpi_format_exception(method_status)); 155} 156 157/******************************************************************************* 158 * 159 * FUNCTION: acpi_ns_print_node_pathname 160 * 161 * PARAMETERS: Node - Object 162 * Message - Prefix message 163 * 164 * DESCRIPTION: Print an object's full namespace pathname 165 * Manages allocation/freeing of a pathname buffer 166 * 167 ******************************************************************************/ 168 169void 170acpi_ns_print_node_pathname(struct acpi_namespace_node *node, char *message) 171{ 172 struct acpi_buffer buffer; 173 acpi_status status; 174 175 if (!node) { 176 acpi_os_printf("[NULL NAME]"); 177 return; 178 } 179 180 /* Convert handle to full pathname and print it (with supplied message) */ 181 182 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 183 184 status = acpi_ns_handle_to_pathname(node, &buffer); 185 if (ACPI_SUCCESS(status)) { 186 if (message) { 187 acpi_os_printf("%s ", message); 188 } 189 190 acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node); 191 ACPI_FREE(buffer.pointer); 192 } 193} 194 195/******************************************************************************* 196 * 197 * FUNCTION: acpi_ns_valid_root_prefix 198 * 199 * PARAMETERS: Prefix - Character to be checked 200 * 201 * RETURN: TRUE if a valid prefix 202 * 203 * DESCRIPTION: Check if a character is a valid ACPI Root prefix 204 * 205 ******************************************************************************/ 206 207u8 acpi_ns_valid_root_prefix(char prefix) 208{ 209 210 return ((u8) (prefix == '\\')); 211} 212 213/******************************************************************************* 214 * 215 * FUNCTION: acpi_ns_valid_path_separator 216 * 217 * PARAMETERS: Sep - Character to be checked 218 * 219 * RETURN: TRUE if a valid path separator 220 * 221 * DESCRIPTION: Check if a character is a valid ACPI path separator 222 * 223 ******************************************************************************/ 224 225static u8 acpi_ns_valid_path_separator(char sep) 226{ 227 228 return ((u8) (sep == '.')); 229} 230 231/******************************************************************************* 232 * 233 * FUNCTION: acpi_ns_get_type 234 * 235 * PARAMETERS: Node - Parent Node to be examined 236 * 237 * RETURN: Type field from Node whose handle is passed 238 * 239 * DESCRIPTION: Return the type of a Namespace node 240 * 241 ******************************************************************************/ 242 243acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) 244{ 245 ACPI_FUNCTION_TRACE(ns_get_type); 246 247 if (!node) { 248 ACPI_WARNING((AE_INFO, "Null Node parameter")); 249 return_UINT32(ACPI_TYPE_ANY); 250 } 251 252 return_UINT32((acpi_object_type) node->type); 253} 254 255/******************************************************************************* 256 * 257 * FUNCTION: acpi_ns_local 258 * 259 * PARAMETERS: Type - A namespace object type 260 * 261 * RETURN: LOCAL if names must be found locally in objects of the 262 * passed type, 0 if enclosing scopes should be searched 263 * 264 * DESCRIPTION: Returns scope rule for the given object type. 265 * 266 ******************************************************************************/ 267 268u32 acpi_ns_local(acpi_object_type type) 269{ 270 ACPI_FUNCTION_TRACE(ns_local); 271 272 if (!acpi_ut_valid_object_type(type)) { 273 274 /* Type code out of range */ 275 276 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); 277 return_UINT32(ACPI_NS_NORMAL); 278 } 279 280 return_UINT32((u32) acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); 281} 282 283/******************************************************************************* 284 * 285 * FUNCTION: acpi_ns_get_internal_name_length 286 * 287 * PARAMETERS: Info - Info struct initialized with the 288 * external name pointer. 289 * 290 * RETURN: None 291 * 292 * DESCRIPTION: Calculate the length of the internal (AML) namestring 293 * corresponding to the external (ASL) namestring. 294 * 295 ******************************************************************************/ 296 297void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) 298{ 299 char *next_external_char; 300 u32 i; 301 302 ACPI_FUNCTION_ENTRY(); 303 304 next_external_char = info->external_name; 305 info->num_carats = 0; 306 info->num_segments = 0; 307 info->fully_qualified = FALSE; 308 309 /* 310 * For the internal name, the required length is 4 bytes per segment, plus 311 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null 312 * (which is not really needed, but no there's harm in putting it there) 313 * 314 * strlen() + 1 covers the first name_seg, which has no path separator 315 */ 316 if (acpi_ns_valid_root_prefix(next_external_char[0])) { 317 info->fully_qualified = TRUE; 318 next_external_char++; 319 } else { 320 /* 321 * Handle Carat prefixes 322 */ 323 while (*next_external_char == '^') { 324 info->num_carats++; 325 next_external_char++; 326 } 327 } 328 329 /* 330 * Determine the number of ACPI name "segments" by counting the number of 331 * path separators within the string. Start with one segment since the 332 * segment count is [(# separators) + 1], and zero separators is ok. 333 */ 334 if (*next_external_char) { 335 info->num_segments = 1; 336 for (i = 0; next_external_char[i]; i++) { 337 if (acpi_ns_valid_path_separator(next_external_char[i])) { 338 info->num_segments++; 339 } 340 } 341 } 342 343 info->length = (ACPI_NAME_SIZE * info->num_segments) + 344 4 + info->num_carats; 345 346 info->next_external_char = next_external_char; 347} 348 349/******************************************************************************* 350 * 351 * FUNCTION: acpi_ns_build_internal_name 352 * 353 * PARAMETERS: Info - Info struct fully initialized 354 * 355 * RETURN: Status 356 * 357 * DESCRIPTION: Construct the internal (AML) namestring 358 * corresponding to the external (ASL) namestring. 359 * 360 ******************************************************************************/ 361 362acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) 363{ 364 u32 num_segments = info->num_segments; 365 char *internal_name = info->internal_name; 366 char *external_name = info->next_external_char; 367 char *result = NULL; 368 acpi_native_uint i; 369 370 ACPI_FUNCTION_TRACE(ns_build_internal_name); 371 372 /* Setup the correct prefixes, counts, and pointers */ 373 374 if (info->fully_qualified) { 375 internal_name[0] = '\\'; 376 377 if (num_segments <= 1) { 378 result = &internal_name[1]; 379 } else if (num_segments == 2) { 380 internal_name[1] = AML_DUAL_NAME_PREFIX; 381 result = &internal_name[2]; 382 } else { 383 internal_name[1] = AML_MULTI_NAME_PREFIX_OP; 384 internal_name[2] = (char)num_segments; 385 result = &internal_name[3]; 386 } 387 } else { 388 /* 389 * Not fully qualified. 390 * Handle Carats first, then append the name segments 391 */ 392 i = 0; 393 if (info->num_carats) { 394 for (i = 0; i < info->num_carats; i++) { 395 internal_name[i] = '^'; 396 } 397 } 398 399 if (num_segments <= 1) { 400 result = &internal_name[i]; 401 } else if (num_segments == 2) { 402 internal_name[i] = AML_DUAL_NAME_PREFIX; 403 result = &internal_name[(acpi_native_uint) (i + 1)]; 404 } else { 405 internal_name[i] = AML_MULTI_NAME_PREFIX_OP; 406 internal_name[(acpi_native_uint) (i + 1)] = 407 (char)num_segments; 408 result = &internal_name[(acpi_native_uint) (i + 2)]; 409 } 410 } 411 412 /* Build the name (minus path separators) */ 413 414 for (; num_segments; num_segments--) { 415 for (i = 0; i < ACPI_NAME_SIZE; i++) { 416 if (acpi_ns_valid_path_separator(*external_name) || 417 (*external_name == 0)) { 418 419 /* Pad the segment with underscore(s) if segment is short */ 420 421 result[i] = '_'; 422 } else { 423 /* Convert the character to uppercase and save it */ 424 425 result[i] = 426 (char)ACPI_TOUPPER((int)*external_name); 427 external_name++; 428 } 429 } 430 431 /* Now we must have a path separator, or the pathname is bad */ 432 433 if (!acpi_ns_valid_path_separator(*external_name) && 434 (*external_name != 0)) { 435 return_ACPI_STATUS(AE_BAD_PARAMETER); 436 } 437 438 /* Move on the next segment */ 439 440 external_name++; 441 result += ACPI_NAME_SIZE; 442 } 443 444 /* Terminate the string */ 445 446 *result = 0; 447 448 if (info->fully_qualified) { 449 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 450 "Returning [%p] (abs) \"\\%s\"\n", 451 internal_name, internal_name)); 452 } else { 453 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 454 internal_name, internal_name)); 455 } 456 457 return_ACPI_STATUS(AE_OK); 458} 459 460/******************************************************************************* 461 * 462 * FUNCTION: acpi_ns_internalize_name 463 * 464 * PARAMETERS: *external_name - External representation of name 465 * **Converted Name - Where to return the resulting 466 * internal represention of the name 467 * 468 * RETURN: Status 469 * 470 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 471 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 472 * 473 *******************************************************************************/ 474 475acpi_status acpi_ns_internalize_name(char *external_name, char **converted_name) 476{ 477 char *internal_name; 478 struct acpi_namestring_info info; 479 acpi_status status; 480 481 ACPI_FUNCTION_TRACE(ns_internalize_name); 482 483 if ((!external_name) || (*external_name == 0) || (!converted_name)) { 484 return_ACPI_STATUS(AE_BAD_PARAMETER); 485 } 486 487 /* Get the length of the new internal name */ 488 489 info.external_name = external_name; 490 acpi_ns_get_internal_name_length(&info); 491 492 /* We need a segment to store the internal name */ 493 494 internal_name = ACPI_ALLOCATE_ZEROED(info.length); 495 if (!internal_name) { 496 return_ACPI_STATUS(AE_NO_MEMORY); 497 } 498 499 /* Build the name */ 500 501 info.internal_name = internal_name; 502 status = acpi_ns_build_internal_name(&info); 503 if (ACPI_FAILURE(status)) { 504 ACPI_FREE(internal_name); 505 return_ACPI_STATUS(status); 506 } 507 508 *converted_name = internal_name; 509 return_ACPI_STATUS(AE_OK); 510} 511 512/******************************************************************************* 513 * 514 * FUNCTION: acpi_ns_externalize_name 515 * 516 * PARAMETERS: internal_name_length - Lenth of the internal name below 517 * internal_name - Internal representation of name 518 * converted_name_length - Where the length is returned 519 * converted_name - Where the resulting external name 520 * is returned 521 * 522 * RETURN: Status 523 * 524 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 525 * to its external (printable) form (e.g. "\_PR_.CPU0") 526 * 527 ******************************************************************************/ 528 529acpi_status 530acpi_ns_externalize_name(u32 internal_name_length, 531 char *internal_name, 532 u32 * converted_name_length, char **converted_name) 533{ 534 acpi_native_uint names_index = 0; 535 acpi_native_uint num_segments = 0; 536 acpi_native_uint required_length; 537 acpi_native_uint prefix_length = 0; 538 acpi_native_uint i = 0; 539 acpi_native_uint j = 0; 540 541 ACPI_FUNCTION_TRACE(ns_externalize_name); 542 543 if (!internal_name_length || !internal_name || !converted_name) { 544 return_ACPI_STATUS(AE_BAD_PARAMETER); 545 } 546 547 /* 548 * Check for a prefix (one '\' | one or more '^'). 549 */ 550 switch (internal_name[0]) { 551 case '\\': 552 prefix_length = 1; 553 break; 554 555 case '^': 556 for (i = 0; i < internal_name_length; i++) { 557 if (internal_name[i] == '^') { 558 prefix_length = i + 1; 559 } else { 560 break; 561 } 562 } 563 564 if (i == internal_name_length) { 565 prefix_length = i; 566 } 567 568 break; 569 570 default: 571 break; 572 } 573 574 /* 575 * Check for object names. Note that there could be 0-255 of these 576 * 4-byte elements. 577 */ 578 if (prefix_length < internal_name_length) { 579 switch (internal_name[prefix_length]) { 580 case AML_MULTI_NAME_PREFIX_OP: 581 582 /* <count> 4-byte names */ 583 584 names_index = prefix_length + 2; 585 num_segments = (acpi_native_uint) (u8) 586 internal_name[(acpi_native_uint) 587 (prefix_length + 1)]; 588 break; 589 590 case AML_DUAL_NAME_PREFIX: 591 592 /* Two 4-byte names */ 593 594 names_index = prefix_length + 1; 595 num_segments = 2; 596 break; 597 598 case 0: 599 600 /* null_name */ 601 602 names_index = 0; 603 num_segments = 0; 604 break; 605 606 default: 607 608 /* one 4-byte name */ 609 610 names_index = prefix_length; 611 num_segments = 1; 612 break; 613 } 614 } 615 616 /* 617 * Calculate the length of converted_name, which equals the length 618 * of the prefix, length of all object names, length of any required 619 * punctuation ('.') between object names, plus the NULL terminator. 620 */ 621 required_length = prefix_length + (4 * num_segments) + 622 ((num_segments > 0) ? (num_segments - 1) : 0) + 1; 623 624 /* 625 * Check to see if we're still in bounds. If not, there's a problem 626 * with internal_name (invalid format). 627 */ 628 if (required_length > internal_name_length) { 629 ACPI_ERROR((AE_INFO, "Invalid internal name")); 630 return_ACPI_STATUS(AE_BAD_PATHNAME); 631 } 632 633 /* 634 * Build converted_name 635 */ 636 *converted_name = ACPI_ALLOCATE_ZEROED(required_length); 637 if (!(*converted_name)) { 638 return_ACPI_STATUS(AE_NO_MEMORY); 639 } 640 641 j = 0; 642 643 for (i = 0; i < prefix_length; i++) { 644 (*converted_name)[j++] = internal_name[i]; 645 } 646 647 if (num_segments > 0) { 648 for (i = 0; i < num_segments; i++) { 649 if (i > 0) { 650 (*converted_name)[j++] = '.'; 651 } 652 653 (*converted_name)[j++] = internal_name[names_index++]; 654 (*converted_name)[j++] = internal_name[names_index++]; 655 (*converted_name)[j++] = internal_name[names_index++]; 656 (*converted_name)[j++] = internal_name[names_index++]; 657 } 658 } 659 660 if (converted_name_length) { 661 *converted_name_length = (u32) required_length; 662 } 663 664 return_ACPI_STATUS(AE_OK); 665} 666 667/******************************************************************************* 668 * 669 * FUNCTION: acpi_ns_map_handle_to_node 670 * 671 * PARAMETERS: Handle - Handle to be converted to an Node 672 * 673 * RETURN: A Name table entry pointer 674 * 675 * DESCRIPTION: Convert a namespace handle to a real Node 676 * 677 * Note: Real integer handles would allow for more verification 678 * and keep all pointers within this subsystem - however this introduces 679 * more (and perhaps unnecessary) overhead. 680 * 681 ******************************************************************************/ 682 683struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle) 684{ 685 686 ACPI_FUNCTION_ENTRY(); 687 688 /* 689 * Simple implementation 690 */ 691 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { 692 return (acpi_gbl_root_node); 693 } 694 695 /* We can at least attempt to verify the handle */ 696 697 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) { 698 return (NULL); 699 } 700 701 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); 702} 703 704/******************************************************************************* 705 * 706 * FUNCTION: acpi_ns_convert_entry_to_handle 707 * 708 * PARAMETERS: Node - Node to be converted to a Handle 709 * 710 * RETURN: A user handle 711 * 712 * DESCRIPTION: Convert a real Node to a namespace handle 713 * 714 ******************************************************************************/ 715 716acpi_handle acpi_ns_convert_entry_to_handle(struct acpi_namespace_node *node) 717{ 718 719 /* 720 * Simple implementation for now; 721 */ 722 return ((acpi_handle) node); 723 724/* Example future implementation --------------------- 725 726 if (!Node) 727 { 728 return (NULL); 729 } 730 731 if (Node == acpi_gbl_root_node) 732 { 733 return (ACPI_ROOT_OBJECT); 734 } 735 736 return ((acpi_handle) Node); 737------------------------------------------------------*/ 738} 739 740/******************************************************************************* 741 * 742 * FUNCTION: acpi_ns_terminate 743 * 744 * PARAMETERS: none 745 * 746 * RETURN: none 747 * 748 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 749 * 750 ******************************************************************************/ 751 752void acpi_ns_terminate(void) 753{ 754 union acpi_operand_object *obj_desc; 755 756 ACPI_FUNCTION_TRACE(ns_terminate); 757 758 /* 759 * 1) Free the entire namespace -- all nodes and objects 760 * 761 * Delete all object descriptors attached to namepsace nodes 762 */ 763 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node); 764 765 /* Detach any objects attached to the root */ 766 767 obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); 768 if (obj_desc) { 769 acpi_ns_detach_object(acpi_gbl_root_node); 770 } 771 772 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); 773 return_VOID; 774} 775 776/******************************************************************************* 777 * 778 * FUNCTION: acpi_ns_opens_scope 779 * 780 * PARAMETERS: Type - A valid namespace type 781 * 782 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 783 * to the ACPI specification, else 0 784 * 785 ******************************************************************************/ 786 787u32 acpi_ns_opens_scope(acpi_object_type type) 788{ 789 ACPI_FUNCTION_TRACE_STR(ns_opens_scope, acpi_ut_get_type_name(type)); 790 791 if (!acpi_ut_valid_object_type(type)) { 792 793 /* type code out of range */ 794 795 ACPI_WARNING((AE_INFO, "Invalid Object Type %X", type)); 796 return_UINT32(ACPI_NS_NORMAL); 797 } 798 799 return_UINT32(((u32) acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); 800} 801 802/******************************************************************************* 803 * 804 * FUNCTION: acpi_ns_get_node 805 * 806 * PARAMETERS: *Pathname - Name to be found, in external (ASL) format. The 807 * \ (backslash) and ^ (carat) prefixes, and the 808 * . (period) to separate segments are supported. 809 * prefix_node - Root of subtree to be searched, or NS_ALL for the 810 * root of the name space. If Name is fully 811 * qualified (first s8 is '\'), the passed value 812 * of Scope will not be accessed. 813 * Flags - Used to indicate whether to perform upsearch or 814 * not. 815 * return_node - Where the Node is returned 816 * 817 * DESCRIPTION: Look up a name relative to a given scope and return the 818 * corresponding Node. NOTE: Scope can be null. 819 * 820 * MUTEX: Locks namespace 821 * 822 ******************************************************************************/ 823 824acpi_status 825acpi_ns_get_node(struct acpi_namespace_node *prefix_node, 826 char *pathname, 827 u32 flags, struct acpi_namespace_node **return_node) 828{ 829 union acpi_generic_state scope_info; 830 acpi_status status; 831 char *internal_path; 832 833 ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); 834 835 if (!pathname) { 836 *return_node = prefix_node; 837 if (!prefix_node) { 838 *return_node = acpi_gbl_root_node; 839 } 840 return_ACPI_STATUS(AE_OK); 841 } 842 843 /* Convert path to internal representation */ 844 845 status = acpi_ns_internalize_name(pathname, &internal_path); 846 if (ACPI_FAILURE(status)) { 847 return_ACPI_STATUS(status); 848 } 849 850 /* Must lock namespace during lookup */ 851 852 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 853 if (ACPI_FAILURE(status)) { 854 goto cleanup; 855 } 856 857 /* Setup lookup scope (search starting point) */ 858 859 scope_info.scope.node = prefix_node; 860 861 /* Lookup the name in the namespace */ 862 863 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, 864 ACPI_IMODE_EXECUTE, 865 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, 866 return_node); 867 if (ACPI_FAILURE(status)) { 868 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n", 869 pathname, acpi_format_exception(status))); 870 } 871 872 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 873 874 cleanup: 875 ACPI_FREE(internal_path); 876 return_ACPI_STATUS(status); 877} 878 879/******************************************************************************* 880 * 881 * FUNCTION: acpi_ns_get_parent_node 882 * 883 * PARAMETERS: Node - Current table entry 884 * 885 * RETURN: Parent entry of the given entry 886 * 887 * DESCRIPTION: Obtain the parent entry for a given entry in the namespace. 888 * 889 ******************************************************************************/ 890 891struct acpi_namespace_node *acpi_ns_get_parent_node(struct acpi_namespace_node 892 *node) 893{ 894 ACPI_FUNCTION_ENTRY(); 895 896 if (!node) { 897 return (NULL); 898 } 899 900 /* 901 * Walk to the end of this peer list. The last entry is marked with a flag 902 * and the peer pointer is really a pointer back to the parent. This saves 903 * putting a parent back pointer in each and every named object! 904 */ 905 while (!(node->flags & ANOBJ_END_OF_PEER_LIST)) { 906 node = node->peer; 907 } 908 909 return (node->peer); 910} 911 912/******************************************************************************* 913 * 914 * FUNCTION: acpi_ns_get_next_valid_node 915 * 916 * PARAMETERS: Node - Current table entry 917 * 918 * RETURN: Next valid Node in the linked node list. NULL if no more valid 919 * nodes. 920 * 921 * DESCRIPTION: Find the next valid node within a name table. 922 * Useful for implementing NULL-end-of-list loops. 923 * 924 ******************************************************************************/ 925 926struct acpi_namespace_node *acpi_ns_get_next_valid_node(struct 927 acpi_namespace_node 928 *node) 929{ 930 931 /* If we are at the end of this peer list, return NULL */ 932 933 if (node->flags & ANOBJ_END_OF_PEER_LIST) { 934 return NULL; 935 } 936 937 /* Otherwise just return the next peer */ 938 939 return (node->peer); 940} 941 942#ifdef ACPI_OBSOLETE_FUNCTIONS 943/******************************************************************************* 944 * 945 * FUNCTION: acpi_ns_find_parent_name 946 * 947 * PARAMETERS: *child_node - Named Obj whose name is to be found 948 * 949 * RETURN: The ACPI name 950 * 951 * DESCRIPTION: Search for the given obj in its parent scope and return the 952 * name segment, or "????" if the parent name can't be found 953 * (which "should not happen"). 954 * 955 ******************************************************************************/ 956 957acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node * child_node) 958{ 959 struct acpi_namespace_node *parent_node; 960 961 ACPI_FUNCTION_TRACE(ns_find_parent_name); 962 963 if (child_node) { 964 965 /* Valid entry. Get the parent Node */ 966 967 parent_node = acpi_ns_get_parent_node(child_node); 968 if (parent_node) { 969 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 970 "Parent of %p [%4.4s] is %p [%4.4s]\n", 971 child_node, 972 acpi_ut_get_node_name(child_node), 973 parent_node, 974 acpi_ut_get_node_name(parent_node))); 975 976 if (parent_node->name.integer) { 977 return_VALUE((acpi_name) parent_node->name. 978 integer); 979 } 980 } 981 982 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 983 "Unable to find parent of %p (%4.4s)\n", 984 child_node, 985 acpi_ut_get_node_name(child_node))); 986 } 987 988 return_VALUE(ACPI_UNKNOWN_NAME); 989} 990#endif 991