// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/*******************************************************************************
 *
 * Module Name: dbnames - Debugger commands for the acpi namespace
 *
 ******************************************************************************/

#include <acpi/acpi.h>
#include "accommon.h"
#include "acnamesp.h"
#include "acdebug.h"
#include "acpredef.h"

#define _COMPONENT          ACPI_CA_DEBUGGER
ACPI_MODULE_NAME("dbnames")

/* Local prototypes */
static acpi_status
acpi_db_walk_and_match_name(acpi_handle obj_handle,
			    u32 nesting_level,
			    void *context, void **return_value);

static acpi_status
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
				  u32 nesting_level,
				  void *context, void **return_value);

static acpi_status
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
				  u32 nesting_level,
				  void *context, void **return_value);

static acpi_status
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
			       u32 nesting_level,
			       void *context, void **return_value);

static acpi_status
acpi_db_integrity_walk(acpi_handle obj_handle,
		       u32 nesting_level, void *context, void **return_value);

static acpi_status
acpi_db_walk_for_references(acpi_handle obj_handle,
			    u32 nesting_level,
			    void *context, void **return_value);

static acpi_status
acpi_db_bus_walk(acpi_handle obj_handle,
		 u32 nesting_level, void *context, void **return_value);

/*
 * Arguments for the Objects command
 * These object types map directly to the ACPI_TYPES
 */
static struct acpi_db_argument_info acpi_db_object_types[] = {
	{"ANY"},
	{"INTEGERS"},
	{"STRINGS"},
	{"BUFFERS"},
	{"PACKAGES"},
	{"FIELDS"},
	{"DEVICES"},
	{"EVENTS"},
	{"METHODS"},
	{"MUTEXES"},
	{"REGIONS"},
	{"POWERRESOURCES"},
	{"PROCESSORS"},
	{"THERMALZONES"},
	{"BUFFERFIELDS"},
	{"DDBHANDLES"},
	{"DEBUG"},
	{"REGIONFIELDS"},
	{"BANKFIELDS"},
	{"INDEXFIELDS"},
	{"REFERENCES"},
	{"ALIASES"},
	{"METHODALIASES"},
	{"NOTIFY"},
	{"ADDRESSHANDLER"},
	{"RESOURCE"},
	{"RESOURCEFIELD"},
	{"SCOPES"},
	{NULL}			/* Must be null terminated */
};

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_set_scope
 *
 * PARAMETERS:  name                - New scope path
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Set the "current scope" as maintained by this utility.
 *              The scope is used as a prefix to ACPI paths.
 *
 ******************************************************************************/

void acpi_db_set_scope(char *name)
{
	acpi_status status;
	struct acpi_namespace_node *node;

	if (!name || name[0] == 0) {
		acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf);
		return;
	}

	acpi_db_prep_namestring(name);

	if (ACPI_IS_ROOT_PREFIX(name[0])) {

		/* Validate new scope from the root */

		status = acpi_ns_get_node(acpi_gbl_root_node, name,
					  ACPI_NS_NO_UPSEARCH, &node);
		if (ACPI_FAILURE(status)) {
			goto error_exit;
		}

		acpi_gbl_db_scope_buf[0] = 0;
	} else {
		/* Validate new scope relative to old scope */

		status = acpi_ns_get_node(acpi_gbl_db_scope_node, name,
					  ACPI_NS_NO_UPSEARCH, &node);
		if (ACPI_FAILURE(status)) {
			goto error_exit;
		}
	}

	/* Build the final pathname */

	if (acpi_ut_safe_strcat
	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) {
		status = AE_BUFFER_OVERFLOW;
		goto error_exit;
	}

	if (acpi_ut_safe_strcat
	    (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) {
		status = AE_BUFFER_OVERFLOW;
		goto error_exit;
	}

	acpi_gbl_db_scope_node = node;
	acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf);
	return;

