1/*******************************************************************************
2 *
3 * Module Name: dbnames - Debugger commands for the acpi namespace
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, 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
51ACPI_MODULE_NAME("dbnames")
52
53/* Local prototypes */
54static acpi_status
55acpi_db_walk_and_match_name(acpi_handle obj_handle,
56			    u32 nesting_level,
57			    void *context, void **return_value);
58
59static acpi_status
60acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
61				  u32 nesting_level,
62				  void *context, void **return_value);
63
64static acpi_status
65acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
66				  u32 nesting_level,
67				  void *context, void **return_value);
68
69static acpi_status
70acpi_db_walk_for_object_counts(acpi_handle obj_handle,
71			       u32 nesting_level,
72			       void *context, void **return_value);
73
74static acpi_status
75acpi_db_integrity_walk(acpi_handle obj_handle,
76		       u32 nesting_level, void *context, void **return_value);
77
78static acpi_status
79acpi_db_walk_for_references(acpi_handle obj_handle,
80			    u32 nesting_level,
81			    void *context, void **return_value);
82
83static acpi_status
84acpi_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 */
91static 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
136void 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
187error_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
207void 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
253void 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
282void 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
320static acpi_status
321acpi_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
381acpi_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
423static acpi_status
424acpi_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_external_pathname(node);
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
489void 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
515static acpi_status
516acpi_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
546static acpi_status
547acpi_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
589acpi_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		/* Walk the namespace from the root */
604
605		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
606					  ACPI_UINT32_MAX,
607					  acpi_db_walk_for_object_counts, NULL,
608					  (void *)object_info, NULL);
609
610		acpi_os_printf("\nSummary of namespace objects:\n\n");
611
612		for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
613			acpi_os_printf("%8u %s\n", object_info->types[i],
614				       acpi_ut_get_type_name(i));
615
616			total_objects += object_info->types[i];
617		}
618
619		acpi_os_printf("\n%8u Total namespace objects\n\n",
620			       total_objects);
621
622		ACPI_FREE(object_info);
623		return (AE_OK);
624	}
625
626	/* Get the object type */
627
628	type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
629	if (type == ACPI_TYPE_NOT_FOUND) {
630		acpi_os_printf("Invalid or unsupported argument\n");
631		return (AE_OK);
632	}
633
634	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
635	acpi_os_printf
636	    ("Objects of type [%s] defined in the current ACPI Namespace:\n",
637	     acpi_ut_get_type_name(type));
638
639	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
640
641	info.count = 0;
642	info.owner_id = ACPI_OWNER_ID_MAX;
643	info.debug_level = ACPI_UINT32_MAX;
644	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;
645
646	/* Walk the namespace from the root */
647
648	(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
649				  acpi_db_walk_for_specific_objects, NULL,
650				  (void *)&info, NULL);
651
652	acpi_os_printf
653	    ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
654	     info.count, acpi_ut_get_type_name(type));
655
656	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
657	return (AE_OK);
658}
659
660/*******************************************************************************
661 *
662 * FUNCTION:    acpi_db_integrity_walk
663 *
664 * PARAMETERS:  Callback from walk_namespace
665 *
666 * RETURN:      Status
667 *
668 * DESCRIPTION: Examine one NS node for valid values.
669 *
670 ******************************************************************************/
671
672static acpi_status
673acpi_db_integrity_walk(acpi_handle obj_handle,
674		       u32 nesting_level, void *context, void **return_value)
675{
676	struct acpi_integrity_info *info =
677	    (struct acpi_integrity_info *)context;
678	struct acpi_namespace_node *node =
679	    (struct acpi_namespace_node *)obj_handle;
680	union acpi_operand_object *object;
681	u8 alias = TRUE;
682
683	info->nodes++;
684
685	/* Verify the NS node, and dereference aliases */
686
687	while (alias) {
688		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
689			acpi_os_printf
690			    ("Invalid Descriptor Type for Node %p [%s] - "
691			     "is %2.2X should be %2.2X\n", node,
692			     acpi_ut_get_descriptor_name(node),
693			     ACPI_GET_DESCRIPTOR_TYPE(node),
694			     ACPI_DESC_TYPE_NAMED);
695			return (AE_OK);
696		}
697
698		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
699		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
700			node = (struct acpi_namespace_node *)node->object;
701		} else {
702			alias = FALSE;
703		}
704	}
705
706	if (node->type > ACPI_TYPE_LOCAL_MAX) {
707		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
708			       node, node->type);
709		return (AE_OK);
710	}
711
712	if (!acpi_ut_valid_acpi_name(node->name.ascii)) {
713		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
714		return (AE_OK);
715	}
716
717	object = acpi_ns_get_attached_object(node);
718	if (object) {
719		info->objects++;
720		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
721			acpi_os_printf
722			    ("Invalid Descriptor Type for Object %p [%s]\n",
723			     object, acpi_ut_get_descriptor_name(object));
724		}
725	}
726
727	return (AE_OK);
728}
729
730/*******************************************************************************
731 *
732 * FUNCTION:    acpi_db_check_integrity
733 *
734 * PARAMETERS:  None
735 *
736 * RETURN:      None
737 *
738 * DESCRIPTION: Check entire namespace for data structure integrity
739 *
740 ******************************************************************************/
741
742void acpi_db_check_integrity(void)
743{
744	struct acpi_integrity_info info = { 0, 0 };
745
746	/* Search all nodes in namespace */
747
748	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
749				  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
750				  (void *)&info, NULL);
751
752	acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
753		       info.nodes, info.objects);
754}
755
756/*******************************************************************************
757 *
758 * FUNCTION:    acpi_db_walk_for_references
759 *
760 * PARAMETERS:  Callback from walk_namespace
761 *
762 * RETURN:      Status
763 *
764 * DESCRIPTION: Check if this namespace object refers to the target object
765 *              that is passed in as the context value.
766 *
767 * Note: Currently doesn't check subobjects within the Node's object
768 *
769 ******************************************************************************/
770
771static acpi_status
772acpi_db_walk_for_references(acpi_handle obj_handle,
773			    u32 nesting_level,
774			    void *context, void **return_value)
775{
776	union acpi_operand_object *obj_desc =
777	    (union acpi_operand_object *)context;
778	struct acpi_namespace_node *node =
779	    (struct acpi_namespace_node *)obj_handle;
780
781	/* Check for match against the namespace node itself */
782
783	if (node == (void *)obj_desc) {
784		acpi_os_printf("Object is a Node [%4.4s]\n",
785			       acpi_ut_get_node_name(node));
786	}
787
788	/* Check for match against the object attached to the node */
789
790	if (acpi_ns_get_attached_object(node) == obj_desc) {
791		acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
792			       node, acpi_ut_get_node_name(node));
793	}
794
795	return (AE_OK);
796}
797
798/*******************************************************************************
799 *
800 * FUNCTION:    acpi_db_find_references
801 *
802 * PARAMETERS:  object_arg      - String with hex value of the object
803 *
804 * RETURN:      None
805 *
806 * DESCRIPTION: Search namespace for all references to the input object
807 *
808 ******************************************************************************/
809
810void acpi_db_find_references(char *object_arg)
811{
812	union acpi_operand_object *obj_desc;
813	acpi_size address;
814
815	/* Convert string to object pointer */
816
817	address = strtoul(object_arg, NULL, 16);
818	obj_desc = ACPI_TO_POINTER(address);
819
820	/* Search all nodes in namespace */
821
822	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
823				  ACPI_UINT32_MAX, acpi_db_walk_for_references,
824				  NULL, (void *)obj_desc, NULL);
825}
826
827/*******************************************************************************
828 *
829 * FUNCTION:    acpi_db_bus_walk
830 *
831 * PARAMETERS:  Callback from walk_namespace
832 *
833 * RETURN:      Status
834 *
835 * DESCRIPTION: Display info about device objects that have a corresponding
836 *              _PRT method.
837 *
838 ******************************************************************************/
839
840static acpi_status
841acpi_db_bus_walk(acpi_handle obj_handle,
842		 u32 nesting_level, void *context, void **return_value)
843{
844	struct acpi_namespace_node *node =
845	    (struct acpi_namespace_node *)obj_handle;
846	acpi_status status;
847	struct acpi_buffer buffer;
848	struct acpi_namespace_node *temp_node;
849	struct acpi_device_info *info;
850	u32 i;
851
852	if ((node->type != ACPI_TYPE_DEVICE) &&
853	    (node->type != ACPI_TYPE_PROCESSOR)) {
854		return (AE_OK);
855	}
856
857	/* Exit if there is no _PRT under this device */
858
859	status = acpi_get_handle(node, METHOD_NAME__PRT,
860				 ACPI_CAST_PTR(acpi_handle, &temp_node));
861	if (ACPI_FAILURE(status)) {
862		return (AE_OK);
863	}
864
865	/* Get the full path to this device object */
866
867	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
868	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
869	if (ACPI_FAILURE(status)) {
870		acpi_os_printf("Could Not get pathname for object %p\n",
871			       obj_handle);
872		return (AE_OK);
873	}
874
875	status = acpi_get_object_info(obj_handle, &info);
876	if (ACPI_FAILURE(status)) {
877		return (AE_OK);
878	}
879
880	/* Display the full path */
881
882	acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
883	ACPI_FREE(buffer.pointer);
884
885	if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
886		acpi_os_printf(" - Is PCI Root Bridge");
887	}
888	acpi_os_printf("\n");
889
890	/* _PRT info */
891
892	acpi_os_printf("_PRT: %p\n", temp_node);
893
894	/* Dump _ADR, _HID, _UID, _CID */
895
896	if (info->valid & ACPI_VALID_ADR) {
897		acpi_os_printf("_ADR: %8.8X%8.8X\n",
898			       ACPI_FORMAT_UINT64(info->address));
899	} else {
900		acpi_os_printf("_ADR: <Not Present>\n");
901	}
902
903	if (info->valid & ACPI_VALID_HID) {
904		acpi_os_printf("_HID: %s\n", info->hardware_id.string);
905	} else {
906		acpi_os_printf("_HID: <Not Present>\n");
907	}
908
909	if (info->valid & ACPI_VALID_UID) {
910		acpi_os_printf("_UID: %s\n", info->unique_id.string);
911	} else {
912		acpi_os_printf("_UID: <Not Present>\n");
913	}
914
915	if (info->valid & ACPI_VALID_CID) {
916		for (i = 0; i < info->compatible_id_list.count; i++) {
917			acpi_os_printf("_CID: %s\n",
918				       info->compatible_id_list.ids[i].string);
919		}
920	} else {
921		acpi_os_printf("_CID: <Not Present>\n");
922	}
923
924	ACPI_FREE(info);
925	return (AE_OK);
926}
927
928/*******************************************************************************
929 *
930 * FUNCTION:    acpi_db_get_bus_info
931 *
932 * PARAMETERS:  None
933 *
934 * RETURN:      None
935 *
936 * DESCRIPTION: Display info about system busses.
937 *
938 ******************************************************************************/
939
940void acpi_db_get_bus_info(void)
941{
942	/* Search all nodes in namespace */
943
944	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
945				  ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
946				  NULL);
947}
948