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