1 /*******************************************************************************
   2  *
   3  * Module Name: dbnames - Debugger commands for the acpi namespace
   4  *
   5  ******************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2011, 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 
  45 #include "acpi.h"
  46 #include "accommon.h"
  47 #include "acnamesp.h"
  48 #include "acdebug.h"
  49 
  50 
  51 #ifdef ACPI_DEBUGGER
  52 
  53 #define _COMPONENT          ACPI_CA_DEBUGGER
  54         ACPI_MODULE_NAME    ("dbnames")
  55 
  56 
  57 /* Local prototypes */
  58 
  59 static ACPI_STATUS
  60 AcpiDbWalkAndMatchName (
  61     ACPI_HANDLE             ObjHandle,
  62     UINT32                  NestingLevel,
  63     void                    *Context,
  64     void                    **ReturnValue);
  65 
  66 static ACPI_STATUS
  67 AcpiDbWalkForPredefinedNames (
  68     ACPI_HANDLE             ObjHandle,
  69     UINT32                  NestingLevel,
  70     void                    *Context,
  71     void                    **ReturnValue);
  72 
  73 static ACPI_STATUS
  74 AcpiDbWalkForSpecificObjects (
  75     ACPI_HANDLE             ObjHandle,
  76     UINT32                  NestingLevel,
  77     void                    *Context,
  78     void                    **ReturnValue);
  79 
  80 static ACPI_STATUS
  81 AcpiDbIntegrityWalk (
  82     ACPI_HANDLE             ObjHandle,
  83     UINT32                  NestingLevel,
  84     void                    *Context,
  85     void                    **ReturnValue);
  86 
  87 static ACPI_STATUS
  88 AcpiDbWalkForReferences (
  89     ACPI_HANDLE             ObjHandle,
  90     UINT32                  NestingLevel,
  91     void                    *Context,
  92     void                    **ReturnValue);
  93 
  94 static ACPI_STATUS
  95 AcpiDbBusWalk (
  96     ACPI_HANDLE             ObjHandle,
  97     UINT32                  NestingLevel,
  98     void                    *Context,
  99     void                    **ReturnValue);
 100 
 101 /*
 102  * Arguments for the Objects command
 103  * These object types map directly to the ACPI_TYPES
 104  */
 105 static ARGUMENT_INFO        AcpiDbObjectTypes [] =
 106 {
 107     {"ANY"},
 108     {"INTEGERS"},
 109     {"STRINGS"},
 110     {"BUFFERS"},
 111     {"PACKAGES"},
 112     {"FIELDS"},
 113     {"DEVICES"},
 114     {"EVENTS"},
 115     {"METHODS"},
 116     {"MUTEXES"},
 117     {"REGIONS"},
 118     {"POWERRESOURCES"},
 119     {"PROCESSORS"},
 120     {"THERMALZONES"},
 121     {"BUFFERFIELDS"},
 122     {"DDBHANDLES"},
 123     {"DEBUG"},
 124     {"REGIONFIELDS"},
 125     {"BANKFIELDS"},
 126     {"INDEXFIELDS"},
 127     {"REFERENCES"},
 128     {"ALIAS"},
 129     {NULL}           /* Must be null terminated */
 130 };
 131 
 132 
 133 /*******************************************************************************
 134  *
 135  * FUNCTION:    AcpiDbSetScope
 136  *
 137  * PARAMETERS:  Name                - New scope path
 138  *
 139  * RETURN:      Status
 140  *
 141  * DESCRIPTION: Set the "current scope" as maintained by this utility.
 142  *              The scope is used as a prefix to ACPI paths.
 143  *
 144  ******************************************************************************/
 145 
 146 void
 147 AcpiDbSetScope (
 148     char                    *Name)
 149 {
 150     ACPI_STATUS             Status;
 151     ACPI_NAMESPACE_NODE     *Node;
 152 
 153 
 154     if (!Name || Name[0] == 0)
 155     {
 156         AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf);
 157         return;
 158     }
 159 
 160     AcpiDbPrepNamestring (Name);
 161 
 162     if (Name[0] == '\\')
 163     {
 164         /* Validate new scope from the root */
 165 
 166         Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH,
 167                     &Node);
 168         if (ACPI_FAILURE (Status))
 169         {
 170             goto ErrorExit;
 171         }
 172 
 173         ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name);
 174         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
 175     }
 176     else
 177     {
 178         /* Validate new scope relative to old scope */
 179 
 180         Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH,
 181                     &Node);
 182         if (ACPI_FAILURE (Status))
 183         {
 184             goto ErrorExit;
 185         }
 186 
 187         ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name);
 188         ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\");
 189     }
 190 
 191     AcpiGbl_DbScopeNode = Node;
 192     AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf);
 193     return;
 194 
 195 ErrorExit:
 196 
 197     AcpiOsPrintf ("Could not attach scope: %s, %s\n",
 198         Name, AcpiFormatException (Status));
 199 }
 200 
 201 
 202 /*******************************************************************************
 203  *
 204  * FUNCTION:    AcpiDbDumpNamespace
 205  *
 206  * PARAMETERS:  StartArg        - Node to begin namespace dump
 207  *              DepthArg        - Maximum tree depth to be dumped
 208  *
 209  * RETURN:      None
 210  *
 211  * DESCRIPTION: Dump entire namespace or a subtree.  Each node is displayed
 212  *              with type and other information.
 213  *
 214  ******************************************************************************/
 215 
 216 void
 217 AcpiDbDumpNamespace (
 218     char                    *StartArg,
 219     char                    *DepthArg)
 220 {
 221     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
 222     UINT32                  MaxDepth = ACPI_UINT32_MAX;
 223 
 224 
 225     /* No argument given, just start at the root and dump entire namespace */
 226 
 227     if (StartArg)
 228     {
 229         SubtreeEntry = AcpiDbConvertToNode (StartArg);
 230         if (!SubtreeEntry)
 231         {
 232             return;
 233         }
 234 
 235         /* Now we can check for the depth argument */
 236 
 237         if (DepthArg)
 238         {
 239             MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
 240         }
 241     }
 242 
 243     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
 244     AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n",
 245         ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry);
 246 
 247     /* Display the subtree */
 248 
 249     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
 250     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth,
 251         ACPI_OWNER_ID_MAX, SubtreeEntry);
 252     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
 253 }
 254 
 255 
 256 /*******************************************************************************
 257  *
 258  * FUNCTION:    AcpiDbDumpNamespaceByOwner
 259  *
 260  * PARAMETERS:  OwnerArg        - Owner ID whose nodes will be displayed
 261  *              DepthArg        - Maximum tree depth to be dumped
 262  *
 263  * RETURN:      None
 264  *
 265  * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId.
 266  *
 267  ******************************************************************************/
 268 
 269 void
 270 AcpiDbDumpNamespaceByOwner (
 271     char                    *OwnerArg,
 272     char                    *DepthArg)
 273 {
 274     ACPI_HANDLE             SubtreeEntry = AcpiGbl_RootNode;
 275     UINT32                  MaxDepth = ACPI_UINT32_MAX;
 276     ACPI_OWNER_ID           OwnerId;
 277 
 278 
 279     OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0);
 280 
 281     /* Now we can check for the depth argument */
 282 
 283     if (DepthArg)
 284     {
 285         MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0);
 286     }
 287 
 288     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
 289     AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId);
 290 
 291     /* Display the subtree */
 292 
 293     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
 294     AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId,
 295         SubtreeEntry);
 296     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
 297 }
 298 
 299 
 300 /*******************************************************************************
 301  *
 302  * FUNCTION:    AcpiDbWalkAndMatchName
 303  *
 304  * PARAMETERS:  Callback from WalkNamespace
 305  *
 306  * RETURN:      Status
 307  *
 308  * DESCRIPTION: Find a particular name/names within the namespace.  Wildcards
 309  *              are supported -- '?' matches any character.
 310  *
 311  ******************************************************************************/
 312 
 313 static ACPI_STATUS
 314 AcpiDbWalkAndMatchName (
 315     ACPI_HANDLE             ObjHandle,
 316     UINT32                  NestingLevel,
 317     void                    *Context,
 318     void                    **ReturnValue)
 319 {
 320     ACPI_STATUS             Status;
 321     char                    *RequestedName = (char *) Context;
 322     UINT32                  i;
 323     ACPI_BUFFER             Buffer;
 324     ACPI_WALK_INFO          Info;
 325 
 326 
 327     /* Check for a name match */
 328 
 329     for (i = 0; i < 4; i++)
 330     {
 331         /* Wildcard support */
 332 
 333         if ((RequestedName[i] != '?') &&
 334             (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i]))
 335         {
 336             /* No match, just exit */
 337 
 338             return (AE_OK);
 339         }
 340     }
 341 
 342     /* Get the full pathname to this object */
 343 
 344     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 345     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
 346     if (ACPI_FAILURE (Status))
 347     {
 348         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
 349     }
 350     else
 351     {
 352         Info.OwnerId = ACPI_OWNER_ID_MAX;
 353         Info.DebugLevel = ACPI_UINT32_MAX;
 354         Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
 355 
 356         AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
 357         (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL);
 358         ACPI_FREE (Buffer.Pointer);
 359     }
 360 
 361     return (AE_OK);
 362 }
 363 
 364 
 365 /*******************************************************************************
 366  *
 367  * FUNCTION:    AcpiDbFindNameInNamespace
 368  *
 369  * PARAMETERS:  NameArg         - The 4-character ACPI name to find.
 370  *                                wildcards are supported.
 371  *
 372  * RETURN:      None
 373  *
 374  * DESCRIPTION: Search the namespace for a given name (with wildcards)
 375  *
 376  ******************************************************************************/
 377 
 378 ACPI_STATUS
 379 AcpiDbFindNameInNamespace (
 380     char                    *NameArg)
 381 {
 382     char                    AcpiName[5] = "____";
 383     char                    *AcpiNamePtr = AcpiName;
 384 
 385 
 386     if (ACPI_STRLEN (NameArg) > 4)
 387     {
 388         AcpiOsPrintf ("Name must be no longer than 4 characters\n");
 389         return (AE_OK);
 390     }
 391 
 392     /* Pad out name with underscores as necessary to create a 4-char name */
 393 
 394     AcpiUtStrupr (NameArg);
 395     while (*NameArg)
 396     {
 397         *AcpiNamePtr = *NameArg;
 398         AcpiNamePtr++;
 399         NameArg++;
 400     }
 401 
 402     /* Walk the namespace from the root */
 403 
 404     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 405                         AcpiDbWalkAndMatchName, NULL, AcpiName, NULL);
 406 
 407     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
 408     return (AE_OK);
 409 }
 410 
 411 
 412 /*******************************************************************************
 413  *
 414  * FUNCTION:    AcpiDbWalkForPredefinedNames
 415  *
 416  * PARAMETERS:  Callback from WalkNamespace
 417  *
 418  * RETURN:      Status
 419  *
 420  * DESCRIPTION: Detect and display predefined ACPI names (names that start with
 421  *              an underscore)
 422  *
 423  ******************************************************************************/
 424 
 425 static ACPI_STATUS
 426 AcpiDbWalkForPredefinedNames (
 427     ACPI_HANDLE             ObjHandle,
 428     UINT32                  NestingLevel,
 429     void                    *Context,
 430     void                    **ReturnValue)
 431 {
 432     ACPI_NAMESPACE_NODE         *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
 433     UINT32                      *Count = (UINT32 *) Context;
 434     const ACPI_PREDEFINED_INFO  *Predefined;
 435     const ACPI_PREDEFINED_INFO  *Package = NULL;
 436     char                        *Pathname;
 437 
 438 
 439     Predefined = AcpiNsCheckForPredefinedName (Node);
 440     if (!Predefined)
 441     {
 442         return (AE_OK);
 443     }
 444 
 445     Pathname = AcpiNsGetExternalPathname (Node);
 446     if (!Pathname)
 447     {
 448         return (AE_OK);
 449     }
 450 
 451     /* If method returns a package, the info is in the next table entry */
 452 
 453     if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE)
 454     {
 455         Package = Predefined + 1;
 456     }
 457 
 458     AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname,
 459         Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes);
 460 
 461     if (Package)
 462     {
 463         AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X",
 464             Package->RetInfo.Type, Package->RetInfo.ObjectType1,
 465             Package->RetInfo.Count1);
 466     }
 467 
 468     AcpiOsPrintf("\n");
 469 
 470     AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined);
 471     ACPI_FREE (Pathname);
 472     (*Count)++;
 473 
 474     return (AE_OK);
 475 }
 476 
 477 
 478 /*******************************************************************************
 479  *
 480  * FUNCTION:    AcpiDbCheckPredefinedNames
 481  *
 482  * PARAMETERS:  None
 483  *
 484  * RETURN:      None
 485  *
 486  * DESCRIPTION: Validate all predefined names in the namespace
 487  *
 488  ******************************************************************************/
 489 
 490 void
 491 AcpiDbCheckPredefinedNames (
 492     void)
 493 {
 494     UINT32                  Count = 0;
 495 
 496 
 497     /* Search all nodes in namespace */
 498 
 499     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 500                 AcpiDbWalkForPredefinedNames, NULL, (void *) &Count, NULL);
 501 
 502     AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count);
 503 }
 504 
 505 
 506 /*******************************************************************************
 507  *
 508  * FUNCTION:    AcpiDbWalkForSpecificObjects
 509  *
 510  * PARAMETERS:  Callback from WalkNamespace
 511  *
 512  * RETURN:      Status
 513  *
 514  * DESCRIPTION: Display short info about objects in the namespace
 515  *
 516  ******************************************************************************/
 517 
 518 static ACPI_STATUS
 519 AcpiDbWalkForSpecificObjects (
 520     ACPI_HANDLE             ObjHandle,
 521     UINT32                  NestingLevel,
 522     void                    *Context,
 523     void                    **ReturnValue)
 524 {
 525     ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
 526     ACPI_BUFFER             Buffer;
 527     ACPI_STATUS             Status;
 528 
 529 
 530     Info->Count++;
 531 
 532     /* Get and display the full pathname to this object */
 533 
 534     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 535     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
 536     if (ACPI_FAILURE (Status))
 537     {
 538         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
 539         return (AE_OK);
 540     }
 541 
 542     AcpiOsPrintf ("%32s", (char *) Buffer.Pointer);
 543     ACPI_FREE (Buffer.Pointer);
 544 
 545     /* Dump short info about the object */
 546 
 547     (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL);
 548     return (AE_OK);
 549 }
 550 
 551 
 552 /*******************************************************************************
 553  *
 554  * FUNCTION:    AcpiDbDisplayObjects
 555  *
 556  * PARAMETERS:  ObjTypeArg          - Type of object to display
 557  *              DisplayCountArg     - Max depth to display
 558  *
 559  * RETURN:      None
 560  *
 561  * DESCRIPTION: Display objects in the namespace of the requested type
 562  *
 563  ******************************************************************************/
 564 
 565 ACPI_STATUS
 566 AcpiDbDisplayObjects (
 567     char                    *ObjTypeArg,
 568     char                    *DisplayCountArg)
 569 {
 570     ACPI_WALK_INFO          Info;
 571     ACPI_OBJECT_TYPE        Type;
 572 
 573 
 574     /* Get the object type */
 575 
 576     Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes);
 577     if (Type == ACPI_TYPE_NOT_FOUND)
 578     {
 579         AcpiOsPrintf ("Invalid or unsupported argument\n");
 580         return (AE_OK);
 581     }
 582 
 583     AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT);
 584     AcpiOsPrintf (
 585         "Objects of type [%s] defined in the current ACPI Namespace:\n",
 586         AcpiUtGetTypeName (Type));
 587 
 588     AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT);
 589 
 590     Info.Count = 0;
 591     Info.OwnerId = ACPI_OWNER_ID_MAX;
 592     Info.DebugLevel = ACPI_UINT32_MAX;
 593     Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
 594 
 595     /* Walk the namespace from the root */
 596 
 597     (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 598                 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL);
 599 
 600     AcpiOsPrintf (
 601         "\nFound %u objects of type [%s] in the current ACPI Namespace\n",
 602         Info.Count, AcpiUtGetTypeName (Type));
 603 
 604     AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT);
 605     return (AE_OK);
 606 }
 607 
 608 
 609 /*******************************************************************************
 610  *
 611  * FUNCTION:    AcpiDbIntegrityWalk
 612  *
 613  * PARAMETERS:  Callback from WalkNamespace
 614  *
 615  * RETURN:      Status
 616  *
 617  * DESCRIPTION: Examine one NS node for valid values.
 618  *
 619  ******************************************************************************/
 620 
 621 static ACPI_STATUS
 622 AcpiDbIntegrityWalk (
 623     ACPI_HANDLE             ObjHandle,
 624     UINT32                  NestingLevel,
 625     void                    *Context,
 626     void                    **ReturnValue)
 627 {
 628     ACPI_INTEGRITY_INFO     *Info = (ACPI_INTEGRITY_INFO *) Context;
 629     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
 630     ACPI_OPERAND_OBJECT     *Object;
 631     BOOLEAN                 Alias = TRUE;
 632 
 633 
 634     Info->Nodes++;
 635 
 636     /* Verify the NS node, and dereference aliases */
 637 
 638     while (Alias)
 639     {
 640         if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
 641         {
 642             AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n",
 643                 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node),
 644                 ACPI_DESC_TYPE_NAMED);
 645             return (AE_OK);
 646         }
 647 
 648         if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS)  ||
 649             (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS))
 650         {
 651             Node = (ACPI_NAMESPACE_NODE *) Node->Object;
 652         }
 653         else
 654         {
 655             Alias = FALSE;
 656         }
 657     }
 658 
 659     if (Node->Type > ACPI_TYPE_LOCAL_MAX)
 660     {
 661         AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n",
 662             Node, Node->Type);
 663         return (AE_OK);
 664     }
 665 
 666     if (!AcpiUtValidAcpiName (Node->Name.Integer))
 667     {
 668         AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node);
 669         return (AE_OK);
 670     }
 671 
 672     Object = AcpiNsGetAttachedObject (Node);
 673     if (Object)
 674     {
 675         Info->Objects++;
 676         if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND)
 677         {
 678             AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n",
 679                 Object, AcpiUtGetDescriptorName (Object));
 680         }
 681     }
 682 
 683     return (AE_OK);
 684 }
 685 
 686 
 687 /*******************************************************************************
 688  *
 689  * FUNCTION:    AcpiDbCheckIntegrity
 690  *
 691  * PARAMETERS:  None
 692  *
 693  * RETURN:      None
 694  *
 695  * DESCRIPTION: Check entire namespace for data structure integrity
 696  *
 697  ******************************************************************************/
 698 
 699 void
 700 AcpiDbCheckIntegrity (
 701     void)
 702 {
 703     ACPI_INTEGRITY_INFO     Info = {0,0};
 704 
 705     /* Search all nodes in namespace */
 706 
 707     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 708                     AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL);
 709 
 710     AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n",
 711         Info.Nodes, Info.Objects);
 712 }
 713 
 714 
 715 /*******************************************************************************
 716  *
 717  * FUNCTION:    AcpiDbWalkForReferences
 718  *
 719  * PARAMETERS:  Callback from WalkNamespace
 720  *
 721  * RETURN:      Status
 722  *
 723  * DESCRIPTION: Check if this namespace object refers to the target object
 724  *              that is passed in as the context value.
 725  *
 726  * Note: Currently doesn't check subobjects within the Node's object
 727  *
 728  ******************************************************************************/
 729 
 730 static ACPI_STATUS
 731 AcpiDbWalkForReferences (
 732     ACPI_HANDLE             ObjHandle,
 733     UINT32                  NestingLevel,
 734     void                    *Context,
 735     void                    **ReturnValue)
 736 {
 737     ACPI_OPERAND_OBJECT     *ObjDesc = (ACPI_OPERAND_OBJECT  *) Context;
 738     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
 739 
 740 
 741     /* Check for match against the namespace node itself */
 742 
 743     if (Node == (void *) ObjDesc)
 744     {
 745         AcpiOsPrintf ("Object is a Node [%4.4s]\n",
 746             AcpiUtGetNodeName (Node));
 747     }
 748 
 749     /* Check for match against the object attached to the node */
 750 
 751     if (AcpiNsGetAttachedObject (Node) == ObjDesc)
 752     {
 753         AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n",
 754             Node, AcpiUtGetNodeName (Node));
 755     }
 756 
 757     return (AE_OK);
 758 }
 759 
 760 
 761 /*******************************************************************************
 762  *
 763  * FUNCTION:    AcpiDbFindReferences
 764  *
 765  * PARAMETERS:  ObjectArg       - String with hex value of the object
 766  *
 767  * RETURN:      None
 768  *
 769  * DESCRIPTION: Search namespace for all references to the input object
 770  *
 771  ******************************************************************************/
 772 
 773 void
 774 AcpiDbFindReferences (
 775     char                    *ObjectArg)
 776 {
 777     ACPI_OPERAND_OBJECT     *ObjDesc;
 778 
 779 
 780     /* Convert string to object pointer */
 781 
 782     ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16));
 783 
 784     /* Search all nodes in namespace */
 785 
 786     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 787                     AcpiDbWalkForReferences, NULL, (void *) ObjDesc, NULL);
 788 }
 789 
 790 
 791 /*******************************************************************************
 792  *
 793  * FUNCTION:    AcpiDbBusWalk
 794  *
 795  * PARAMETERS:  Callback from WalkNamespace
 796  *
 797  * RETURN:      Status
 798  *
 799  * DESCRIPTION: Display info about device objects that have a corresponding
 800  *              _PRT method.
 801  *
 802  ******************************************************************************/
 803 
 804 static ACPI_STATUS
 805 AcpiDbBusWalk (
 806     ACPI_HANDLE             ObjHandle,
 807     UINT32                  NestingLevel,
 808     void                    *Context,
 809     void                    **ReturnValue)
 810 {
 811     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
 812     ACPI_STATUS             Status;
 813     ACPI_BUFFER             Buffer;
 814     ACPI_NAMESPACE_NODE     *TempNode;
 815     ACPI_DEVICE_INFO        *Info;
 816     UINT32                  i;
 817 
 818 
 819     if ((Node->Type != ACPI_TYPE_DEVICE) &&
 820         (Node->Type != ACPI_TYPE_PROCESSOR))
 821     {
 822         return (AE_OK);
 823     }
 824 
 825     /* Exit if there is no _PRT under this device */
 826 
 827     Status = AcpiGetHandle (Node, METHOD_NAME__PRT,
 828                 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode));
 829     if (ACPI_FAILURE (Status))
 830     {
 831         return (AE_OK);
 832     }
 833 
 834     /* Get the full path to this device object */
 835 
 836     Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
 837     Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
 838     if (ACPI_FAILURE (Status))
 839     {
 840         AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle);
 841         return (AE_OK);
 842     }
 843 
 844     Status = AcpiGetObjectInfo (ObjHandle, &Info);
 845     if (ACPI_FAILURE (Status))
 846     {
 847         return (AE_OK);
 848     }
 849 
 850     /* Display the full path */
 851 
 852     AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type);
 853     ACPI_FREE (Buffer.Pointer);
 854 
 855     if (Info->Flags & ACPI_PCI_ROOT_BRIDGE)
 856     {
 857         AcpiOsPrintf ("  - Is PCI Root Bridge");
 858     }
 859     AcpiOsPrintf ("\n");
 860 
 861     /* _PRT info */
 862 
 863     AcpiOsPrintf ("_PRT: %p\n", TempNode);
 864 
 865     /* Dump _ADR, _HID, _UID, _CID */
 866 
 867     if (Info->Valid & ACPI_VALID_ADR)
 868     {
 869         AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", ACPI_FORMAT_UINT64 (Info->Address));
 870     }
 871     else
 872     {
 873         AcpiOsPrintf ("_ADR: <Not Present>\n");
 874     }
 875 
 876     if (Info->Valid & ACPI_VALID_HID)
 877     {
 878         AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String);
 879     }
 880     else
 881     {
 882         AcpiOsPrintf ("_HID: <Not Present>\n");
 883     }
 884 
 885     if (Info->Valid & ACPI_VALID_UID)
 886     {
 887         AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String);
 888     }
 889     else
 890     {
 891         AcpiOsPrintf ("_UID: <Not Present>\n");
 892     }
 893 
 894     if (Info->Valid & ACPI_VALID_CID)
 895     {
 896         for (i = 0; i < Info->CompatibleIdList.Count; i++)
 897         {
 898             AcpiOsPrintf ("_CID: %s\n",
 899                 Info->CompatibleIdList.Ids[i].String);
 900         }
 901     }
 902     else
 903     {
 904         AcpiOsPrintf ("_CID: <Not Present>\n");
 905     }
 906 
 907     ACPI_FREE (Info);
 908     return (AE_OK);
 909 }
 910 
 911 
 912 /*******************************************************************************
 913  *
 914  * FUNCTION:    AcpiDbGetBusInfo
 915  *
 916  * PARAMETERS:  None
 917  *
 918  * RETURN:      None
 919  *
 920  * DESCRIPTION: Display info about system busses.
 921  *
 922  ******************************************************************************/
 923 
 924 void
 925 AcpiDbGetBusInfo (
 926     void)
 927 {
 928     /* Search all nodes in namespace */
 929 
 930     (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
 931                     AcpiDbBusWalk, NULL, NULL, NULL);
 932 }
 933 
 934 #endif /* ACPI_DEBUGGER */