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 - 2015, 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); 87 if (ACPI_SUCCESS(status)) { 88 if (message) { 89 acpi_os_printf("%s ", message); 90 } 91 92 acpi_os_printf("[%s] (Node %p)", (char *)buffer.pointer, node); 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, plus 177 * 1 each for root_prefix, multi_name_prefix_op, segment count, trailing null 178 * (which is not really needed, but no there's harm in putting it there) 179 * 180 * strlen() + 1 covers the first name_seg, which has no path separator 181 */ 182 if (ACPI_IS_ROOT_PREFIX(*next_external_char)) { 183 info->fully_qualified = TRUE; 184 next_external_char++; 185 186 /* Skip redundant root_prefix, like \\_SB.PCI0.SBRG.EC0 */ 187 188 while (ACPI_IS_ROOT_PREFIX(*next_external_char)) { 189 next_external_char++; 190 } 191 } else { 192 /* Handle Carat prefixes */ 193 194 while (ACPI_IS_PARENT_PREFIX(*next_external_char)) { 195 info->num_carats++; 196 next_external_char++; 197 } 198 } 199 200 /* 201 * Determine the number of ACPI name "segments" by counting the number of 202 * path separators within the string. Start with one segment since the 203 * segment count is [(# separators) + 1], and zero separators is ok. 204 */ 205 if (*next_external_char) { 206 info->num_segments = 1; 207 for (i = 0; next_external_char[i]; i++) { 208 if (ACPI_IS_PATH_SEPARATOR(next_external_char[i])) { 209 info->num_segments++; 210 } 211 } 212 } 213 214 info->length = (ACPI_NAME_SIZE * info->num_segments) + 215 4 + info->num_carats; 216 217 info->next_external_char = next_external_char; 218 } 219 220 /******************************************************************************* 221 * 222 * FUNCTION: acpi_ns_build_internal_name 223 * 224 * PARAMETERS: info - Info struct fully initialized 225 * 226 * RETURN: Status 227 * 228 * DESCRIPTION: Construct the internal (AML) namestring 229 * corresponding to the external (ASL) namestring. 230 * 231 ******************************************************************************/ 232 233 acpi_status acpi_ns_build_internal_name(struct acpi_namestring_info *info) 234 { 235 u32 num_segments = info->num_segments; 236 char *internal_name = info->internal_name; 237 const char *external_name = info->next_external_char; 238 char *result = NULL; 239 u32 i; 240 241 ACPI_FUNCTION_TRACE(ns_build_internal_name); 242 243 /* Setup the correct prefixes, counts, and pointers */ 244 245 if (info->fully_qualified) { 246 internal_name[0] = AML_ROOT_PREFIX; 247 248 if (num_segments <= 1) { 249 result = &internal_name[1]; 250 } else if (num_segments == 2) { 251 internal_name[1] = AML_DUAL_NAME_PREFIX; 252 result = &internal_name[2]; 253 } else { 254 internal_name[1] = AML_MULTI_NAME_PREFIX_OP; 255 internal_name[2] = (char)num_segments; 256 result = &internal_name[3]; 257 } 258 } else { 259 /* 260 * Not fully qualified. 261 * Handle Carats first, then append the name segments 262 */ 263 i = 0; 264 if (info->num_carats) { 265 for (i = 0; i < info->num_carats; i++) { 266 internal_name[i] = AML_PARENT_PREFIX; 267 } 268 } 269 270 if (num_segments <= 1) { 271 result = &internal_name[i]; 272 } else if (num_segments == 2) { 273 internal_name[i] = AML_DUAL_NAME_PREFIX; 274 result = &internal_name[(acpi_size) i + 1]; 275 } else { 276 internal_name[i] = AML_MULTI_NAME_PREFIX_OP; 277 internal_name[(acpi_size) i + 1] = (char)num_segments; 278 result = &internal_name[(acpi_size) i + 2]; 279 } 280 } 281 282 /* Build the name (minus path separators) */ 283 284 for (; num_segments; num_segments--) { 285 for (i = 0; i < ACPI_NAME_SIZE; i++) { 286 if (ACPI_IS_PATH_SEPARATOR(*external_name) || 287 (*external_name == 0)) { 288 289 /* Pad the segment with underscore(s) if segment is short */ 290 291 result[i] = '_'; 292 } else { 293 /* Convert the character to uppercase and save it */ 294 295 result[i] = (char)toupper((int)*external_name); 296 external_name++; 297 } 298 } 299 300 /* Now we must have a path separator, or the pathname is bad */ 301 302 if (!ACPI_IS_PATH_SEPARATOR(*external_name) && 303 (*external_name != 0)) { 304 return_ACPI_STATUS(AE_BAD_PATHNAME); 305 } 306 307 /* Move on the next segment */ 308 309 external_name++; 310 result += ACPI_NAME_SIZE; 311 } 312 313 /* Terminate the string */ 314 315 *result = 0; 316 317 if (info->fully_qualified) { 318 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 319 "Returning [%p] (abs) \"\\%s\"\n", 320 internal_name, internal_name)); 321 } else { 322 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Returning [%p] (rel) \"%s\"\n", 323 internal_name, internal_name)); 324 } 325 326 return_ACPI_STATUS(AE_OK); 327 } 328 329 /******************************************************************************* 330 * 331 * FUNCTION: acpi_ns_internalize_name 332 * 333 * PARAMETERS: *external_name - External representation of name 334 * **Converted name - Where to return the resulting 335 * internal represention of the name 336 * 337 * RETURN: Status 338 * 339 * DESCRIPTION: Convert an external representation (e.g. "\_PR_.CPU0") 340 * to internal form (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 341 * 342 *******************************************************************************/ 343 344 acpi_status 345 acpi_ns_internalize_name(const char *external_name, char **converted_name) 346 { 347 char *internal_name; 348 struct acpi_namestring_info info; 349 acpi_status status; 350 351 ACPI_FUNCTION_TRACE(ns_internalize_name); 352 353 if ((!external_name) || (*external_name == 0) || (!converted_name)) { 354 return_ACPI_STATUS(AE_BAD_PARAMETER); 355 } 356 357 /* Get the length of the new internal name */ 358 359 info.external_name = external_name; 360 acpi_ns_get_internal_name_length(&info); 361 362 /* We need a segment to store the internal name */ 363 364 internal_name = ACPI_ALLOCATE_ZEROED(info.length); 365 if (!internal_name) { 366 return_ACPI_STATUS(AE_NO_MEMORY); 367 } 368 369 /* Build the name */ 370 371 info.internal_name = internal_name; 372 status = acpi_ns_build_internal_name(&info); 373 if (ACPI_FAILURE(status)) { 374 ACPI_FREE(internal_name); 375 return_ACPI_STATUS(status); 376 } 377 378 *converted_name = internal_name; 379 return_ACPI_STATUS(AE_OK); 380 } 381 382 /******************************************************************************* 383 * 384 * FUNCTION: acpi_ns_externalize_name 385 * 386 * PARAMETERS: internal_name_length - Lenth of the internal name below 387 * internal_name - Internal representation of name 388 * converted_name_length - Where the length is returned 389 * converted_name - Where the resulting external name 390 * is returned 391 * 392 * RETURN: Status 393 * 394 * DESCRIPTION: Convert internal name (e.g. 5c 2f 02 5f 50 52 5f 43 50 55 30) 395 * to its external (printable) form (e.g. "\_PR_.CPU0") 396 * 397 ******************************************************************************/ 398 399 acpi_status 400 acpi_ns_externalize_name(u32 internal_name_length, 401 const char *internal_name, 402 u32 * converted_name_length, char **converted_name) 403 { 404 u32 names_index = 0; 405 u32 num_segments = 0; 406 u32 required_length; 407 u32 prefix_length = 0; 408 u32 i = 0; 409 u32 j = 0; 410 411 ACPI_FUNCTION_TRACE(ns_externalize_name); 412 413 if (!internal_name_length || !internal_name || !converted_name) { 414 return_ACPI_STATUS(AE_BAD_PARAMETER); 415 } 416 417 /* Check for a prefix (one '\' | one or more '^') */ 418 419 switch (internal_name[0]) { 420 case AML_ROOT_PREFIX: 421 422 prefix_length = 1; 423 break; 424 425 case AML_PARENT_PREFIX: 426 427 for (i = 0; i < internal_name_length; i++) { 428 if (ACPI_IS_PARENT_PREFIX(internal_name[i])) { 429 prefix_length = i + 1; 430 } else { 431 break; 432 } 433 } 434 435 if (i == internal_name_length) { 436 prefix_length = i; 437 } 438 439 break; 440 441 default: 442 443 break; 444 } 445 446 /* 447 * Check for object names. Note that there could be 0-255 of these 448 * 4-byte elements. 449 */ 450 if (prefix_length < internal_name_length) { 451 switch (internal_name[prefix_length]) { 452 case AML_MULTI_NAME_PREFIX_OP: 453 454 /* <count> 4-byte names */ 455 456 names_index = prefix_length + 2; 457 num_segments = (u8) 458 internal_name[(acpi_size) prefix_length + 1]; 459 break; 460 461 case AML_DUAL_NAME_PREFIX: 462 463 /* Two 4-byte names */ 464 465 names_index = prefix_length + 1; 466 num_segments = 2; 467 break; 468 469 case 0: 470 471 /* null_name */ 472 473 names_index = 0; 474 num_segments = 0; 475 break; 476 477 default: 478 479 /* one 4-byte name */ 480 481 names_index = prefix_length; 482 num_segments = 1; 483 break; 484 } 485 } 486 487 /* 488 * Calculate the length of converted_name, which equals the length 489 * of the prefix, length of all object names, length of any required 490 * punctuation ('.') between object names, plus the NULL terminator. 491 */ 492 required_length = prefix_length + (4 * num_segments) + 493 ((num_segments > 0) ? (num_segments - 1) : 0) + 1; 494 495 /* 496 * Check to see if we're still in bounds. If not, there's a problem 497 * with internal_name (invalid format). 498 */ 499 if (required_length > internal_name_length) { 500 ACPI_ERROR((AE_INFO, "Invalid internal name")); 501 return_ACPI_STATUS(AE_BAD_PATHNAME); 502 } 503 504 /* Build the converted_name */ 505 506 *converted_name = ACPI_ALLOCATE_ZEROED(required_length); 507 if (!(*converted_name)) { 508 return_ACPI_STATUS(AE_NO_MEMORY); 509 } 510 511 j = 0; 512 513 for (i = 0; i < prefix_length; i++) { 514 (*converted_name)[j++] = internal_name[i]; 515 } 516 517 if (num_segments > 0) { 518 for (i = 0; i < num_segments; i++) { 519 if (i > 0) { 520 (*converted_name)[j++] = '.'; 521 } 522 523 /* Copy and validate the 4-char name segment */ 524 525 ACPI_MOVE_NAME(&(*converted_name)[j], 526 &internal_name[names_index]); 527 acpi_ut_repair_name(&(*converted_name)[j]); 528 529 j += ACPI_NAME_SIZE; 530 names_index += ACPI_NAME_SIZE; 531 } 532 } 533 534 if (converted_name_length) { 535 *converted_name_length = (u32) required_length; 536 } 537 538 return_ACPI_STATUS(AE_OK); 539 } 540 541 /******************************************************************************* 542 * 543 * FUNCTION: acpi_ns_validate_handle 544 * 545 * PARAMETERS: handle - Handle to be validated and typecast to a 546 * namespace node. 547 * 548 * RETURN: A pointer to a namespace node 549 * 550 * DESCRIPTION: Convert a namespace handle to a namespace node. Handles special 551 * cases for the root node. 552 * 553 * NOTE: Real integer handles would allow for more verification 554 * and keep all pointers within this subsystem - however this introduces 555 * more overhead and has not been necessary to this point. Drivers 556 * holding handles are typically notified before a node becomes invalid 557 * due to a table unload. 558 * 559 ******************************************************************************/ 560 561 struct acpi_namespace_node *acpi_ns_validate_handle(acpi_handle handle) 562 { 563 564 ACPI_FUNCTION_ENTRY(); 565 566 /* Parameter validation */ 567 568 if ((!handle) || (handle == ACPI_ROOT_OBJECT)) { 569 return (acpi_gbl_root_node); 570 } 571 572 /* We can at least attempt to verify the handle */ 573 574 if (ACPI_GET_DESCRIPTOR_TYPE(handle) != ACPI_DESC_TYPE_NAMED) { 575 return (NULL); 576 } 577 578 return (ACPI_CAST_PTR(struct acpi_namespace_node, handle)); 579 } 580 581 /******************************************************************************* 582 * 583 * FUNCTION: acpi_ns_terminate 584 * 585 * PARAMETERS: none 586 * 587 * RETURN: none 588 * 589 * DESCRIPTION: free memory allocated for namespace and ACPI table storage. 590 * 591 ******************************************************************************/ 592 593 void acpi_ns_terminate(void) 594 { 595 acpi_status status; 596 597 ACPI_FUNCTION_TRACE(ns_terminate); 598 599 /* 600 * Free the entire namespace -- all nodes and all objects 601 * attached to the nodes 602 */ 603 acpi_ns_delete_namespace_subtree(acpi_gbl_root_node); 604 605 /* Delete any objects attached to the root node */ 606 607 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 608 if (ACPI_FAILURE(status)) { 609 return_VOID; 610 } 611 612 acpi_ns_delete_node(acpi_gbl_root_node); 613 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 614 615 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Namespace freed\n")); 616 return_VOID; 617 } 618 619 /******************************************************************************* 620 * 621 * FUNCTION: acpi_ns_opens_scope 622 * 623 * PARAMETERS: type - A valid namespace type 624 * 625 * RETURN: NEWSCOPE if the passed type "opens a name scope" according 626 * to the ACPI specification, else 0 627 * 628 ******************************************************************************/ 629 630 u32 acpi_ns_opens_scope(acpi_object_type type) 631 { 632 ACPI_FUNCTION_ENTRY(); 633 634 if (type > ACPI_TYPE_LOCAL_MAX) { 635 636 /* type code out of range */ 637 638 ACPI_WARNING((AE_INFO, "Invalid Object Type 0x%X", type)); 639 return (ACPI_NS_NORMAL); 640 } 641 642 return (((u32)acpi_gbl_ns_properties[type]) & ACPI_NS_NEWSCOPE); 643 } 644 645 /******************************************************************************* 646 * 647 * FUNCTION: acpi_ns_get_node 648 * 649 * PARAMETERS: *pathname - Name to be found, in external (ASL) format. The 650 * \ (backslash) and ^ (carat) prefixes, and the 651 * . (period) to separate segments are supported. 652 * prefix_node - Root of subtree to be searched, or NS_ALL for the 653 * root of the name space. If Name is fully 654 * qualified (first s8 is '\'), the passed value 655 * of Scope will not be accessed. 656 * flags - Used to indicate whether to perform upsearch or 657 * not. 658 * return_node - Where the Node is returned 659 * 660 * DESCRIPTION: Look up a name relative to a given scope and return the 661 * corresponding Node. NOTE: Scope can be null. 662 * 663 * MUTEX: Locks namespace 664 * 665 ******************************************************************************/ 666 667 acpi_status 668 acpi_ns_get_node(struct acpi_namespace_node *prefix_node, 669 const char *pathname, 670 u32 flags, struct acpi_namespace_node **return_node) 671 { 672 union acpi_generic_state scope_info; 673 acpi_status status; 674 char *internal_path; 675 676 ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); 677 678 /* Simplest case is a null pathname */ 679 680 if (!pathname) { 681 *return_node = prefix_node; 682 if (!prefix_node) { 683 *return_node = acpi_gbl_root_node; 684 } 685 return_ACPI_STATUS(AE_OK); 686 } 687 688 /* Quick check for a reference to the root */ 689 690 if (ACPI_IS_ROOT_PREFIX(pathname[0]) && (!pathname[1])) { 691 *return_node = acpi_gbl_root_node; 692 return_ACPI_STATUS(AE_OK); 693 } 694 695 /* Convert path to internal representation */ 696 697 status = acpi_ns_internalize_name(pathname, &internal_path); 698 if (ACPI_FAILURE(status)) { 699 return_ACPI_STATUS(status); 700 } 701 702 /* Must lock namespace during lookup */ 703 704 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 705 if (ACPI_FAILURE(status)) { 706 goto cleanup; 707 } 708 709 /* Setup lookup scope (search starting point) */ 710 711 scope_info.scope.node = prefix_node; 712 713 /* Lookup the name in the namespace */ 714 715 status = acpi_ns_lookup(&scope_info, internal_path, ACPI_TYPE_ANY, 716 ACPI_IMODE_EXECUTE, 717 (flags | ACPI_NS_DONT_OPEN_SCOPE), NULL, 718 return_node); 719 if (ACPI_FAILURE(status)) { 720 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n", 721 pathname, acpi_format_exception(status))); 722 } 723 724 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 725 726 cleanup: 727 ACPI_FREE(internal_path); 728 return_ACPI_STATUS(status); 729 } 730