// 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"
#include "acinterp.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_NAMESEG_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_fields
 *
 * PARAMETERS:  Callback from walk_namespace
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Display short info about objects in the namespace
 *
 ******************************************************************************/

static acpi_status
acpi_db_walk_for_fields(acpi_handle obj_handle,
			u32 nesting_level, void *context, void **return_value)
{
	union acpi_object *ret_value;
	struct acpi_region_walk_info *info =
	    (struct acpi_region_walk_info *)context;
	struct acpi_buffer buffer;
	acpi_status status;
	struct acpi_namespace_node *node = acpi_ns_validate_handle(obj_handle);

	if (!node) {
		return (AE_OK);
	}
	if (node->object->field.region_obj->region.space_id !=
	    info->address_space_id) {
		return (AE_OK);
	}

	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("%s ", (char *)buffer.pointer);
	ACPI_FREE(buffer.pointer);

	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
	acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);

	/*
	 * Since this is a field unit, surround the output in braces
	 */
	acpi_os_printf("{");

	ret_value = (union acpi_object *)buffer.pointer;
	switch (ret_value->type) {
	case ACPI_TYPE_INTEGER:

		acpi_os_printf("%8.8X%8.8X",
			       ACPI_FORMAT_UINT64(ret_value->integer.value));
		break;

	case ACPI_TYPE_BUFFER:

		acpi_ut_dump_buffer(ret_value->buffer.pointer,
				    ret_value->buffer.length,
				    DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0);
		break;

	default:

		break;
	}
	acpi_os_printf("}\n");

	ACPI_FREE(buffer.pointer);

	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_display_fields
 *
 * 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_fields(u32 address_space_id)
{
	struct acpi_region_walk_info info;

	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;
	info.address_space_id = address_space_id;

	/* Walk the namespace from the root */

	(void)acpi_walk_namespace(ACPI_TYPE_LOCAL_REGION_FIELD,
				  ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
				  acpi_db_walk_for_fields, NULL, (void *)&info,
				  NULL);

	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 buses.
 *
 ******************************************************************************/

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