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