error_exit:

	acpi_os_printf("Could not attach scope: %s, %s\n",
		       name, acpi_format_exception(status));
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_dump_namespace
 *
 * PARAMETERS:  start_arg       - Node to begin namespace dump
 *              depth_arg       - Maximum tree depth to be dumped
 *
 * RETURN:      None
 *
 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed
 *              with type and other information.
 *
 ******************************************************************************/

void acpi_db_dump_namespace(char *start_arg, char *depth_arg)
{
	acpi_handle subtree_entry = acpi_gbl_root_node;
	u32 max_depth = ACPI_UINT32_MAX;

	/* No argument given, just start at the root and dump entire namespace */

	if (start_arg) {
		subtree_entry = acpi_db_convert_to_node(start_arg);
		if (!subtree_entry) {
			return;
		}

		/* Now we can check for the depth argument */

		if (depth_arg) {
			max_depth = strtoul(depth_arg, NULL, 0);
		}
	}

	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);

	if (((struct acpi_namespace_node *)subtree_entry)->parent) {
		acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n",
			       ((struct acpi_namespace_node *)subtree_entry)->
			       name.ascii, subtree_entry);
	} else {
		acpi_os_printf("ACPI Namespace (from %s):\n",
			       ACPI_NAMESPACE_ROOT);
	}

	/* Display the subtree */

	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
			     ACPI_OWNER_ID_MAX, subtree_entry);
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_dump_namespace_paths
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Dump entire namespace with full object pathnames and object
 *              type information. Alternative to "namespace" command.
 *
 ******************************************************************************/

void acpi_db_dump_namespace_paths(void)
{

	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
	acpi_os_printf("ACPI Namespace (from root):\n");

	/* Display the entire namespace */

	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
	acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY,
				  ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX,
				  acpi_gbl_root_node);

	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_dump_namespace_by_owner
 *
 * PARAMETERS:  owner_arg       - Owner ID whose nodes will be displayed
 *              depth_arg       - Maximum tree depth to be dumped
 *
 * RETURN:      None
 *
 * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id.
 *
 ******************************************************************************/

void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg)
{
	acpi_handle subtree_entry = acpi_gbl_root_node;
	u32 max_depth = ACPI_UINT32_MAX;
	acpi_owner_id owner_id;

	owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0);

	/* Now we can check for the depth argument */

	if (depth_arg) {
		max_depth = strtoul(depth_arg, NULL, 0);
	}

	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
	acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id);

	/* Display the subtree */

	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
	acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth,
			     owner_id, subtree_entry);
	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_and_match_name
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards
 *              are supported -- '?' matches any character.
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_and_match_name(acpi_handle obj_handle,
			    u32 nesting_level,
			    void *context, void **return_value)
{
	acpi_status status;
	char *requested_name = (char *)context;
	u32 i;
	struct acpi_buffer buffer;
	struct acpi_walk_info info;

	/* Check for a name match */

	for (i = 0; i < 4; i++) {

		/* Wildcard support */

		if ((requested_name[i] != '?') &&
		    (requested_name[i] != ((struct acpi_namespace_node *)
					   obj_handle)->name.ascii[i])) {

			/* No match, just exit */

			return (AE_OK);
		}
	}

	/* Get the full pathname to this object */

	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("Could Not get pathname for object %p\n",
			       obj_handle);
	} else {
		info.count = 0;
		info.owner_id = ACPI_OWNER_ID_MAX;
		info.debug_level = ACPI_UINT32_MAX;
		info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;

		acpi_os_printf("%32s", (char *)buffer.pointer);
		(void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info,
					      NULL);
		ACPI_FREE(buffer.pointer);
	}

	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_find_name_in_namespace
 *
 * PARAMETERS:  name_arg        - The 4-character ACPI name to find.
 *                                wildcards are supported.
 *
 * RETURN:      None
 *
 * DESCRIPTION: Search the namespace for a given name (with wildcards)
 *
 ******************************************************************************/

