// 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));

		if (!object_info)
			return (AE_NO_MEMORY);

		/* 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);
}
