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 - 2018, Intel Corp. 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 "accommon.h" 47 #include "acnamesp.h" 48 #include "amlcode.h" 49 50 #define _COMPONENT ACPI_NAMESPACE 51 ACPI_MODULE_NAME("nsutils") 52 53 /* Local prototypes */ 54 #ifdef ACPI_OBSOLETE_FUNCTIONS 55 acpi_name acpi_ns_find_parent_name(struct acpi_namespace_node *node_to_search); 56 #endif 57 58 /******************************************************************************* 59 * 60 * FUNCTION: acpi_ns_print_node_pathname 61 * 62 * PARAMETERS: node - Object 63 * message - Prefix message 64 * 65 * DESCRIPTION: Print an object's full namespace pathname 66 * Manages allocation/freeing of a pathname buffer 67 * 68 ******************************************************************************/ 69 70 void 71 acpi_ns_print_node_pathname(struct acpi_namespace_node *node, 72 const char *message) 73 { 74 struct acpi_buffer buffer; 75 acpi_status status; 76 77 if (!node) { 78 acpi_os_printf("[NULL NAME]"); 79 return; 80 } 81 82 /* Convert handle to full pathname and print it (with supplied message) */ 83 84 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 85 86 status = acpi_ns_handle_to_pathname(node, &buffer, TRUE); 87 if (ACPI_SUCCESS(status)) { 88 if (message) { 89 acpi_os_printf("%s ", message); 90 } 91 92 acpi_os_printf("%s", (char *)buffer.pointer); 93 ACPI_FREE(buffer.pointer); 94 } 95 } 96 97 /******************************************************************************* 98 * 99 * FUNCTION: acpi_ns_get_type 100 * 101 * PARAMETERS: node - Parent Node to be examined 102 * 103 * RETURN: Type field from Node whose handle is passed 104 * 105 * DESCRIPTION: Return the type of a Namespace node 106 * 107 ******************************************************************************/ 108 109 acpi_object_type acpi_ns_get_type(struct acpi_namespace_node * node) 110 { 111 ACPI_FUNCTION_TRACE(ns_get_type); 112 113 if (!node) { 114 ACPI_WARNING((AE_INFO, "Null Node parameter")); 115 return_UINT8(ACPI_TYPE_ANY); 116 } 117 118 return_UINT8(node->type); 119 } 120 121 /******************************************************************************* 122 * 123 * FUNCTION: acpi_ns_local 124 * 125 * PARAMETERS: type - A namespace object type 126 * 127 * RETURN: LOCAL if names must be found locally in objects of the 128 * passed type, 0 if enclosing scopes should be searched 129 * 130 * DESCRIPTION: Returns scope rule for the given object type. 131 * 132 ******************************************************************************/ 133 134 u32 acpi_ns_local(acpi_object_type type) 135 { 136 ACPI_FUNCTION_TRACE(ns_local); 137 138 if (!acpi_ut_valid_object_type(type)) { 139 140 /* Type code out of range */ 141 142 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type)); 143 return_UINT32(ACPI_NS_NORMAL); 144 } 145 146 return_UINT32(acpi_gbl_ns_properties[type] & ACPI_NS_LOCAL); 147 } 148 149 /******************************************************************************* 150 * 151 * FUNCTION: acpi_ns_get_internal_name_length 152 * 153 * PARAMETERS: info - Info struct initialized with the 154 * external name pointer. 155 * 156 * RETURN: None 157 * 158 * DESCRIPTION: Calculate the length of the internal (AML) namestring 159 * corresponding to the external (ASL) namestring. 160 * 161 ******************************************************************************/ 162 163 void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info) 164 { 165 const char *next_external_char; 166 u32 i; 167 168 ACPI_FUNCTION_ENTRY(); 169 170 next_external_char = info->external_name; 171 info->num_carats = 0; 172 info->num_segments = 0; 173 info->fully_qualified = FALSE; 174 175 /* 176 * For the internal name, the required length is 4 bytes per segment, 177 * plus 1 each for root_prefix, multi_name_prefix_op, segment count, 178 * trailing null (which is not really needed, but no there's harm in 179 * putting it there) 180 * 181 * strlen() + 1 covers the first name_seg, which has no path separator 182 */ 183 if (ACPI_IS_ROOT_PREFIX(*next_external_char)) { 184 info->fully_qualified = TRUE; 185 next_external_char++; 186 187 /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ 188 189 while (ACPI_IS_ROOT_PREFIX(*next_external_char)) { 190 next_external_char++; 191 } 192 } else { 193 /* Handle Carat prefixes */ 194 195 while (ACPI_IS_PARENT_PREFIX(*next_external_char)) { 196 info->num_carats++; 197 next_external_char++; 198 } 199 } 200 201 /* 202 * Determine the number of ACPI name "segments" by counting the number of 203 * path separators within the string. Start with one segment since the 204 * segment count is [(# separators) + 1], and zero separators is ok. 205 */ 206 if (*next_external_char) { 207 info->num_segments = 1; 208 for (i = 0; next_external_char[i]; i++) { 209 if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) { 210 info->num_segments++; 211 } 212 } 213 } 214 215 info->length = (ACPI_NAME_SIZE * info->num_segments) + 216 4 + info->num_carats; 217 218 info->next_external_char = next_external_char; 219 } 220 221 /******************************************************************************* 222 * 223 * FUNCTION: acpi_ns_build_internal_name 224 * 225 * PARAMETERS: info - Info struct fully initialized 226 * 227 * RETURN: Status 228 * 229 * DESCRIPTION: Construct the internal (AML) namestring 230 * corresponding to the external (ASL) namestring. 231 * 232 ******************************************************************************/ 233 234 acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) 235 { 236 u32 num_segments = info->num_segments; 237 char *internal_name = info->internal_name; 238 const char *external_name = info->next_external_char; 239 char *result = NULL; 240 u32 i; 241 242 ACPI_FUNCTION_TRACE(ns_build_internal_name); 243 244 /* Setup the correct prefixes, counts, and pointers */ 245 246 if (info->fully_qualified) { 247 internal_name[0] = AML_ROOT_PREFIX; 248 249 if (num_segments <= 1) { 250 result = &internal_name[1]; 251 } else if (num_segments == 2) { 252 internal_name[1] = AML_DUAL_NAME_PREFIX; 253 result = &internal_name[2]; 254 } else { 255 internal_name[1] = AML_MULTI_NAME_PREFIX; 256 internal_name[2] = (char)num_segments; 257 result = &internal_name[3]; 258 } 259 } else { 260 /* 261 * Not fully qualified. 262 * Handle Carats first, then append the name segments 263 */ 264 i = 0; 265 if (info->num_carats) { 266 for (i = 0; i < info->num_carats; i++) { 267 internal_name[i] = AML_PARENT_PREFIX; 268 } 269 } 270 271 if (num_segments <= 1) { 272 result = &internal_name[i]; 273 } else if (num_segments == 2) { 274 internal_name[i] = AML_DUAL_NAME_PREFIX; 275 result = &internal_name[(acpi_size)i + 1]; 276 } else { 277 internal_name[i] = AML_MULTI_NAME_PREFIX; 278 internal_name[(acpi_size)i + 1] = (char)num_segments; 279 result = &internal_name[(acpi_size)i + 2]; 280 } 281 } 282 283 /* Build the name (minus path separators) */ 284 285 for (; num_segments; num_segments--) { 286 for (i = 0; i < ACPI_NAME_SIZE; i++) { 287 if (ACPI_IS_PATH_SEPARATOR(*external_name) || 288 (*external_name == 0)) { 289 290 /* Pad the segment with underscore(s) if segment is short */ 291 292 result[i] = '_'; 293 } else { 294 /* Convert the character to uppercase and save it */ 295 296 result[i] = (char)toupper((int)*external_name); 297 external_name++; 298 } 299 } 300 301 /* Now we must have a path separator, or the pathname is bad */ 302 303 if (!ACPI_IS_PATH_SEPARATOR(*external_name) && 304 (*external_name != 0)) { 305 return_ACPI_STATUS(AE_BAD_PATHNAME); 306 } 307 308 /* Move on the next segment */ 309 310 external_name++; 311 result += ACPI_NAME_SIZE; 312 } 313 314 /* Terminate the string */ 315 316 *result = 0; 317 318 if (info->fully_qualified) { 319 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 320 "Returning [%p] (abs) \"\\%s\"\n", 321 internal_name, internal_name)); 322 } else { 323 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 324 internal_name, internal_name)); 325 } 326 327 return_ACPI_STATUS(AE_OK); 328 } 329 330 /******************************************************************************* 331 * 332 * FUNCTION: acpi_ns_internalize_name 333 * 334 * PARAMETERS: *external_name - External representation of name 335 * **Converted name - Where to return the resulting 336 * internal represention of the name 337 * 338 * RETURN: Status 339 * 340 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 341 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 342 * 343 *******************************************************************************/ 344 345 acpi_status 346 acpi_ns_internalize_name(const char *external_name, char **converted_name) 347 { 348 char *internal_name; 349 struct acpi_namestring_info info; 350 acpi_status status; 351 352 ACPI_FUNCTION_TRACE(ns_internalize_name); 353 354 if ((!external_name) || (*external_name == 0) || (!converted_name)) { 355 return_ACPI_STATUS(AE_BAD_PARAMETER); 356 } 357 358 /* Get the length of the new internal name */ 359 360 info.external_name = external_name; 361 acpi_ns_get_internal_name_length(&info); 362 363 /* We need a segment to store the internal name */ 364 365 internal_name = ACPI_ALLOCATE_ZEROED(info.length); 366 if (!internal_name) { 367 return_ACPI_STATUS(AE_NO_MEMORY); 368 } 369 370 /* Build the name */ 371 372 info.internal_name = internal_name; 373 status = acpi_ns_build_internal_name(&info); 374 if (ACPI_FAILURE(status)) { 375 ACPI_FREE(internal_name); 376 return_ACPI_STATUS(status); 377 } 378 379 *converted_name = internal_name; 380 return_ACPI_STATUS(AE_OK); 381 } 382 383 /******************************************************************************* 384 * 385 * FUNCTION: acpi_ns_externalize_name 386 * 387 * PARAMETERS: internal_name_length - Lenth of the internal name below 388 * internal_name - Internal representation of name 389 * converted_name_length - Where the length is returned 390 * converted_name - Where the resulting external name 391 * is returned 392 * 393 * RETURN: Status 394 * 395 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 396 * to its external (printable) form (e.g. "\_PR_.CPU0") 397 * 398 ******************************************************************************/ 399 400 acpi_status 401 acpi_ns_externalize_name(u32 internal_name_length, 402 const char *internal_name, 403 u32 * converted_name_length, char **converted_name) 404 { 405 u32 names_index = 0; 406 u32 num_segments = 0; 407 u32 required_length; 408 u32 prefix_length = 0; 409 u32 i = 0; 410 u32 j = 0; 411 412 ACPI_FUNCTION_TRACE(ns_externalize_name); 413 414 if (!internal_name_length || !internal_name || !converted_name) { 415 return_ACPI_STATUS(AE_BAD_PARAMETER); 416 } 417 418 /* Check for a prefix (one '\' | one or more '^') */ 419 420 switch (internal_name[0]) { 421 case AML_ROOT_PREFIX: 422 423 prefix_length = 1; 424 break; 425 426 case AML_PARENT_PREFIX: 427 428 for (i = 0; i < internal_name_length; i++) { 429 if (ACPI_IS_PARENT_PREFIX(internal_name[i])) { 430 prefix_length = i + 1; 431 } else { 432 break; 433 } 434 } 435 436 if (i == internal_name_length) { 437 prefix_length = i; 438 } 439 440 break; 441 442 default: 443 444 break; 445 } 446 447 /* 448 * Check for object names. Note that there could be 0-255 of these 449 * 4-byte elements. 450 */ 451 if (prefix_length < internal_name_length) { 452 switch (internal_name[prefix_length]) { 453 case AML_MULTI_NAME_PREFIX: 454 455 /* <count> 4-byte names */ 456 457 names_index = prefix_length + 2; 458 num_segments = (u8) 459 internal_name[(acpi_size)prefix_length + 1]; 460 break; 461 462 case AML_DUAL_NAME_PREFIX: 463 464 /* Two 4-byte names */ 465 466 names_index = prefix_length + 1; 467 num_segments = 2; 468 break; 469 470 case 0: 471 472 /* null_name */ 473 474 names_index = 0; 475 num_segments = 0; 476 break; 477 478 default: 479 480 /* one 4-byte name */ 481 482 names_index = prefix_length; 483 num_segments = 1; 484 break; 485 } 486 } 487 488 /* 489 * Calculate the length of converted_name, which equals the length 490 * of the prefix, length of all object names, length of any required 491 * punctuation ('.') between object names, plus the NULL terminator. 492 */ 493 required_length = prefix_length + (4 * num_segments) + 494 ((num_segments > 0) ? (num_segments - 1) : 0) + 1; 495 496 /* 497 * Check to see if we're still in bounds. If not, there's a problem 498 * with internal_name (invalid format). 499 */ 500 if (required_length > internal_name_length) { 501 ACPI_ERROR((AE_INFO, "Invalid internal name")); 502 return_ACPI_STATUS(AE_BAD_PATHNAME); 503 } 504 505 /* Build the converted_name */ 506 507 *converted_name = ACPI_ALLOCATE_ZEROED(required_length); 508 if (!(*converted_name)) { 509 return_ACPI_STATUS(AE_NO_MEMORY); 510 } 511 512 j = 0; 513 514 for (i = 0; i < prefix_length; i++) { 515 (*converted_name)[j++] = internal_name[i]; 516 } 517 518 if (num_segments > 0) { 519 for (i = 0; i < num_segments; i++) { 520 if (i > 0) { 521 (*converted_name)[j++] = '.'; 522 } 523 524 /* Copy and validate the 4-char name segment */ 525 526 ACPI_MOVE_NAME(&(*converted_name)[j], 527 &internal_name[names_index]); 528 acpi_ut_repair_name(&(*converted_name)[j]); 529 530 j += ACPI_NAME_SIZE; 531 names_index += ACPI_NAME_SIZE; 532 } 533 } 534 535 if (converted_name_length) { 536 *converted_name_length = (u32) required_length; 537 } 538 539 return_ACPI_STATUS(AE_OK); 540 } 541 542 /******************************************************************************* 543 * 544 * FUNCTION: acpi_ns_validate_handle 545 * 546 * PARAMETERS: handle - Handle to be validated and typecast to a 547 * namespace node. 548 * 549 * RETURN: A pointer to a namespace node 550 * 551 * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 552 * cases for the root node. 553 * 554 * NOTE: Real integer handles would allow for more verification 555 * and keep all pointers within this subsystem - however this introduces 556 * more overhead and has not been necessary to this point. Drivers 557 * holding handles are typically notified before a node becomes invalid 558 * due to a table unload. 559 * 560 ******************************************************************************/ 561 562 struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle) 563 { 564 565 ACPI_FUNCTION_ENTRY(); 566 567 /* Parameter validation */ 568 569 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { 570 return (acpi_gbl_root_node); 571 } 572 573 /* We can at least attempt to verify the handle */ 574 575 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) { 576 return (NULL); 577 } 578 579 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); 580 } 581 582 /******************************************************************************* 583 * 584 * FUNCTION: acpi_ns_terminate 585 * 586 * PARAMETERS: none 587 * 588 * RETURN: none 589 * 590 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 591 * 592 ******************************************************************************/ 593 594 void acpi_ns_terminate(void) 595 { 596 acpi_status status; 597 union acpi_operand_object *prev; 598 union acpi_operand_object *next; 599 600 ACPI_FUNCTION_TRACE(ns_terminate); 601 602 /* Delete any module-level code blocks */ 603 604 next = acpi_gbl_module_code_list; 605 while (next) { 606 prev = next; 607 next = next->method.mutex; 608 prev->method.mutex = NULL; /* Clear the Mutex (cheated) field */ 609 acpi_ut_remove_reference(prev); 610 } 611 612 /* 613 * Free the entire namespace -- all nodes and all objects 614 * attached to the nodes 615 */ 616 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node); 617 618 /* Delete any objects attached to the root node */ 619 620 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 621 if (ACPI_FAILURE(status)) { 622 return_VOID; 623 } 624 625 acpi_ns_delete_node(acpi_gbl_root_node); 626 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 627 628 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); 629 return_VOID; 630 } 631 632 /******************************************************************************* 633 * 634 * FUNCTION: acpi_ns_opens_scope 635 * 636 * PARAMETERS: type - A valid namespace type 637 * 638 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 639 * to the ACPI specification, else 0 640 * 641 ******************************************************************************/ 642 643 u32 acpi_ns_opens_scope(acpi_object_type type) 644 { 645 ACPI_FUNCTION_ENTRY(); 646 647 if (type > ACPI_TYPE_LOCAL_MAX) { 648 649 /* type code out of range */ 650 651 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type)); 652 return (ACPI_NS_NORMAL); 653 } 654 655 return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); 656 } 657 658 /******************************************************************************* 659 * 660 * FUNCTION: acpi_ns_get_node_unlocked 661 * 662 * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The 663 * \ (backslash) and ^ (carat) prefixes, and the 664 * . (period) to separate segments are supported. 665 * prefix_node - Root of subtree to be searched, or NS_ALL for the 666 * root of the name space. If Name is fully 667 * qualified (first s8 is '\'), the passed value 668 * of Scope will not be accessed. 669 * flags - Used to indicate whether to perform upsearch or 670 * not. 671 * return_node - Where the Node is returned 672 * 673 * DESCRIPTION: Look up a name relative to a given scope and return the 674 * corresponding Node. NOTE: Scope can be null. 675 * 676 * MUTEX: Doesn't locks namespace 677 * 678 ******************************************************************************/ 679 680 acpi_status 681 acpi_ns_get_node_unlocked(struct acpi_namespace_node *prefix_node, 682 const char *pathname, 683 u32 flags, struct acpi_namespace_node **return_node) 684 { 685 union acpi_generic_state scope_info; 686 acpi_status status; 687 char *internal_path; 688 689 ACPI_FUNCTION_TRACE_PTR(ns_get_node_unlocked, 690 ACPI_CAST_PTR(char, pathname)); 691 692 /* Simplest case is a null pathname */ 693 694 if (!pathname) { 695 *return_node = prefix_node; 696 if (!prefix_node) { 697 *return_node = acpi_gbl_root_node; 698 } 699 700 return_ACPI_STATUS(AE_OK); 701 } 702 703 /* Quick check for a reference to the root */ 704 705 if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) { 706 *return_node = acpi_gbl_root_node; 707 return_ACPI_STATUS(AE_OK); 708 } 709 710 /* Convert path to internal representation */ 711 712 status = acpi_ns_internalize_name(pathname, &internal_path); 713 if (ACPI_FAILURE(status)) { 714 return_ACPI_STATUS(status); 715 } 716 717 /* Setup lookup scope (search starting point) */ 718 719 scope_info.scope.node = prefix_node; 720 721 /* Lookup the name in the namespace */ 722 723 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, 724 ACPI_IMODE_EXECUTE, 725 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, 726 return_node); 727 if (ACPI_FAILURE(status)) { 728 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n", 729 pathname, acpi_format_exception(status))); 730 } 731 732 ACPI_FREE(internal_path); 733 return_ACPI_STATUS(status); 734 } 735 736 /******************************************************************************* 737 * 738 * FUNCTION: acpi_ns_get_node 739 * 740 * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The 741 * \ (backslash) and ^ (carat) prefixes, and the 742 * . (period) to separate segments are supported. 743 * prefix_node - Root of subtree to be searched, or NS_ALL for the 744 * root of the name space. If Name is fully 745 * qualified (first s8 is '\'), the passed value 746 * of Scope will not be accessed. 747 * flags - Used to indicate whether to perform upsearch or 748 * not. 749 * return_node - 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 758 acpi_status 759 acpi_ns_get_node(struct acpi_namespace_node *prefix_node, 760 const char *pathname, 761 u32 flags, struct acpi_namespace_node **return_node) 762 { 763 acpi_status status; 764 765 ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); 766 767 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 768 if (ACPI_FAILURE(status)) { 769 return_ACPI_STATUS(status); 770 } 771 772 status = acpi_ns_get_node_unlocked(prefix_node, pathname, 773 flags, return_node); 774 775 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 776 return_ACPI_STATUS(status); 777 } 778