acpi_status acpi_db_find_name_in_namespace(char *name_arg)
{
	char acpi_name[5] = "____";
	char *acpi_name_ptr = acpi_name;

	if (strlen(name_arg) > ACPI_NAME_SIZE) {
		acpi_os_printf("Name must be no longer than 4 characters\n");
		return (AE_OK);
	}

	/* Pad out name with underscores as necessary to create a 4-char name */

	acpi_ut_strupr(name_arg);
	while (*name_arg) {
		*acpi_name_ptr = *name_arg;
		acpi_name_ptr++;
		name_arg++;
	}

	/* Walk the namespace from the root */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX, acpi_db_walk_and_match_name,
				  NULL, acpi_name, NULL);

	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_for_predefined_names
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Detect and display predefined ACPI names (names that start with
 *              an underscore)
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_predefined_names(acpi_handle obj_handle,
				  u32 nesting_level,
				  void *context, void **return_value)
{
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;
	u32 *count = (u32 *)context;
	const union acpi_predefined_info *predefined;
	const union acpi_predefined_info *package = NULL;
	char *pathname;
	char string_buffer[48];

	predefined = acpi_ut_match_predefined_method(node->name.ascii);
	if (!predefined) {
		return (AE_OK);
	}

	pathname = acpi_ns_get_normalized_pathname(node, TRUE);
	if (!pathname) {
		return (AE_OK);
	}

	/* If method returns a package, the info is in the next table entry */

	if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) {
		package = predefined + 1;
	}

	acpi_ut_get_expected_return_types(string_buffer,
					  predefined->info.expected_btypes);

	acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname,
		       METHOD_GET_ARG_COUNT(predefined->info.argument_list),
		       string_buffer);

	if (package) {
		acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)",
			       package->ret_info.type,
			       package->ret_info.object_type1,
			       package->ret_info.count1);
	}

	acpi_os_printf("\n");

	/* Check that the declared argument count matches the ACPI spec */

	acpi_ns_check_acpi_compliance(pathname, node, predefined);

	ACPI_FREE(pathname);
	(*count)++;
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_check_predefined_names
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Validate all predefined names in the namespace
 *
 ******************************************************************************/

void acpi_db_check_predefined_names(void)
{
	u32 count = 0;

	/* Search all nodes in namespace */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX,
				  acpi_db_walk_for_predefined_names, NULL,
				  (void *)&count, NULL);

	acpi_os_printf("Found %u predefined names in the namespace\n", count);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_for_object_counts
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Display short info about objects in the namespace
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_object_counts(acpi_handle obj_handle,
			       u32 nesting_level,
			       void *context, void **return_value)
{
	struct acpi_object_info *info = (struct acpi_object_info *)context;
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;

	if (node->type > ACPI_TYPE_NS_NODE_MAX) {
		acpi_os_printf("[%4.4s]: Unknown object type %X\n",
			       node->name.ascii, node->type);
	} else {
		info->types[node->type]++;
	}

	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_for_specific_objects
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Display short info about objects in the namespace
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_specific_objects(acpi_handle obj_handle,
				  u32 nesting_level,
				  void *context, void **return_value)
{
	struct acpi_walk_info *info = (struct acpi_walk_info *)context;
	struct acpi_buffer buffer;
	acpi_status status;

	info->count++;

	/* Get and display the full pathname to this object */

	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("Could Not get pathname for object %p\n",
			       obj_handle);
		return (AE_OK);
	}

	acpi_os_printf("%32s", (char *)buffer.pointer);
	ACPI_FREE(buffer.pointer);

	/* Dump short info about the object */

	(void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL);
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_display_objects
 *
 * PARAMETERS:  obj_type_arg        - Type of object to display
 *              display_count_arg   - Max depth to display
 *
 * RETURN:      None
 *
 * DESCRIPTION: Display objects in the namespace of the requested type
 *
 ******************************************************************************/

acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg)
{
	struct acpi_walk_info info;
	acpi_object_type type;
	struct acpi_object_info *object_info;
	u32 i;
	u32 total_objects = 0;

	/* No argument means display summary/count of all object types */

	if (!obj_type_arg) {
		object_info =
		    ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info));

		/* Walk the namespace from the root */

		(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
					  ACPI_UINT32_MAX,
					  acpi_db_walk_for_object_counts, NULL,
					  (void *)object_info, NULL);

		acpi_os_printf("\nSummary of namespace objects:\n\n");

		for (i = 0; i < ACPI_TOTAL_TYPES; i++) {
			acpi_os_printf("%8u %s\n", object_info->types[i],
				       acpi_ut_get_type_name(i));

			total_objects += object_info->types[i];
		}

		acpi_os_printf("\n%8u Total namespace objects\n\n",
			       total_objects);

		ACPI_FREE(object_info);
		return (AE_OK);
	}

	/* Get the object type */

	type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types);
	if (type == ACPI_TYPE_NOT_FOUND) {
		acpi_os_printf("Invalid or unsupported argument\n");
		return (AE_OK);
	}

	acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT);
	acpi_os_printf
	    ("Objects of type [%s] defined in the current ACPI Namespace:\n",
	     acpi_ut_get_type_name(type));

	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);

	info.count = 0;
	info.owner_id = ACPI_OWNER_ID_MAX;
	info.debug_level = ACPI_UINT32_MAX;
	info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT;

	/* Walk the namespace from the root */

	(void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
				  acpi_db_walk_for_specific_objects, NULL,
				  (void *)&info, NULL);

	acpi_os_printf
	    ("\nFound %u objects of type [%s] in the current ACPI Namespace\n",
	     info.count, acpi_ut_get_type_name(type));

	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_integrity_walk
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Examine one NS node for valid values.
 *
 ******************************************************************************/

