1 /****************************************************************************** 2 * 3 * Module Name: nsdump - table dumping routines for debug 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include <acpi/acoutput.h> 48 49 #define _COMPONENT ACPI_NAMESPACE 50 ACPI_MODULE_NAME("nsdump") 51 52 /* Local prototypes */ 53 #ifdef ACPI_OBSOLETE_FUNCTIONS 54 void acpi_ns_dump_root_devices(void); 55 56 static acpi_status 57 acpi_ns_dump_one_device(acpi_handle obj_handle, 58 u32 level, void *context, void **return_value); 59 #endif 60 61 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) 62 63 static acpi_status 64 acpi_ns_dump_one_object_path(acpi_handle obj_handle, 65 u32 level, void *context, void **return_value); 66 67 static acpi_status 68 acpi_ns_get_max_depth(acpi_handle obj_handle, 69 u32 level, void *context, void **return_value); 70 71 /******************************************************************************* 72 * 73 * FUNCTION: acpi_ns_print_pathname 74 * 75 * PARAMETERS: num_segments - Number of ACPI name segments 76 * pathname - The compressed (internal) path 77 * 78 * RETURN: None 79 * 80 * DESCRIPTION: Print an object's full namespace pathname 81 * 82 ******************************************************************************/ 83 84 void acpi_ns_print_pathname(u32 num_segments, const char *pathname) 85 { 86 u32 i; 87 88 ACPI_FUNCTION_NAME(ns_print_pathname); 89 90 /* Check if debug output enabled */ 91 92 if (!ACPI_IS_DEBUG_ENABLED(ACPI_LV_NAMES, ACPI_NAMESPACE)) { 93 return; 94 } 95 96 /* Print the entire name */ 97 98 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "[")); 99 100 while (num_segments) { 101 for (i = 0; i < 4; i++) { 102 isprint((int)pathname[i]) ? 103 acpi_os_printf("%c", pathname[i]) : 104 acpi_os_printf("?"); 105 } 106 107 pathname += ACPI_NAME_SIZE; 108 num_segments--; 109 if (num_segments) { 110 acpi_os_printf("."); 111 } 112 } 113 114 acpi_os_printf("]\n"); 115 } 116 117 #ifdef ACPI_OBSOLETE_FUNCTIONS 118 /* Not used at this time, perhaps later */ 119 120 /******************************************************************************* 121 * 122 * FUNCTION: acpi_ns_dump_pathname 123 * 124 * PARAMETERS: handle - Object 125 * msg - Prefix message 126 * level - Desired debug level 127 * component - Caller's component ID 128 * 129 * RETURN: None 130 * 131 * DESCRIPTION: Print an object's full namespace pathname 132 * Manages allocation/freeing of a pathname buffer 133 * 134 ******************************************************************************/ 135 136 void 137 acpi_ns_dump_pathname(acpi_handle handle, 138 const char *msg, u32 level, u32 component) 139 { 140 141 ACPI_FUNCTION_TRACE(ns_dump_pathname); 142 143 /* Do this only if the requested debug level and component are enabled */ 144 145 if (!ACPI_IS_DEBUG_ENABLED(level, component)) { 146 return_VOID; 147 } 148 149 /* Convert handle to a full pathname and print it (with supplied message) */ 150 151 acpi_ns_print_node_pathname(handle, msg); 152 acpi_os_printf("\n"); 153 return_VOID; 154 } 155 #endif 156 157 /******************************************************************************* 158 * 159 * FUNCTION: acpi_ns_dump_one_object 160 * 161 * PARAMETERS: obj_handle - Node to be dumped 162 * level - Nesting level of the handle 163 * context - Passed into walk_namespace 164 * return_value - Not used 165 * 166 * RETURN: Status 167 * 168 * DESCRIPTION: Dump a single Node 169 * This procedure is a user_function called by acpi_ns_walk_namespace. 170 * 171 ******************************************************************************/ 172 173 acpi_status 174 acpi_ns_dump_one_object(acpi_handle obj_handle, 175 u32 level, void *context, void **return_value) 176 { 177 struct acpi_walk_info *info = (struct acpi_walk_info *)context; 178 struct acpi_namespace_node *this_node; 179 union acpi_operand_object *obj_desc = NULL; 180 acpi_object_type obj_type; 181 acpi_object_type type; 182 u32 bytes_to_dump; 183 u32 dbg_level; 184 u32 i; 185 186 ACPI_FUNCTION_NAME(ns_dump_one_object); 187 188 /* Is output enabled? */ 189 190 if (!(acpi_dbg_level & info->debug_level)) { 191 return (AE_OK); 192 } 193 194 if (!obj_handle) { 195 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Null object handle\n")); 196 return (AE_OK); 197 } 198 199 this_node = acpi_ns_validate_handle(obj_handle); 200 if (!this_node) { 201 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n", 202 obj_handle)); 203 return (AE_OK); 204 } 205 206 type = this_node->type; 207 208 /* Check if the owner matches */ 209 210 if ((info->owner_id != ACPI_OWNER_ID_MAX) && 211 (info->owner_id != this_node->owner_id)) { 212 return (AE_OK); 213 } 214 215 if (!(info->display_type & ACPI_DISPLAY_SHORT)) { 216 217 /* Indent the object according to the level */ 218 219 acpi_os_printf("%2d%*s", (u32) level - 1, (int)level * 2, " "); 220 221 /* Check the node type and name */ 222 223 if (type > ACPI_TYPE_LOCAL_MAX) { 224 ACPI_WARNING((AE_INFO, 225 "Invalid ACPI Object Type 0x%08X", type)); 226 } 227 228 acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node)); 229 } 230 231 /* Now we can print out the pertinent information */ 232 233 acpi_os_printf(" %-12s %p %2.2X ", 234 acpi_ut_get_type_name(type), this_node, 235 this_node->owner_id); 236 237 dbg_level = acpi_dbg_level; 238 acpi_dbg_level = 0; 239 obj_desc = acpi_ns_get_attached_object(this_node); 240 acpi_dbg_level = dbg_level; 241 242 /* Temp nodes are those nodes created by a control method */ 243 244 if (this_node->flags & ANOBJ_TEMPORARY) { 245 acpi_os_printf("(T) "); 246 } 247 248 switch (info->display_type & ACPI_DISPLAY_MASK) { 249 case ACPI_DISPLAY_SUMMARY: 250 251 if (!obj_desc) { 252 253 /* No attached object. Some types should always have an object */ 254 255 switch (type) { 256 case ACPI_TYPE_INTEGER: 257 case ACPI_TYPE_PACKAGE: 258 case ACPI_TYPE_BUFFER: 259 case ACPI_TYPE_STRING: 260 case ACPI_TYPE_METHOD: 261 262 acpi_os_printf("<No attached object>"); 263 break; 264 265 default: 266 267 break; 268 } 269 270 acpi_os_printf("\n"); 271 return (AE_OK); 272 } 273 274 switch (type) { 275 case ACPI_TYPE_PROCESSOR: 276 277 acpi_os_printf("ID %02X Len %02X Addr %8.8X%8.8X\n", 278 obj_desc->processor.proc_id, 279 obj_desc->processor.length, 280 ACPI_FORMAT_UINT64(obj_desc->processor. 281 address)); 282 break; 283 284 case ACPI_TYPE_DEVICE: 285 286 acpi_os_printf("Notify Object: %p\n", obj_desc); 287 break; 288 289 case ACPI_TYPE_METHOD: 290 291 acpi_os_printf("Args %X Len %.4X Aml %p\n", 292 (u32) obj_desc->method.param_count, 293 obj_desc->method.aml_length, 294 obj_desc->method.aml_start); 295 break; 296 297 case ACPI_TYPE_INTEGER: 298 299 acpi_os_printf("= %8.8X%8.8X\n", 300 ACPI_FORMAT_UINT64(obj_desc->integer. 301 value)); 302 break; 303 304 case ACPI_TYPE_PACKAGE: 305 306 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 307 acpi_os_printf("Elements %.2X\n", 308 obj_desc->package.count); 309 } else { 310 acpi_os_printf("[Length not yet evaluated]\n"); 311 } 312 break; 313 314 case ACPI_TYPE_BUFFER: 315 316 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 317 acpi_os_printf("Len %.2X", 318 obj_desc->buffer.length); 319 320 /* Dump some of the buffer */ 321 322 if (obj_desc->buffer.length > 0) { 323 acpi_os_printf(" ="); 324 for (i = 0; 325 (i < obj_desc->buffer.length 326 && i < 12); i++) { 327 acpi_os_printf(" %.2hX", 328 obj_desc->buffer. 329 pointer[i]); 330 } 331 } 332 acpi_os_printf("\n"); 333 } else { 334 acpi_os_printf("[Length not yet evaluated]\n"); 335 } 336 break; 337 338 case ACPI_TYPE_STRING: 339 340 acpi_os_printf("Len %.2X ", obj_desc->string.length); 341 acpi_ut_print_string(obj_desc->string.pointer, 32); 342 acpi_os_printf("\n"); 343 break; 344 345 case ACPI_TYPE_REGION: 346 347 acpi_os_printf("[%s]", 348 acpi_ut_get_region_name(obj_desc->region. 349 space_id)); 350 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 351 acpi_os_printf(" Addr %8.8X%8.8X Len %.4X\n", 352 ACPI_FORMAT_UINT64(obj_desc-> 353 region. 354 address), 355 obj_desc->region.length); 356 } else { 357 acpi_os_printf 358 (" [Address/Length not yet evaluated]\n"); 359 } 360 break; 361 362 case ACPI_TYPE_LOCAL_REFERENCE: 363 364 acpi_os_printf("[%s]\n", 365 acpi_ut_get_reference_name(obj_desc)); 366 break; 367 368 case ACPI_TYPE_BUFFER_FIELD: 369 370 if (obj_desc->buffer_field.buffer_obj && 371 obj_desc->buffer_field.buffer_obj->buffer.node) { 372 acpi_os_printf("Buf [%4.4s]", 373 acpi_ut_get_node_name(obj_desc-> 374 buffer_field. 375 buffer_obj-> 376 buffer. 377 node)); 378 } 379 break; 380 381 case ACPI_TYPE_LOCAL_REGION_FIELD: 382 383 acpi_os_printf("Rgn [%4.4s]", 384 acpi_ut_get_node_name(obj_desc-> 385 common_field. 386 region_obj->region. 387 node)); 388 break; 389 390 case ACPI_TYPE_LOCAL_BANK_FIELD: 391 392 acpi_os_printf("Rgn [%4.4s] Bnk [%4.4s]", 393 acpi_ut_get_node_name(obj_desc-> 394 common_field. 395 region_obj->region. 396 node), 397 acpi_ut_get_node_name(obj_desc-> 398 bank_field. 399 bank_obj-> 400 common_field. 401 node)); 402 break; 403 404 case ACPI_TYPE_LOCAL_INDEX_FIELD: 405 406 acpi_os_printf("Idx [%4.4s] Dat [%4.4s]", 407 acpi_ut_get_node_name(obj_desc-> 408 index_field. 409 index_obj-> 410 common_field.node), 411 acpi_ut_get_node_name(obj_desc-> 412 index_field. 413 data_obj-> 414 common_field. 415 node)); 416 break; 417 418 case ACPI_TYPE_LOCAL_ALIAS: 419 case ACPI_TYPE_LOCAL_METHOD_ALIAS: 420 421 acpi_os_printf("Target %4.4s (%p)\n", 422 acpi_ut_get_node_name(obj_desc), 423 obj_desc); 424 break; 425 426 default: 427 428 acpi_os_printf("Object %p\n", obj_desc); 429 break; 430 } 431 432 /* Common field handling */ 433 434 switch (type) { 435 case ACPI_TYPE_BUFFER_FIELD: 436 case ACPI_TYPE_LOCAL_REGION_FIELD: 437 case ACPI_TYPE_LOCAL_BANK_FIELD: 438 case ACPI_TYPE_LOCAL_INDEX_FIELD: 439 440 acpi_os_printf(" Off %.3X Len %.2X Acc %.2hd\n", 441 (obj_desc->common_field. 442 base_byte_offset * 8) 443 + 444 obj_desc->common_field. 445 start_field_bit_offset, 446 obj_desc->common_field.bit_length, 447 obj_desc->common_field. 448 access_byte_width); 449 break; 450 451 default: 452 453 break; 454 } 455 break; 456 457 case ACPI_DISPLAY_OBJECTS: 458 459 acpi_os_printf("O:%p", obj_desc); 460 if (!obj_desc) { 461 462 /* No attached object, we are done */ 463 464 acpi_os_printf("\n"); 465 return (AE_OK); 466 } 467 468 acpi_os_printf("(R%u)", obj_desc->common.reference_count); 469 470 switch (type) { 471 case ACPI_TYPE_METHOD: 472 473 /* Name is a Method and its AML offset/length are set */ 474 475 acpi_os_printf(" M:%p-%X\n", obj_desc->method.aml_start, 476 obj_desc->method.aml_length); 477 break; 478 479 case ACPI_TYPE_INTEGER: 480 481 acpi_os_printf(" I:%8.8X8.8%X\n", 482 ACPI_FORMAT_UINT64(obj_desc->integer. 483 value)); 484 break; 485 486 case ACPI_TYPE_STRING: 487 488 acpi_os_printf(" S:%p-%X\n", obj_desc->string.pointer, 489 obj_desc->string.length); 490 break; 491 492 case ACPI_TYPE_BUFFER: 493 494 acpi_os_printf(" B:%p-%X\n", obj_desc->buffer.pointer, 495 obj_desc->buffer.length); 496 break; 497 498 default: 499 500 acpi_os_printf("\n"); 501 break; 502 } 503 break; 504 505 default: 506 acpi_os_printf("\n"); 507 break; 508 } 509 510 /* If debug turned off, done */ 511 512 if (!(acpi_dbg_level & ACPI_LV_VALUES)) { 513 return (AE_OK); 514 } 515 516 /* If there is an attached object, display it */ 517 518 dbg_level = acpi_dbg_level; 519 acpi_dbg_level = 0; 520 obj_desc = acpi_ns_get_attached_object(this_node); 521 acpi_dbg_level = dbg_level; 522 523 /* Dump attached objects */ 524 525 while (obj_desc) { 526 obj_type = ACPI_TYPE_INVALID; 527 acpi_os_printf("Attached Object %p: ", obj_desc); 528 529 /* Decode the type of attached object and dump the contents */ 530 531 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { 532 case ACPI_DESC_TYPE_NAMED: 533 534 acpi_os_printf("(Ptr to Node)\n"); 535 bytes_to_dump = sizeof(struct acpi_namespace_node); 536 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); 537 break; 538 539 case ACPI_DESC_TYPE_OPERAND: 540 541 obj_type = obj_desc->common.type; 542 543 if (obj_type > ACPI_TYPE_LOCAL_MAX) { 544 acpi_os_printf 545 ("(Pointer to ACPI Object type %.2X [UNKNOWN])\n", 546 obj_type); 547 548 bytes_to_dump = 32; 549 } else { 550 acpi_os_printf 551 ("(Pointer to ACPI Object type %.2X [%s])\n", 552 obj_type, acpi_ut_get_type_name(obj_type)); 553 554 bytes_to_dump = 555 sizeof(union acpi_operand_object); 556 } 557 558 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); 559 break; 560 561 default: 562 563 break; 564 } 565 566 /* If value is NOT an internal object, we are done */ 567 568 if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != 569 ACPI_DESC_TYPE_OPERAND) { 570 goto cleanup; 571 } 572 573 /* Valid object, get the pointer to next level, if any */ 574 575 switch (obj_type) { 576 case ACPI_TYPE_BUFFER: 577 case ACPI_TYPE_STRING: 578 /* 579 * NOTE: takes advantage of common fields between string/buffer 580 */ 581 bytes_to_dump = obj_desc->string.length; 582 obj_desc = (void *)obj_desc->string.pointer; 583 584 acpi_os_printf("(Buffer/String pointer %p length %X)\n", 585 obj_desc, bytes_to_dump); 586 ACPI_DUMP_BUFFER(obj_desc, bytes_to_dump); 587 goto cleanup; 588 589 case ACPI_TYPE_BUFFER_FIELD: 590 591 obj_desc = 592 (union acpi_operand_object *)obj_desc->buffer_field. 593 buffer_obj; 594 break; 595 596 case ACPI_TYPE_PACKAGE: 597 598 obj_desc = (void *)obj_desc->package.elements; 599 break; 600 601 case ACPI_TYPE_METHOD: 602 603 obj_desc = (void *)obj_desc->method.aml_start; 604 break; 605 606 case ACPI_TYPE_LOCAL_REGION_FIELD: 607 608 obj_desc = (void *)obj_desc->field.region_obj; 609 break; 610 611 case ACPI_TYPE_LOCAL_BANK_FIELD: 612 613 obj_desc = (void *)obj_desc->bank_field.region_obj; 614 break; 615 616 case ACPI_TYPE_LOCAL_INDEX_FIELD: 617 618 obj_desc = (void *)obj_desc->index_field.index_obj; 619 break; 620 621 default: 622 623 goto cleanup; 624 } 625 626 obj_type = ACPI_TYPE_INVALID; /* Terminate loop after next pass */ 627 } 628 629 cleanup: 630 acpi_os_printf("\n"); 631 return (AE_OK); 632 } 633 634 /******************************************************************************* 635 * 636 * FUNCTION: acpi_ns_dump_objects 637 * 638 * PARAMETERS: type - Object type to be dumped 639 * display_type - 0 or ACPI_DISPLAY_SUMMARY 640 * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX 641 * for an effectively unlimited depth. 642 * owner_id - Dump only objects owned by this ID. Use 643 * ACPI_UINT32_MAX to match all owners. 644 * start_handle - Where in namespace to start/end search 645 * 646 * RETURN: None 647 * 648 * DESCRIPTION: Dump typed objects within the loaded namespace. Uses 649 * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object. 650 * 651 ******************************************************************************/ 652 653 void 654 acpi_ns_dump_objects(acpi_object_type type, 655 u8 display_type, 656 u32 max_depth, 657 acpi_owner_id owner_id, acpi_handle start_handle) 658 { 659 struct acpi_walk_info info; 660 acpi_status status; 661 662 ACPI_FUNCTION_ENTRY(); 663 664 /* 665 * Just lock the entire namespace for the duration of the dump. 666 * We don't want any changes to the namespace during this time, 667 * especially the temporary nodes since we are going to display 668 * them also. 669 */ 670 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 671 if (ACPI_FAILURE(status)) { 672 acpi_os_printf("Could not acquire namespace mutex\n"); 673 return; 674 } 675 676 info.debug_level = ACPI_LV_TABLES; 677 info.owner_id = owner_id; 678 info.display_type = display_type; 679 680 (void)acpi_ns_walk_namespace(type, start_handle, max_depth, 681 ACPI_NS_WALK_NO_UNLOCK | 682 ACPI_NS_WALK_TEMP_NODES, 683 acpi_ns_dump_one_object, NULL, 684 (void *)&info, NULL); 685 686 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 687 } 688 689 /******************************************************************************* 690 * 691 * FUNCTION: acpi_ns_dump_one_object_path, acpi_ns_get_max_depth 692 * 693 * PARAMETERS: obj_handle - Node to be dumped 694 * level - Nesting level of the handle 695 * context - Passed into walk_namespace 696 * return_value - Not used 697 * 698 * RETURN: Status 699 * 700 * DESCRIPTION: Dump the full pathname to a namespace object. acp_ns_get_max_depth 701 * computes the maximum nesting depth in the namespace tree, in 702 * order to simplify formatting in acpi_ns_dump_one_object_path. 703 * These procedures are user_functions called by acpi_ns_walk_namespace. 704 * 705 ******************************************************************************/ 706 707 static acpi_status 708 acpi_ns_dump_one_object_path(acpi_handle obj_handle, 709 u32 level, void *context, void **return_value) 710 { 711 u32 max_level = *((u32 *)context); 712 char *pathname; 713 struct acpi_namespace_node *node; 714 int path_indent; 715 716 if (!obj_handle) { 717 return (AE_OK); 718 } 719 720 node = acpi_ns_validate_handle(obj_handle); 721 if (!node) { 722 723 /* Ignore bad node during namespace walk */ 724 725 return (AE_OK); 726 } 727 728 pathname = acpi_ns_get_normalized_pathname(node, TRUE); 729 730 path_indent = 1; 731 if (level <= max_level) { 732 path_indent = max_level - level + 1; 733 } 734 735 acpi_os_printf("%2d%*s%-12s%*s", 736 level, level, " ", acpi_ut_get_type_name(node->type), 737 path_indent, " "); 738 739 acpi_os_printf("%s\n", &pathname[1]); 740 ACPI_FREE(pathname); 741 return (AE_OK); 742 } 743 744 static acpi_status 745 acpi_ns_get_max_depth(acpi_handle obj_handle, 746 u32 level, void *context, void **return_value) 747 { 748 u32 *max_level = (u32 *)context; 749 750 if (level > *max_level) { 751 *max_level = level; 752 } 753 return (AE_OK); 754 } 755 756 /******************************************************************************* 757 * 758 * FUNCTION: acpi_ns_dump_object_paths 759 * 760 * PARAMETERS: type - Object type to be dumped 761 * display_type - 0 or ACPI_DISPLAY_SUMMARY 762 * max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX 763 * for an effectively unlimited depth. 764 * owner_id - Dump only objects owned by this ID. Use 765 * ACPI_UINT32_MAX to match all owners. 766 * start_handle - Where in namespace to start/end search 767 * 768 * RETURN: None 769 * 770 * DESCRIPTION: Dump full object pathnames within the loaded namespace. Uses 771 * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object_path. 772 * 773 ******************************************************************************/ 774 775 void 776 acpi_ns_dump_object_paths(acpi_object_type type, 777 u8 display_type, 778 u32 max_depth, 779 acpi_owner_id owner_id, acpi_handle start_handle) 780 { 781 acpi_status status; 782 u32 max_level = 0; 783 784 ACPI_FUNCTION_ENTRY(); 785 786 /* 787 * Just lock the entire namespace for the duration of the dump. 788 * We don't want any changes to the namespace during this time, 789 * especially the temporary nodes since we are going to display 790 * them also. 791 */ 792 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 793 if (ACPI_FAILURE(status)) { 794 acpi_os_printf("Could not acquire namespace mutex\n"); 795 return; 796 } 797 798 /* Get the max depth of the namespace tree, for formatting later */ 799 800 (void)acpi_ns_walk_namespace(type, start_handle, max_depth, 801 ACPI_NS_WALK_NO_UNLOCK | 802 ACPI_NS_WALK_TEMP_NODES, 803 acpi_ns_get_max_depth, NULL, 804 (void *)&max_level, NULL); 805 806 /* Now dump the entire namespace */ 807 808 (void)acpi_ns_walk_namespace(type, start_handle, max_depth, 809 ACPI_NS_WALK_NO_UNLOCK | 810 ACPI_NS_WALK_TEMP_NODES, 811 acpi_ns_dump_one_object_path, NULL, 812 (void *)&max_level, NULL); 813 814 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 815 } 816 817 /******************************************************************************* 818 * 819 * FUNCTION: acpi_ns_dump_entry 820 * 821 * PARAMETERS: handle - Node to be dumped 822 * debug_level - Output level 823 * 824 * RETURN: None 825 * 826 * DESCRIPTION: Dump a single Node 827 * 828 ******************************************************************************/ 829 830 void acpi_ns_dump_entry(acpi_handle handle, u32 debug_level) 831 { 832 struct acpi_walk_info info; 833 834 ACPI_FUNCTION_ENTRY(); 835 836 info.debug_level = debug_level; 837 info.owner_id = ACPI_OWNER_ID_MAX; 838 info.display_type = ACPI_DISPLAY_SUMMARY; 839 840 (void)acpi_ns_dump_one_object(handle, 1, &info, NULL); 841 } 842 843 #ifdef ACPI_ASL_COMPILER 844 /******************************************************************************* 845 * 846 * FUNCTION: acpi_ns_dump_tables 847 * 848 * PARAMETERS: search_base - Root of subtree to be dumped, or 849 * NS_ALL to dump the entire namespace 850 * max_depth - Maximum depth of dump. Use INT_MAX 851 * for an effectively unlimited depth. 852 * 853 * RETURN: None 854 * 855 * DESCRIPTION: Dump the name space, or a portion of it. 856 * 857 ******************************************************************************/ 858 859 void acpi_ns_dump_tables(acpi_handle search_base, u32 max_depth) 860 { 861 acpi_handle search_handle = search_base; 862 863 ACPI_FUNCTION_TRACE(ns_dump_tables); 864 865 if (!acpi_gbl_root_node) { 866 /* 867 * If the name space has not been initialized, 868 * there is nothing to dump. 869 */ 870 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, 871 "namespace not initialized!\n")); 872 return_VOID; 873 } 874 875 if (ACPI_NS_ALL == search_base) { 876 877 /* Entire namespace */ 878 879 search_handle = acpi_gbl_root_node; 880 ACPI_DEBUG_PRINT((ACPI_DB_TABLES, "\\\n")); 881 } 882 883 acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, 884 ACPI_OWNER_ID_MAX, search_handle); 885 return_VOID; 886 } 887 #endif 888 #endif 889