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