static acpi_status
acpi_db_integrity_walk(acpi_handle obj_handle,
		       u32 nesting_level, void *context, void **return_value)
{
	struct acpi_integrity_info *info =
	    (struct acpi_integrity_info *)context;
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;
	union acpi_operand_object *object;
	u8 alias = TRUE;

	info->nodes++;

	/* Verify the NS node, and dereference aliases */

	while (alias) {
		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
			acpi_os_printf
			    ("Invalid Descriptor Type for Node %p [%s] - "
			     "is %2.2X should be %2.2X\n", node,
			     acpi_ut_get_descriptor_name(node),
			     ACPI_GET_DESCRIPTOR_TYPE(node),
			     ACPI_DESC_TYPE_NAMED);
			return (AE_OK);
		}

		if ((node->type == ACPI_TYPE_LOCAL_ALIAS) ||
		    (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
			node = (struct acpi_namespace_node *)node->object;
		} else {
			alias = FALSE;
		}
	}

	if (node->type > ACPI_TYPE_LOCAL_MAX) {
		acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n",
			       node, node->type);
		return (AE_OK);
	}

	if (!acpi_ut_valid_nameseg(node->name.ascii)) {
		acpi_os_printf("Invalid AcpiName for Node %p\n", node);
		return (AE_OK);
	}

	object = acpi_ns_get_attached_object(node);
	if (object) {
		info->objects++;
		if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) {
			acpi_os_printf
			    ("Invalid Descriptor Type for Object %p [%s]\n",
			     object, acpi_ut_get_descriptor_name(object));
		}
	}

	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_check_integrity
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Check entire namespace for data structure integrity
 *
 ******************************************************************************/

