linux/drivers/acpi/acpica/dbnames.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: dbnames - Debugger commands for the acpi namespace
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acnamesp.h"
  11#include "acdebug.h"
  12#include "acpredef.h"
  13#include "acinterp.h"
  14
  15#define _COMPONENT          ACPI_CA_DEBUGGER
  16ACPI_MODULE_NAME("dbnames")
  17
  18/* Local prototypes */
  19static acpi_status
  20acpi_db_walk_and_match_name(acpi_handle obj_handle,
  21                            u32 nesting_level,
  22                            void *context, void **return_value);
  23
  24static acpi_status
  25acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
  26                                  u32 nesting_level,
  27                                  void *context, void **return_value);
  28
  29static acpi_status
  30acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
  31                                  u32 nesting_level,
  32                                  void *context, void **return_value);
  33
  34static acpi_status
  35acpi_db_walk_for_object_counts(acpi_handle obj_handle,
  36                               u32 nesting_level,
  37                               void *context, void **return_value);
  38
  39static acpi_status
  40acpi_db_integrity_walk(acpi_handle obj_handle,
  41                       u32 nesting_level, void *context, void **return_value);
  42
  43static acpi_status
  44acpi_db_walk_for_references(acpi_handle obj_handle,
  45                            u32 nesting_level,
  46                            void *context, void **return_value);
  47
  48static acpi_status
  49acpi_db_bus_walk(acpi_handle obj_handle,
  50                 u32 nesting_level, void *context, void **return_value);
  51
  52/*
  53 * Arguments for the Objects command
  54 * These object types map directly to the ACPI_TYPES
  55 */
  56static struct acpi_db_argument_info acpi_db_object_types[] = {
  57        {"ANY"},
  58        {"INTEGERS"},
  59        {"STRINGS"},
  60        {"BUFFERS"},
  61        {"PACKAGES"},
  62        {"FIELDS"},
  63        {"DEVICES"},
  64        {"EVENTS"},
  65        {"METHODS"},
  66        {"MUTEXES"},
  67        {"REGIONS"},
  68        {"POWERRESOURCES"},
  69        {"PROCESSORS"},
  70        {"THERMALZONES"},
  71        {"BUFFERFIELDS"},
  72        {"DDBHANDLES"},
  73        {"DEBUG"},
  74        {"REGIONFIELDS"},
  75        {"BANKFIELDS"},
  76        {"INDEXFIELDS"},
  77        {"REFERENCES"},
  78        {"ALIASES"},
  79        {"METHODALIASES"},
  80        {"NOTIFY"},
  81        {"ADDRESSHANDLER"},
  82        {"RESOURCE"},
  83        {"RESOURCEFIELD"},
  84        {"SCOPES"},
  85        {NULL}                  /* Must be null terminated */
  86};
  87
  88/*******************************************************************************
  89 *
  90 * FUNCTION:    acpi_db_set_scope
  91 *
  92 * PARAMETERS:  name                - New scope path
  93 *
  94 * RETURN:      Status
  95 *
  96 * DESCRIPTION: Set the "current scope" as maintained by this utility.
  97 *              The scope is used as a prefix to ACPI paths.
  98 *
  99 ******************************************************************************/
 100
 101void acpi_db_set_scope(char *name)
 102{
 103        acpi_status status;
 104        struct acpi_namespace_node *node;
 105
 106        if (!name || name[0] == 0) {
 107                acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
 108                return;
 109        }
 110
 111        acpi_db_prep_namestring(name);
 112
 113        if (ACPI_IS_ROOT_PREFIX(name[0])) {
 114
 115                /* Validate new scope from the root */
 116
 117                status = acpi_ns_get_node(acpi_gbl_root_node, name,
 118                                          ACPI_NS_NO_UPSEARCH, &node);
 119                if (ACPI_FAILURE(status)) {
 120                        goto error_exit;
 121                }
 122
 123                acpi_gbl_db_scope_buf[0] = 0;
 124        } else {
 125                /* Validate new scope relative to old scope */
 126
 127                status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
 128                                          ACPI_NS_NO_UPSEARCH, &node);
 129                if (ACPI_FAILURE(status)) {
 130                        goto error_exit;
 131                }
 132        }
 133
 134        /* Build the final pathname */
 135
 136        if (acpi_ut_safe_strcat
 137            (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
 138                status = AE_BUFFER_OVERFLOW;
 139                goto error_exit;
 140        }
 141
 142        if (acpi_ut_safe_strcat
 143            (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
 144                status = AE_BUFFER_OVERFLOW;
 145                goto error_exit;
 146        }
 147
 148        acpi_gbl_db_scope_node = node;
 149        acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
 150        return;
 151
 152error_exit:
 153
 154        acpi_os_printf("Could not attach scope: %s, %s\n",
 155                       name, acpi_format_exception(status));
 156}
 157
 158/*******************************************************************************
 159 *
 160 * FUNCTION:    acpi_db_dump_namespace
 161 *
 162 * PARAMETERS:  start_arg       - Node to begin namespace dump
 163 *              depth_arg       - Maximum tree depth to be dumped
 164 *
 165 * RETURN:      None
 166 *
 167 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
 168 *              with type and other information.
 169 *
 170 ******************************************************************************/
 171
 172void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
 173{
 174        acpi_handle subtree_entry = acpi_gbl_root_node;
 175        u32 max_depth = ACPI_UINT32_MAX;
 176
 177        /* No argument given, just start at the root and dump entire namespace */
 178
 179        if (start_arg) {
 180                subtree_entry = acpi_db_convert_to_node(start_arg);
 181                if (!subtree_entry) {
 182                        return;
 183                }
 184
 185                /* Now we can check for the depth argument */
 186
 187                if (depth_arg) {
 188                        max_depth = strtoul(depth_arg, NULL, 0);
 189                }
 190        }
 191
 192        acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
 193
 194        if (((struct acpi_namespace_node *)subtree_entry)->parent) {
 195                acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
 196                               ((struct acpi_namespace_node *)subtree_entry)->
 197                               name.ascii, subtree_entry);
 198        } else {
 199                acpi_os_printf("ACPI Namespace (from %s):\n",
 200                               ACPI_NAMESPACE_ROOT);
 201        }
 202
 203        /* Display the subtree */
 204
 205        acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 206        acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
 207                             ACPI_OWNER_ID_MAX, subtree_entry);
 208        acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 209}
 210
 211/*******************************************************************************
 212 *
 213 * FUNCTION:    acpi_db_dump_namespace_paths
 214 *
 215 * PARAMETERS:  None
 216 *
 217 * RETURN:      None
 218 *
 219 * DESCRIPTION: Dump entire namespace with full object pathnames and object
 220 *              type information. Alternative to "namespace" command.
 221 *
 222 ******************************************************************************/
 223
 224void acpi_db_dump_namespace_paths(void)
 225{
 226
 227        acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
 228        acpi_os_printf("ACPI Namespace (from root):\n");
 229
 230        /* Display the entire namespace */
 231
 232        acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 233        acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
 234                                  ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
 235                                  acpi_gbl_root_node);
 236
 237        acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 238}
 239
 240/*******************************************************************************
 241 *
 242 * FUNCTION:    acpi_db_dump_namespace_by_owner
 243 *
 244 * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
 245 *              depth_arg       - Maximum tree depth to be dumped
 246 *
 247 * RETURN:      None
 248 *
 249 * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
 250 *
 251 ******************************************************************************/
 252
 253void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
 254{
 255        acpi_handle subtree_entry = acpi_gbl_root_node;
 256        u32 max_depth = ACPI_UINT32_MAX;
 257        acpi_owner_id owner_id;
 258
 259        owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0);
 260
 261        /* Now we can check for the depth argument */
 262
 263        if (depth_arg) {
 264                max_depth = strtoul(depth_arg, NULL, 0);
 265        }
 266
 267        acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
 268        acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);
 269
 270        /* Display the subtree */
 271
 272        acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 273        acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
 274                             owner_id, subtree_entry);
 275        acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 276}
 277
 278/*******************************************************************************
 279 *
 280 * FUNCTION:    acpi_db_walk_and_match_name
 281 *
 282 * PARAMETERS:  Callback from walk_namespace
 283 *
 284 * RETURN:      Status
 285 *
 286 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
 287 *              are supported -- '?' matches any character.
 288 *
 289 ******************************************************************************/
 290
 291static acpi_status
 292acpi_db_walk_and_match_name(acpi_handle obj_handle,
 293                            u32 nesting_level,
 294                            void *context, void **return_value)
 295{
 296        acpi_status status;
 297        char *requested_name = (char *)context;
 298        u32 i;
 299        struct acpi_buffer buffer;
 300        struct acpi_walk_info info;
 301
 302        /* Check for a name match */
 303
 304        for (i = 0; i < 4; i++) {
 305
 306                /* Wildcard support */
 307
 308                if ((requested_name[i] != '?') &&
 309                    (requested_name[i] != ((struct acpi_namespace_node *)
 310                                           obj_handle)->name.ascii[i])) {
 311
 312                        /* No match, just exit */
 313
 314                        return (AE_OK);
 315                }
 316        }
 317
 318        /* Get the full pathname to this object */
 319
 320        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 321        status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
 322        if (ACPI_FAILURE(status)) {
 323                acpi_os_printf("Could Not get pathname for object %p\n",
 324                               obj_handle);
 325        } else {
 326                info.count = 0;
 327                info.owner_id = ACPI_OWNER_ID_MAX;
 328                info.debug_level = ACPI_UINT32_MAX;
 329                info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
 330
 331                acpi_os_printf("%32s", (char *)buffer.pointer);
 332                (void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
 333                                              NULL);
 334                ACPI_FREE(buffer.pointer);
 335        }
 336
 337        return (AE_OK);
 338}
 339
 340/*******************************************************************************
 341 *
 342 * FUNCTION:    acpi_db_find_name_in_namespace
 343 *
 344 * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
 345 *                                wildcards are supported.
 346 *
 347 * RETURN:      None
 348 *
 349 * DESCRIPTION: Search the namespace for a given name (with wildcards)
 350 *
 351 ******************************************************************************/
 352
 353acpi_status acpi_db_find_name_in_namespace(char *name_arg)
 354{
 355        char acpi_name[5] = "____";
 356        char *acpi_name_ptr = acpi_name;
 357
 358        if (strlen(name_arg) > ACPI_NAMESEG_SIZE) {
 359                acpi_os_printf("Name must be no longer than 4 characters\n");
 360                return (AE_OK);
 361        }
 362
 363        /* Pad out name with underscores as necessary to create a 4-char name */
 364
 365        acpi_ut_strupr(name_arg);
 366        while (*name_arg) {
 367                *acpi_name_ptr = *name_arg;
 368                acpi_name_ptr++;
 369                name_arg++;
 370        }
 371
 372        /* Walk the namespace from the root */
 373
 374        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 375                                  ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
 376                                  NULL, acpi_name, NULL);
 377
 378        acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 379        return (AE_OK);
 380}
 381
 382/*******************************************************************************
 383 *
 384 * FUNCTION:    acpi_db_walk_for_predefined_names
 385 *
 386 * PARAMETERS:  Callback from walk_namespace
 387 *
 388 * RETURN:      Status
 389 *
 390 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
 391 *              an underscore)
 392 *
 393 ******************************************************************************/
 394
 395static acpi_status
 396acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
 397                                  u32 nesting_level,
 398                                  void *context, void **return_value)
 399{
 400        struct acpi_namespace_node *node =
 401            (struct acpi_namespace_node *)obj_handle;
 402        u32 *count = (u32 *)context;
 403        const union acpi_predefined_info *predefined;
 404        const union acpi_predefined_info *package = NULL;
 405        char *pathname;
 406        char string_buffer[48];
 407
 408        predefined = acpi_ut_match_predefined_method(node->name.ascii);
 409        if (!predefined) {
 410                return (AE_OK);
 411        }
 412
 413        pathname = acpi_ns_get_normalized_pathname(node, TRUE);
 414        if (!pathname) {
 415                return (AE_OK);
 416        }
 417
 418        /* If method returns a package, the info is in the next table entry */
 419
 420        if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
 421                package = predefined + 1;
 422        }
 423
 424        acpi_ut_get_expected_return_types(string_buffer,
 425                                          predefined->info.expected_btypes);
 426
 427        acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
 428                       METHOD_GET_ARG_COUNT(predefined->info.argument_list),
 429                       string_buffer);
 430
 431        if (package) {
 432                acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
 433                               package->ret_info.type,
 434                               package->ret_info.object_type1,
 435                               package->ret_info.count1);
 436        }
 437
 438        acpi_os_printf("\n");
 439
 440        /* Check that the declared argument count matches the ACPI spec */
 441
 442        acpi_ns_check_acpi_compliance(pathname, node, predefined);
 443
 444        ACPI_FREE(pathname);
 445        (*count)++;
 446        return (AE_OK);
 447}
 448
 449/*******************************************************************************
 450 *
 451 * FUNCTION:    acpi_db_check_predefined_names
 452 *
 453 * PARAMETERS:  None
 454 *
 455 * RETURN:      None
 456 *
 457 * DESCRIPTION: Validate all predefined names in the namespace
 458 *
 459 ******************************************************************************/
 460
 461void acpi_db_check_predefined_names(void)
 462{
 463        u32 count = 0;
 464
 465        /* Search all nodes in namespace */
 466
 467        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 468                                  ACPI_UINT32_MAX,
 469                                  acpi_db_walk_for_predefined_names, NULL,
 470                                  (void *)&count, NULL);
 471
 472        acpi_os_printf("Found %u predefined names in the namespace\n", count);
 473}
 474
 475/*******************************************************************************
 476 *
 477 * FUNCTION:    acpi_db_walk_for_object_counts
 478 *
 479 * PARAMETERS:  Callback from walk_namespace
 480 *
 481 * RETURN:      Status
 482 *
 483 * DESCRIPTION: Display short info about objects in the namespace
 484 *
 485 ******************************************************************************/
 486
 487static acpi_status
 488acpi_db_walk_for_object_counts(acpi_handle obj_handle,
 489                               u32 nesting_level,
 490                               void *context, void **return_value)
 491{
 492        struct acpi_object_info *info = (struct acpi_object_info *)context;
 493        struct acpi_namespace_node *node =
 494            (struct acpi_namespace_node *)obj_handle;
 495
 496        if (node->type > ACPI_TYPE_NS_NODE_MAX) {
 497                acpi_os_printf("[%4.4s]: Unknown object type %X\n",
 498                               node->name.ascii, node->type);
 499        } else {
 500                info->types[node->type]++;
 501        }
 502
 503        return (AE_OK);
 504}
 505
 506/*******************************************************************************
 507 *
 508 * FUNCTION:    acpi_db_walk_for_fields
 509 *
 510 * PARAMETERS:  Callback from walk_namespace
 511 *
 512 * RETURN:      Status
 513 *
 514 * DESCRIPTION: Display short info about objects in the namespace
 515 *
 516 ******************************************************************************/
 517
 518static acpi_status
 519acpi_db_walk_for_fields(acpi_handle obj_handle,
 520                        u32 nesting_level, void *context, void **return_value)
 521{
 522        union acpi_object *ret_value;
 523        struct acpi_region_walk_info *info =
 524            (struct acpi_region_walk_info *)context;
 525        struct acpi_buffer buffer;
 526        acpi_status status;
 527        struct acpi_namespace_node *node = acpi_ns_validate_handle(obj_handle);
 528
 529        if (!node) {
 530                return (AE_OK);
 531        }
 532        if (node->object->field.region_obj->region.space_id !=
 533            info->address_space_id) {
 534                return (AE_OK);
 535        }
 536
 537        info->count++;
 538
 539        /* Get and display the full pathname to this object */
 540
 541        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 542        status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
 543        if (ACPI_FAILURE(status)) {
 544                acpi_os_printf("Could Not get pathname for object %p\n",
 545                               obj_handle);
 546                return (AE_OK);
 547        }
 548
 549        acpi_os_printf("%s ", (char *)buffer.pointer);
 550        ACPI_FREE(buffer.pointer);
 551
 552        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 553        acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
 554
 555        /*
 556         * Since this is a field unit, surround the output in braces
 557         */
 558        acpi_os_printf("{");
 559
 560        ret_value = (union acpi_object *)buffer.pointer;
 561        switch (ret_value->type) {
 562        case ACPI_TYPE_INTEGER:
 563
 564                acpi_os_printf("%8.8X%8.8X",
 565                               ACPI_FORMAT_UINT64(ret_value->integer.value));
 566                break;
 567
 568        case ACPI_TYPE_BUFFER:
 569
 570                acpi_ut_dump_buffer(ret_value->buffer.pointer,
 571                                    ret_value->buffer.length,
 572                                    DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
 573                break;
 574
 575        default:
 576
 577                break;
 578        }
 579        acpi_os_printf("}\n");
 580
 581        ACPI_FREE(buffer.pointer);
 582
 583        return (AE_OK);
 584}
 585
 586/*******************************************************************************
 587 *
 588 * FUNCTION:    acpi_db_walk_for_specific_objects
 589 *
 590 * PARAMETERS:  Callback from walk_namespace
 591 *
 592 * RETURN:      Status
 593 *
 594 * DESCRIPTION: Display short info about objects in the namespace
 595 *
 596 ******************************************************************************/
 597
 598static acpi_status
 599acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
 600                                  u32 nesting_level,
 601                                  void *context, void **return_value)
 602{
 603        struct acpi_walk_info *info = (struct acpi_walk_info *)context;
 604        struct acpi_buffer buffer;
 605        acpi_status status;
 606
 607        info->count++;
 608
 609        /* Get and display the full pathname to this object */
 610
 611        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 612        status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
 613        if (ACPI_FAILURE(status)) {
 614                acpi_os_printf("Could Not get pathname for object %p\n",
 615                               obj_handle);
 616                return (AE_OK);
 617        }
 618
 619        acpi_os_printf("%32s", (char *)buffer.pointer);
 620        ACPI_FREE(buffer.pointer);
 621
 622        /* Dump short info about the object */
 623
 624        (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
 625        return (AE_OK);
 626}
 627
 628/*******************************************************************************
 629 *
 630 * FUNCTION:    acpi_db_display_objects
 631 *
 632 * PARAMETERS:  obj_type_arg        - Type of object to display
 633 *              display_count_arg   - Max depth to display
 634 *
 635 * RETURN:      None
 636 *
 637 * DESCRIPTION: Display objects in the namespace of the requested type
 638 *
 639 ******************************************************************************/
 640
 641acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
 642{
 643        struct acpi_walk_info info;
 644        acpi_object_type type;
 645        struct acpi_object_info *object_info;
 646        u32 i;
 647        u32 total_objects = 0;
 648
 649        /* No argument means display summary/count of all object types */
 650
 651        if (!obj_type_arg) {
 652                object_info =
 653                    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));
 654
 655                /* Walk the namespace from the root */
 656
 657                (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 658                                          ACPI_UINT32_MAX,
 659                                          acpi_db_walk_for_object_counts, NULL,
 660                                          (void *)object_info, NULL);
 661
 662                acpi_os_printf("\nSummary of namespace objects:\n\n");
 663
 664                for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
 665                        acpi_os_printf("%8u %s\n", object_info->types[i],
 666                                       acpi_ut_get_type_name(i));
 667
 668                        total_objects += object_info->types[i];
 669                }
 670
 671                acpi_os_printf("\n%8u Total namespace objects\n\n",
 672                               total_objects);
 673
 674                ACPI_FREE(object_info);
 675                return (AE_OK);
 676        }
 677
 678        /* Get the object type */
 679
 680        type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
 681        if (type == ACPI_TYPE_NOT_FOUND) {
 682                acpi_os_printf("Invalid or unsupported argument\n");
 683                return (AE_OK);
 684        }
 685
 686        acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
 687        acpi_os_printf
 688            ("Objects of type [%s] defined in the current ACPI Namespace:\n",
 689             acpi_ut_get_type_name(type));
 690
 691        acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 692
 693        info.count = 0;
 694        info.owner_id = ACPI_OWNER_ID_MAX;
 695        info.debug_level = ACPI_UINT32_MAX;
 696        info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
 697
 698        /* Walk the namespace from the root */
 699
 700        (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 701                                  acpi_db_walk_for_specific_objects, NULL,
 702                                  (void *)&info, NULL);
 703
 704        acpi_os_printf
 705            ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
 706             info.count, acpi_ut_get_type_name(type));
 707
 708        acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 709        return (AE_OK);
 710}
 711
 712/*******************************************************************************
 713 *
 714 * FUNCTION:    acpi_db_display_fields
 715 *
 716 * PARAMETERS:  obj_type_arg        - Type of object to display
 717 *              display_count_arg   - Max depth to display
 718 *
 719 * RETURN:      None
 720 *
 721 * DESCRIPTION: Display objects in the namespace of the requested type
 722 *
 723 ******************************************************************************/
 724
 725acpi_status acpi_db_display_fields(u32 address_space_id)
 726{
 727        struct acpi_region_walk_info info;
 728
 729        info.count = 0;
 730        info.owner_id = ACPI_OWNER_ID_MAX;
 731        info.debug_level = ACPI_UINT32_MAX;
 732        info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
 733        info.address_space_id = address_space_id;
 734
 735        /* Walk the namespace from the root */
 736
 737        (void)acpi_walk_namespace(ACPI_TYPE_LOCAL_REGION_FIELD,
 738                                  ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 739                                  acpi_db_walk_for_fields, NULL, (void *)&info,
 740                                  NULL);
 741
 742        return (AE_OK);
 743}
 744
 745/*******************************************************************************
 746 *
 747 * FUNCTION:    acpi_db_integrity_walk
 748 *
 749 * PARAMETERS:  Callback from walk_namespace
 750 *
 751 * RETURN:      Status
 752 *
 753 * DESCRIPTION: Examine one NS node for valid values.
 754 *
 755 ******************************************************************************/
 756
 757static acpi_status
 758acpi_db_integrity_walk(acpi_handle obj_handle,
 759                       u32 nesting_level, void *context, void **return_value)
 760{
 761        struct acpi_integrity_info *info =
 762            (struct acpi_integrity_info *)context;
 763        struct acpi_namespace_node *node =
 764            (struct acpi_namespace_node *)obj_handle;
 765        union acpi_operand_object *object;
 766        u8 alias = TRUE;
 767
 768        info->nodes++;
 769
 770        /* Verify the NS node, and dereference aliases */
 771
 772        while (alias) {
 773                if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
 774                        acpi_os_printf
 775                            ("Invalid Descriptor Type for Node %p [%s] - "
 776                             "is %2.2X should be %2.2X\n", node,
 777                             acpi_ut_get_descriptor_name(node),
 778                             ACPI_GET_DESCRIPTOR_TYPE(node),
 779                             ACPI_DESC_TYPE_NAMED);
 780                        return (AE_OK);
 781                }
 782
 783                if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
 784                    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
 785                        node = (struct acpi_namespace_node *)node->object;
 786                } else {
 787                        alias = FALSE;
 788                }
 789        }
 790
 791        if (node->type > ACPI_TYPE_LOCAL_MAX) {
 792                acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
 793                               node, node->type);
 794                return (AE_OK);
 795        }
 796
 797        if (!acpi_ut_valid_nameseg(node->name.ascii)) {
 798                acpi_os_printf("Invalid AcpiName for Node %p\n", node);
 799                return (AE_OK);
 800        }
 801
 802        object = acpi_ns_get_attached_object(node);
 803        if (object) {
 804                info->objects++;
 805                if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
 806                        acpi_os_printf
 807                            ("Invalid Descriptor Type for Object %p [%s]\n",
 808                             object, acpi_ut_get_descriptor_name(object));
 809                }
 810        }
 811
 812        return (AE_OK);
 813}
 814
 815/*******************************************************************************
 816 *
 817 * FUNCTION:    acpi_db_check_integrity
 818 *
 819 * PARAMETERS:  None
 820 *
 821 * RETURN:      None
 822 *
 823 * DESCRIPTION: Check entire namespace for data structure integrity
 824 *
 825 ******************************************************************************/
 826
 827void acpi_db_check_integrity(void)
 828{
 829        struct acpi_integrity_info info = { 0, 0 };
 830
 831        /* Search all nodes in namespace */
 832
 833        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 834                                  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
 835                                  (void *)&info, NULL);
 836
 837        acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
 838                       info.nodes, info.objects);
 839}
 840
 841/*******************************************************************************
 842 *
 843 * FUNCTION:    acpi_db_walk_for_references
 844 *
 845 * PARAMETERS:  Callback from walk_namespace
 846 *
 847 * RETURN:      Status
 848 *
 849 * DESCRIPTION: Check if this namespace object refers to the target object
 850 *              that is passed in as the context value.
 851 *
 852 * Note: Currently doesn't check subobjects within the Node's object
 853 *
 854 ******************************************************************************/
 855
 856static acpi_status
 857acpi_db_walk_for_references(acpi_handle obj_handle,
 858                            u32 nesting_level,
 859                            void *context, void **return_value)
 860{
 861        union acpi_operand_object *obj_desc =
 862            (union acpi_operand_object *)context;
 863        struct acpi_namespace_node *node =
 864            (struct acpi_namespace_node *)obj_handle;
 865
 866        /* Check for match against the namespace node itself */
 867
 868        if (node == (void *)obj_desc) {
 869                acpi_os_printf("Object is a Node [%4.4s]\n",
 870                               acpi_ut_get_node_name(node));
 871        }
 872
 873        /* Check for match against the object attached to the node */
 874
 875        if (acpi_ns_get_attached_object(node) == obj_desc) {
 876                acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
 877                               node, acpi_ut_get_node_name(node));
 878        }
 879
 880        return (AE_OK);
 881}
 882
 883/*******************************************************************************
 884 *
 885 * FUNCTION:    acpi_db_find_references
 886 *
 887 * PARAMETERS:  object_arg      - String with hex value of the object
 888 *
 889 * RETURN:      None
 890 *
 891 * DESCRIPTION: Search namespace for all references to the input object
 892 *
 893 ******************************************************************************/
 894
 895void acpi_db_find_references(char *object_arg)
 896{
 897        union acpi_operand_object *obj_desc;
 898        acpi_size address;
 899
 900        /* Convert string to object pointer */
 901
 902        address = strtoul(object_arg, NULL, 16);
 903        obj_desc = ACPI_TO_POINTER(address);
 904
 905        /* Search all nodes in namespace */
 906
 907        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
 908                                  ACPI_UINT32_MAX, acpi_db_walk_for_references,
 909                                  NULL, (void *)obj_desc, NULL);
 910}
 911
 912/*******************************************************************************
 913 *
 914 * FUNCTION:    acpi_db_bus_walk
 915 *
 916 * PARAMETERS:  Callback from walk_namespace
 917 *
 918 * RETURN:      Status
 919 *
 920 * DESCRIPTION: Display info about device objects that have a corresponding
 921 *              _PRT method.
 922 *
 923 ******************************************************************************/
 924
 925static acpi_status
 926acpi_db_bus_walk(acpi_handle obj_handle,
 927                 u32 nesting_level, void *context, void **return_value)
 928{
 929        struct acpi_namespace_node *node =
 930            (struct acpi_namespace_node *)obj_handle;
 931        acpi_status status;
 932        struct acpi_buffer buffer;
 933        struct acpi_namespace_node *temp_node;
 934        struct acpi_device_info *info;
 935        u32 i;
 936
 937        if ((node->type != ACPI_TYPE_DEVICE) &&
 938            (node->type != ACPI_TYPE_PROCESSOR)) {
 939                return (AE_OK);
 940        }
 941
 942        /* Exit if there is no _PRT under this device */
 943
 944        status = acpi_get_handle(node, METHOD_NAME__PRT,
 945                                 ACPI_CAST_PTR(acpi_handle, &temp_node));
 946        if (ACPI_FAILURE(status)) {
 947                return (AE_OK);
 948        }
 949
 950        /* Get the full path to this device object */
 951
 952        buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 953        status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
 954        if (ACPI_FAILURE(status)) {
 955                acpi_os_printf("Could Not get pathname for object %p\n",
 956                               obj_handle);
 957                return (AE_OK);
 958        }
 959
 960        status = acpi_get_object_info(obj_handle, &info);
 961        if (ACPI_FAILURE(status)) {
 962                return (AE_OK);
 963        }
 964
 965        /* Display the full path */
 966
 967        acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
 968        ACPI_FREE(buffer.pointer);
 969
 970        if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
 971                acpi_os_printf(" - Is PCI Root Bridge");
 972        }
 973        acpi_os_printf("\n");
 974
 975        /* _PRT info */
 976
 977        acpi_os_printf("_PRT: %p\n", temp_node);
 978
 979        /* Dump _ADR, _HID, _UID, _CID */
 980
 981        if (info->valid & ACPI_VALID_ADR) {
 982                acpi_os_printf("_ADR: %8.8X%8.8X\n",
 983                               ACPI_FORMAT_UINT64(info->address));
 984        } else {
 985                acpi_os_printf("_ADR: <Not Present>\n");
 986        }
 987
 988        if (info->valid & ACPI_VALID_HID) {
 989                acpi_os_printf("_HID: %s\n", info->hardware_id.string);
 990        } else {
 991                acpi_os_printf("_HID: <Not Present>\n");
 992        }
 993
 994        if (info->valid & ACPI_VALID_UID) {
 995                acpi_os_printf("_UID: %s\n", info->unique_id.string);
 996        } else {
 997                acpi_os_printf("_UID: <Not Present>\n");
 998        }
 999
1000        if (info->valid & ACPI_VALID_CID) {
1001                for (i = 0; i < info->compatible_id_list.count; i++) {
1002                        acpi_os_printf("_CID: %s\n",
1003                                       info->compatible_id_list.ids[i].string);
1004                }
1005        } else {
1006                acpi_os_printf("_CID: <Not Present>\n");
1007        }
1008
1009        ACPI_FREE(info);
1010        return (AE_OK);
1011}
1012
1013/*******************************************************************************
1014 *
1015 * FUNCTION:    acpi_db_get_bus_info
1016 *
1017 * PARAMETERS:  None
1018 *
1019 * RETURN:      None
1020 *
1021 * DESCRIPTION: Display info about system buses.
1022 *
1023 ******************************************************************************/
1024
1025void acpi_db_get_bus_info(void)
1026{
1027        /* Search all nodes in namespace */
1028
1029        (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
1030                                  ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
1031                                  NULL);
1032}
1033