void acpi_db_check_integrity(void)
{
	struct acpi_integrity_info info = { 0, 0 };

	/* Search all nodes in namespace */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL,
				  (void *)&info, NULL);

	acpi_os_printf("Verified %u namespace nodes with %u Objects\n",
		       info.nodes, info.objects);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_walk_for_references
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Check if this namespace object refers to the target object
 *              that is passed in as the context value.
 *
 * Note: Currently doesn't check subobjects within the Node's object
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_references(acpi_handle obj_handle,
			    u32 nesting_level,
			    void *context, void **return_value)
{
	union acpi_operand_object *obj_desc =
	    (union acpi_operand_object *)context;
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;

	/* Check for match against the namespace node itself */

	if (node == (void *)obj_desc) {
		acpi_os_printf("Object is a Node [%4.4s]\n",
			       acpi_ut_get_node_name(node));
	}

	/* Check for match against the object attached to the node */

	if (acpi_ns_get_attached_object(node) == obj_desc) {
		acpi_os_printf("Reference at Node->Object %p [%4.4s]\n",
			       node, acpi_ut_get_node_name(node));
	}

	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_find_references
 *
 * PARAMETERS:  object_arg      - String with hex value of the object
 *
 * RETURN:      None
 *
 * DESCRIPTION: Search namespace for all references to the input object
 *
 ******************************************************************************/

void acpi_db_find_references(char *object_arg)
{
	union acpi_operand_object *obj_desc;
	acpi_size address;

	/* Convert string to object pointer */

	address = strtoul(object_arg, NULL, 16);
	obj_desc = ACPI_TO_POINTER(address);

	/* Search all nodes in namespace */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX, acpi_db_walk_for_references,
				  NULL, (void *)obj_desc, NULL);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_bus_walk
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Display info about device objects that have a corresponding
 *              _PRT method.
 *
 ******************************************************************************/

static acpi_status
acpi_db_bus_walk(acpi_handle obj_handle,
		 u32 nesting_level, void *context, void **return_value)
{
	struct acpi_namespace_node *node =
	    (struct acpi_namespace_node *)obj_handle;
	acpi_status status;
	struct acpi_buffer buffer;
	struct acpi_namespace_node *temp_node;
	struct acpi_device_info *info;
	u32 i;

	if ((node->type != ACPI_TYPE_DEVICE) &&
	    (node->type != ACPI_TYPE_PROCESSOR)) {
		return (AE_OK);
	}

	/* Exit if there is no _PRT under this device */

	status = acpi_get_handle(node, METHOD_NAME__PRT,
				 ACPI_CAST_PTR(acpi_handle, &temp_node));
	if (ACPI_FAILURE(status)) {
		return (AE_OK);
	}

	/* Get the full path to this device object */

	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
	status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE);
	if (ACPI_FAILURE(status)) {
		acpi_os_printf("Could Not get pathname for object %p\n",
			       obj_handle);
		return (AE_OK);
	}

	status = acpi_get_object_info(obj_handle, &info);
	if (ACPI_FAILURE(status)) {
		return (AE_OK);
	}

	/* Display the full path */

	acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type);
	ACPI_FREE(buffer.pointer);

	if (info->flags & ACPI_PCI_ROOT_BRIDGE) {
		acpi_os_printf(" - Is PCI Root Bridge");
	}
	acpi_os_printf("\n");

	/* _PRT info */

	acpi_os_printf("_PRT: %p\n", temp_node);

	/* Dump _ADR, _HID, _UID, _CID */

	if (info->valid & ACPI_VALID_ADR) {
		acpi_os_printf("_ADR: %8.8X%8.8X\n",
			       ACPI_FORMAT_UINT64(info->address));
	} else {
		acpi_os_printf("_ADR: <Not Present>\n");
	}

	if (info->valid & ACPI_VALID_HID) {
		acpi_os_printf("_HID: %s\n", info->hardware_id.string);
	} else {
		acpi_os_printf("_HID: <Not Present>\n");
	}

	if (info->valid & ACPI_VALID_UID) {
		acpi_os_printf("_UID: %s\n", info->unique_id.string);
	} else {
		acpi_os_printf("_UID: <Not Present>\n");
	}

	if (info->valid & ACPI_VALID_CID) {
		for (i = 0; i < info->compatible_id_list.count; i++) {
			acpi_os_printf("_CID: %s\n",
				       info->compatible_id_list.ids[i].string);
		}
	} else {
		acpi_os_printf("_CID: <Not Present>\n");
	}

	ACPI_FREE(info);
	return (AE_OK);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_db_get_bus_info
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Display info about system busses.
 *
 ******************************************************************************/

void acpi_db_get_bus_info(void)
{
	/* Search all nodes in namespace */

	(void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
				  ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL,
				  NULL);
}
