Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/*******************************************************************************
   3 *
   4 * Module Name: dbcmds - Miscellaneous debug commands and output routines
   5 *
   6 ******************************************************************************/
   7
   8#include <acpi/acpi.h>
   9#include "accommon.h"
  10#include "acevents.h"
  11#include "acdebug.h"
  12#include "acnamesp.h"
  13#include "acresrc.h"
  14#include "actables.h"
  15
  16#define _COMPONENT          ACPI_CA_DEBUGGER
  17ACPI_MODULE_NAME("dbcmds")
  18
  19/* Local prototypes */
  20static void
  21acpi_dm_compare_aml_resources(u8 *aml1_buffer,
  22			      acpi_rsdesc_size aml1_buffer_length,
  23			      u8 *aml2_buffer,
  24			      acpi_rsdesc_size aml2_buffer_length);
  25
  26static acpi_status
  27acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name);
  28
  29static acpi_status
  30acpi_db_resource_callback(struct acpi_resource *resource, void *context);
  31
  32static acpi_status
  33acpi_db_device_resources(acpi_handle obj_handle,
  34			 u32 nesting_level, void *context, void **return_value);
  35
  36static void acpi_db_do_one_sleep_state(u8 sleep_state);
  37
  38static char *acpi_db_trace_method_name = NULL;
  39
  40/*******************************************************************************
  41 *
  42 * FUNCTION:    acpi_db_convert_to_node
  43 *
  44 * PARAMETERS:  in_string           - String to convert
  45 *
  46 * RETURN:      Pointer to a NS node
  47 *
  48 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or
  49 *              alphanumeric strings.
  50 *
  51 ******************************************************************************/
  52
  53struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string)
  54{
  55	struct acpi_namespace_node *node;
  56	acpi_size address;
  57
  58	if ((*in_string >= 0x30) && (*in_string <= 0x39)) {
  59
  60		/* Numeric argument, convert */
  61
  62		address = strtoul(in_string, NULL, 16);
  63		node = ACPI_TO_POINTER(address);
  64		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) {
  65			acpi_os_printf("Address %p is invalid", node);
  66			return (NULL);
  67		}
  68
  69		/* Make sure pointer is valid NS node */
  70
  71		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) {
  72			acpi_os_printf
  73			    ("Address %p is not a valid namespace node [%s]\n",
  74			     node, acpi_ut_get_descriptor_name(node));
  75			return (NULL);
  76		}
  77	} else {
  78		/*
  79		 * Alpha argument: The parameter is a name string that must be
  80		 * resolved to a Namespace object.
  81		 */
  82		node = acpi_db_local_ns_lookup(in_string);
  83		if (!node) {
  84			acpi_os_printf
  85			    ("Could not find [%s] in namespace, defaulting to root node\n",
  86			     in_string);
  87			node = acpi_gbl_root_node;
  88		}
  89	}
  90
  91	return (node);
  92}
  93
  94/*******************************************************************************
  95 *
  96 * FUNCTION:    acpi_db_sleep
  97 *
  98 * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means
  99 *                                    invoke all possible sleep states.
 100 *
 101 * RETURN:      Status
 102 *
 103 * DESCRIPTION: Simulate sleep/wake sequences
 104 *
 105 ******************************************************************************/
 106
 107acpi_status acpi_db_sleep(char *object_arg)
 108{
 109	u8 sleep_state;
 110	u32 i;
 111
 112	ACPI_FUNCTION_TRACE(acpi_db_sleep);
 113
 114	/* Null input (no arguments) means to invoke all sleep states */
 115
 116	if (!object_arg) {
 117		acpi_os_printf("Invoking all possible sleep states, 0-%d\n",
 118			       ACPI_S_STATES_MAX);
 119
 120		for (i = 0; i <= ACPI_S_STATES_MAX; i++) {
 121			acpi_db_do_one_sleep_state((u8)i);
 122		}
 123
 124		return_ACPI_STATUS(AE_OK);
 125	}
 126
 127	/* Convert argument to binary and invoke the sleep state */
 128
 129	sleep_state = (u8)strtoul(object_arg, NULL, 0);
 130	acpi_db_do_one_sleep_state(sleep_state);
 131	return_ACPI_STATUS(AE_OK);
 132}
 133
 134/*******************************************************************************
 135 *
 136 * FUNCTION:    acpi_db_do_one_sleep_state
 137 *
 138 * PARAMETERS:  sleep_state         - Desired sleep state (0-5)
 139 *
 140 * RETURN:      None
 141 *
 142 * DESCRIPTION: Simulate a sleep/wake sequence
 143 *
 144 ******************************************************************************/
 145
 146static void acpi_db_do_one_sleep_state(u8 sleep_state)
 147{
 148	acpi_status status;
 149	u8 sleep_type_a;
 150	u8 sleep_type_b;
 151
 152	/* Validate parameter */
 153
 154	if (sleep_state > ACPI_S_STATES_MAX) {
 155		acpi_os_printf("Sleep state %d out of range (%d max)\n",
 156			       sleep_state, ACPI_S_STATES_MAX);
 157		return;
 158	}
 159
 160	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n",
 161		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]);
 162
 163	/* Get the values for the sleep type registers (for display only) */
 164
 165	status =
 166	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b);
 167	if (ACPI_FAILURE(status)) {
 168		acpi_os_printf("Could not evaluate [%s] method, %s\n",
 169			       acpi_gbl_sleep_state_names[sleep_state],
 170			       acpi_format_exception(status));
 171		return;
 172	}
 173
 174	acpi_os_printf
 175	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n",
 176	     sleep_state, sleep_type_a, sleep_type_b);
 177
 178	/* Invoke the various sleep/wake interfaces */
 179
 180	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n",
 181		       sleep_state);
 182	status = acpi_enter_sleep_state_prep(sleep_state);
 183	if (ACPI_FAILURE(status)) {
 184		goto error_exit;
 185	}
 186
 187	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state);
 188	status = acpi_enter_sleep_state(sleep_state);
 189	if (ACPI_FAILURE(status)) {
 190		goto error_exit;
 191	}
 192
 193	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n",
 194		       sleep_state);
 195	status = acpi_leave_sleep_state_prep(sleep_state);
 196	if (ACPI_FAILURE(status)) {
 197		goto error_exit;
 198	}
 199
 200	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n",
 201		       sleep_state);
 202	status = acpi_leave_sleep_state(sleep_state);
 203	if (ACPI_FAILURE(status)) {
 204		goto error_exit;
 205	}
 206
 207	return;
 208
 209error_exit:
 210	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d",
 211			sleep_state));
 212}
 213
 214/*******************************************************************************
 215 *
 216 * FUNCTION:    acpi_db_display_locks
 217 *
 218 * PARAMETERS:  None
 219 *
 220 * RETURN:      None
 221 *
 222 * DESCRIPTION: Display information about internal mutexes.
 223 *
 224 ******************************************************************************/
 225
 226void acpi_db_display_locks(void)
 227{
 228	u32 i;
 229
 230	for (i = 0; i < ACPI_MAX_MUTEX; i++) {
 231		acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i),
 232			       acpi_gbl_mutex_info[i].thread_id ==
 233			       ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked");
 234	}
 235}
 236
 237/*******************************************************************************
 238 *
 239 * FUNCTION:    acpi_db_display_table_info
 240 *
 241 * PARAMETERS:  table_arg           - Name of table to be displayed
 242 *
 243 * RETURN:      None
 244 *
 245 * DESCRIPTION: Display information about loaded tables. Current
 246 *              implementation displays all loaded tables.
 247 *
 248 ******************************************************************************/
 249
 250void acpi_db_display_table_info(char *table_arg)
 251{
 252	u32 i;
 253	struct acpi_table_desc *table_desc;
 254	acpi_status status;
 255
 256	/* Header */
 257
 258	acpi_os_printf("Idx ID  Status Type                    "
 259		       "TableHeader (Sig, Address, Length, Misc)\n");
 260
 261	/* Walk the entire root table list */
 262
 263	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) {
 264		table_desc = &acpi_gbl_root_table_list.tables[i];
 265
 266		/* Index and Table ID */
 267
 268		acpi_os_printf("%3u %.2u ", i, table_desc->owner_id);
 269
 270		/* Decode the table flags */
 271
 272		if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) {
 273			acpi_os_printf("NotLoaded ");
 274		} else {
 275			acpi_os_printf(" Loaded ");
 276		}
 277
 278		switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
 279		case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
 280
 281			acpi_os_printf("External/virtual ");
 282			break;
 283
 284		case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
 285
 286			acpi_os_printf("Internal/physical ");
 287			break;
 288
 289		case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
 290
 291			acpi_os_printf("Internal/virtual ");
 292			break;
 293
 294		default:
 295
 296			acpi_os_printf("INVALID TYPE    ");
 297			break;
 298		}
 299
 300		/* Make sure that the table is mapped */
 301
 302		status = acpi_tb_validate_table(table_desc);
 303		if (ACPI_FAILURE(status)) {
 304			return;
 305		}
 306
 307		/* Dump the table header */
 308
 309		if (table_desc->pointer) {
 310			acpi_tb_print_table_header(table_desc->address,
 311						   table_desc->pointer);
 312		} else {
 313			/* If the pointer is null, the table has been unloaded */
 314
 315			ACPI_INFO(("%4.4s - Table has been unloaded",
 316				   table_desc->signature.ascii));
 317		}
 318	}
 319}
 320
 321/*******************************************************************************
 322 *
 323 * FUNCTION:    acpi_db_unload_acpi_table
 324 *
 325 * PARAMETERS:  object_name         - Namespace pathname for an object that
 326 *                                    is owned by the table to be unloaded
 327 *
 328 * RETURN:      None
 329 *
 330 * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned
 331 *              by the table.
 332 *
 333 ******************************************************************************/
 334
 335void acpi_db_unload_acpi_table(char *object_name)
 336{
 337	struct acpi_namespace_node *node;
 338	acpi_status status;
 339
 340	/* Translate name to an Named object */
 341
 342	node = acpi_db_convert_to_node(object_name);
 343	if (!node) {
 344		return;
 345	}
 346
 347	status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node));
 348	if (ACPI_SUCCESS(status)) {
 349		acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n",
 350			       object_name, node);
 351	} else {
 352		acpi_os_printf("%s, while unloading parent table of [%s]\n",
 353			       acpi_format_exception(status), object_name);
 354	}
 355}
 356
 357/*******************************************************************************
 358 *
 359 * FUNCTION:    acpi_db_send_notify
 360 *
 361 * PARAMETERS:  name                - Name of ACPI object where to send notify
 362 *              value               - Value of the notify to send.
 363 *
 364 * RETURN:      None
 365 *
 366 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the
 367 *              named object as an ACPI notify.
 368 *
 369 ******************************************************************************/
 370
 371void acpi_db_send_notify(char *name, u32 value)
 372{
 373	struct acpi_namespace_node *node;
 374	acpi_status status;
 375
 376	/* Translate name to an Named object */
 377
 378	node = acpi_db_convert_to_node(name);
 379	if (!node) {
 380		return;
 381	}
 382
 383	/* Dispatch the notify if legal */
 384
 385	if (acpi_ev_is_notify_object(node)) {
 386		status = acpi_ev_queue_notify_request(node, value);
 387		if (ACPI_FAILURE(status)) {
 388			acpi_os_printf("Could not queue notify\n");
 389		}
 390	} else {
 391		acpi_os_printf("Named object [%4.4s] Type %s, "
 392			       "must be Device/Thermal/Processor type\n",
 393			       acpi_ut_get_node_name(node),
 394			       acpi_ut_get_type_name(node->type));
 395	}
 396}
 397
 398/*******************************************************************************
 399 *
 400 * FUNCTION:    acpi_db_display_interfaces
 401 *
 402 * PARAMETERS:  action_arg          - Null, "install", or "remove"
 403 *              interface_name_arg  - Name for install/remove options
 404 *
 405 * RETURN:      None
 406 *
 407 * DESCRIPTION: Display or modify the global _OSI interface list
 408 *
 409 ******************************************************************************/
 410
 411void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg)
 412{
 413	struct acpi_interface_info *next_interface;
 414	char *sub_string;
 415	acpi_status status;
 416
 417	/* If no arguments, just display current interface list */
 418
 419	if (!action_arg) {
 420		(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex,
 421					    ACPI_WAIT_FOREVER);
 422
 423		next_interface = acpi_gbl_supported_interfaces;
 424		while (next_interface) {
 425			if (!(next_interface->flags & ACPI_OSI_INVALID)) {
 426				acpi_os_printf("%s\n", next_interface->name);
 427			}
 428
 429			next_interface = next_interface->next;
 430		}
 431
 432		acpi_os_release_mutex(acpi_gbl_osi_mutex);
 433		return;
 434	}
 435
 436	/* If action_arg exists, so must interface_name_arg */
 437
 438	if (!interface_name_arg) {
 439		acpi_os_printf("Missing Interface Name argument\n");
 440		return;
 441	}
 442
 443	/* Uppercase the action for match below */
 444
 445	acpi_ut_strupr(action_arg);
 446
 447	/* install - install an interface */
 448
 449	sub_string = strstr("INSTALL", action_arg);
 450	if (sub_string) {
 451		status = acpi_install_interface(interface_name_arg);
 452		if (ACPI_FAILURE(status)) {
 453			acpi_os_printf("%s, while installing \"%s\"\n",
 454				       acpi_format_exception(status),
 455				       interface_name_arg);
 456		}
 457		return;
 458	}
 459
 460	/* remove - remove an interface */
 461
 462	sub_string = strstr("REMOVE", action_arg);
 463	if (sub_string) {
 464		status = acpi_remove_interface(interface_name_arg);
 465		if (ACPI_FAILURE(status)) {
 466			acpi_os_printf("%s, while removing \"%s\"\n",
 467				       acpi_format_exception(status),
 468				       interface_name_arg);
 469		}
 470		return;
 471	}
 472
 473	/* Invalid action_arg */
 474
 475	acpi_os_printf("Invalid action argument: %s\n", action_arg);
 476	return;
 477}
 478
 479/*******************************************************************************
 480 *
 481 * FUNCTION:    acpi_db_display_template
 482 *
 483 * PARAMETERS:  buffer_arg          - Buffer name or address
 484 *
 485 * RETURN:      None
 486 *
 487 * DESCRIPTION: Dump a buffer that contains a resource template
 488 *
 489 ******************************************************************************/
 490
 491void acpi_db_display_template(char *buffer_arg)
 492{
 493	struct acpi_namespace_node *node;
 494	acpi_status status;
 495	struct acpi_buffer return_buffer;
 496
 497	/* Translate buffer_arg to an Named object */
 498
 499	node = acpi_db_convert_to_node(buffer_arg);
 500	if (!node || (node == acpi_gbl_root_node)) {
 501		acpi_os_printf("Invalid argument: %s\n", buffer_arg);
 502		return;
 503	}
 504
 505	/* We must have a buffer object */
 506
 507	if (node->type != ACPI_TYPE_BUFFER) {
 508		acpi_os_printf
 509		    ("Not a Buffer object, cannot be a template: %s\n",
 510		     buffer_arg);
 511		return;
 512	}
 513
 514	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 515	return_buffer.pointer = acpi_gbl_db_buffer;
 516
 517	/* Attempt to convert the raw buffer to a resource list */
 518
 519	status = acpi_rs_create_resource_list(node->object, &return_buffer);
 520
 521	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 522	acpi_dbg_level |= ACPI_LV_RESOURCES;
 523
 524	if (ACPI_FAILURE(status)) {
 525		acpi_os_printf
 526		    ("Could not convert Buffer to a resource list: %s, %s\n",
 527		     buffer_arg, acpi_format_exception(status));
 528		goto dump_buffer;
 529	}
 530
 531	/* Now we can dump the resource list */
 532
 533	acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
 534						 return_buffer.pointer));
 535
 536dump_buffer:
 537	acpi_os_printf("\nRaw data buffer:\n");
 538	acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer,
 539				  node->object->buffer.length,
 540				  DB_BYTE_DISPLAY, ACPI_UINT32_MAX);
 541
 542	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
 543	return;
 544}
 545
 546/*******************************************************************************
 547 *
 548 * FUNCTION:    acpi_dm_compare_aml_resources
 549 *
 550 * PARAMETERS:  aml1_buffer         - Contains first resource list
 551 *              aml1_buffer_length  - Length of first resource list
 552 *              aml2_buffer         - Contains second resource list
 553 *              aml2_buffer_length  - Length of second resource list
 554 *
 555 * RETURN:      None
 556 *
 557 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in
 558 *              order to isolate a miscompare to an individual resource)
 559 *
 560 ******************************************************************************/
 561
 562static void
 563acpi_dm_compare_aml_resources(u8 *aml1_buffer,
 564			      acpi_rsdesc_size aml1_buffer_length,
 565			      u8 *aml2_buffer,
 566			      acpi_rsdesc_size aml2_buffer_length)
 567{
 568	u8 *aml1;
 569	u8 *aml2;
 570	u8 *aml1_end;
 571	u8 *aml2_end;
 572	acpi_rsdesc_size aml1_length;
 573	acpi_rsdesc_size aml2_length;
 574	acpi_rsdesc_size offset = 0;
 575	u8 resource_type;
 576	u32 count = 0;
 577	u32 i;
 578
 579	/* Compare overall buffer sizes (may be different due to size rounding) */
 580
 581	if (aml1_buffer_length != aml2_buffer_length) {
 582		acpi_os_printf("**** Buffer length mismatch in converted "
 583			       "AML: Original %X, New %X ****\n",
 584			       aml1_buffer_length, aml2_buffer_length);
 585	}
 586
 587	aml1 = aml1_buffer;
 588	aml2 = aml2_buffer;
 589	aml1_end = aml1_buffer + aml1_buffer_length;
 590	aml2_end = aml2_buffer + aml2_buffer_length;
 591
 592	/* Walk the descriptor lists, comparing each descriptor */
 593
 594	while ((aml1 < aml1_end) && (aml2 < aml2_end)) {
 595
 596		/* Get the lengths of each descriptor */
 597
 598		aml1_length = acpi_ut_get_descriptor_length(aml1);
 599		aml2_length = acpi_ut_get_descriptor_length(aml2);
 600		resource_type = acpi_ut_get_resource_type(aml1);
 601
 602		/* Check for descriptor length match */
 603
 604		if (aml1_length != aml2_length) {
 605			acpi_os_printf
 606			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, "
 607			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count,
 608			     resource_type, offset, aml1_length, aml2_length);
 609		}
 610
 611		/* Check for descriptor byte match */
 612
 613		else if (memcmp(aml1, aml2, aml1_length)) {
 614			acpi_os_printf
 615			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, "
 616			     "Offset %8.8X ****\n", count, resource_type,
 617			     offset);
 618
 619			for (i = 0; i < aml1_length; i++) {
 620				if (aml1[i] != aml2[i]) {
 621					acpi_os_printf
 622					    ("Mismatch at byte offset %.2X: is %2.2X, "
 623					     "should be %2.2X\n", i, aml2[i],
 624					     aml1[i]);
 625				}
 626			}
 627		}
 628
 629		/* Exit on end_tag descriptor */
 630
 631		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) {
 632			return;
 633		}
 634
 635		/* Point to next descriptor in each buffer */
 636
 637		count++;
 638		offset += aml1_length;
 639		aml1 += aml1_length;
 640		aml2 += aml2_length;
 641	}
 642}
 643
 644/*******************************************************************************
 645 *
 646 * FUNCTION:    acpi_dm_test_resource_conversion
 647 *
 648 * PARAMETERS:  node                - Parent device node
 649 *              name                - resource method name (_CRS)
 650 *
 651 * RETURN:      Status
 652 *
 653 * DESCRIPTION: Compare the original AML with a conversion of the AML to
 654 *              internal resource list, then back to AML.
 655 *
 656 ******************************************************************************/
 657
 658static acpi_status
 659acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name)
 660{
 661	acpi_status status;
 662	struct acpi_buffer return_buffer;
 663	struct acpi_buffer resource_buffer;
 664	struct acpi_buffer new_aml;
 665	union acpi_object *original_aml;
 666
 667	acpi_os_printf("Resource Conversion Comparison:\n");
 668
 669	new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 670	return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 671	resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 672
 673	/* Get the original _CRS AML resource template */
 674
 675	status = acpi_evaluate_object(node, name, NULL, &return_buffer);
 676	if (ACPI_FAILURE(status)) {
 677		acpi_os_printf("Could not obtain %s: %s\n",
 678			       name, acpi_format_exception(status));
 679		return (status);
 680	}
 681
 682	/* Get the AML resource template, converted to internal resource structs */
 683
 684	status = acpi_get_current_resources(node, &resource_buffer);
 685	if (ACPI_FAILURE(status)) {
 686		acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
 687			       acpi_format_exception(status));
 688		goto exit1;
 689	}
 690
 691	/* Convert internal resource list to external AML resource template */
 692
 693	status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml);
 694	if (ACPI_FAILURE(status)) {
 695		acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n",
 696			       acpi_format_exception(status));
 697		goto exit2;
 698	}
 699
 700	/* Compare original AML to the newly created AML resource list */
 701
 702	original_aml = return_buffer.pointer;
 703
 704	acpi_dm_compare_aml_resources(original_aml->buffer.pointer,
 705				      (acpi_rsdesc_size)original_aml->buffer.
 706				      length, new_aml.pointer,
 707				      (acpi_rsdesc_size)new_aml.length);
 708
 709	/* Cleanup and exit */
 710
 711	ACPI_FREE(new_aml.pointer);
 712exit2:
 713	ACPI_FREE(resource_buffer.pointer);
 714exit1:
 715	ACPI_FREE(return_buffer.pointer);
 716	return (status);
 717}
 718
 719/*******************************************************************************
 720 *
 721 * FUNCTION:    acpi_db_resource_callback
 722 *
 723 * PARAMETERS:  acpi_walk_resource_callback
 724 *
 725 * RETURN:      Status
 726 *
 727 * DESCRIPTION: Simple callback to exercise acpi_walk_resources and
 728 *              acpi_walk_resource_buffer.
 729 *
 730 ******************************************************************************/
 731
 732static acpi_status
 733acpi_db_resource_callback(struct acpi_resource *resource, void *context)
 734{
 735
 736	return (AE_OK);
 737}
 738
 739/*******************************************************************************
 740 *
 741 * FUNCTION:    acpi_db_device_resources
 742 *
 743 * PARAMETERS:  acpi_walk_callback
 744 *
 745 * RETURN:      Status
 746 *
 747 * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object.
 748 *
 749 ******************************************************************************/
 750
 751static acpi_status
 752acpi_db_device_resources(acpi_handle obj_handle,
 753			 u32 nesting_level, void *context, void **return_value)
 754{
 755	struct acpi_namespace_node *node;
 756	struct acpi_namespace_node *prt_node = NULL;
 757	struct acpi_namespace_node *crs_node = NULL;
 758	struct acpi_namespace_node *prs_node = NULL;
 759	struct acpi_namespace_node *aei_node = NULL;
 760	char *parent_path;
 761	struct acpi_buffer return_buffer;
 762	acpi_status status;
 763
 764	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle);
 765	parent_path = acpi_ns_get_normalized_pathname(node, TRUE);
 766	if (!parent_path) {
 767		return (AE_NO_MEMORY);
 768	}
 769
 770	/* Get handles to the resource methods for this device */
 771
 772	(void)acpi_get_handle(node, METHOD_NAME__PRT,
 773			      ACPI_CAST_PTR(acpi_handle, &prt_node));
 774	(void)acpi_get_handle(node, METHOD_NAME__CRS,
 775			      ACPI_CAST_PTR(acpi_handle, &crs_node));
 776	(void)acpi_get_handle(node, METHOD_NAME__PRS,
 777			      ACPI_CAST_PTR(acpi_handle, &prs_node));
 778	(void)acpi_get_handle(node, METHOD_NAME__AEI,
 779			      ACPI_CAST_PTR(acpi_handle, &aei_node));
 780
 781	if (!prt_node && !crs_node && !prs_node && !aei_node) {
 782		goto cleanup;	/* Nothing to do */
 783	}
 784
 785	acpi_os_printf("\nDevice: %s\n", parent_path);
 786
 787	/* Prepare for a return object of arbitrary size */
 788
 789	return_buffer.pointer = acpi_gbl_db_buffer;
 790	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 791
 792	/* _PRT */
 793
 794	if (prt_node) {
 795		acpi_os_printf("Evaluating _PRT\n");
 796
 797		status =
 798		    acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer);
 799		if (ACPI_FAILURE(status)) {
 800			acpi_os_printf("Could not evaluate _PRT: %s\n",
 801				       acpi_format_exception(status));
 802			goto get_crs;
 803		}
 804
 805		return_buffer.pointer = acpi_gbl_db_buffer;
 806		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 807
 808		status = acpi_get_irq_routing_table(node, &return_buffer);
 809		if (ACPI_FAILURE(status)) {
 810			acpi_os_printf("GetIrqRoutingTable failed: %s\n",
 811				       acpi_format_exception(status));
 812			goto get_crs;
 813		}
 814
 815		acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer));
 816	}
 817
 818	/* _CRS */
 819
 820get_crs:
 821	if (crs_node) {
 822		acpi_os_printf("Evaluating _CRS\n");
 823
 824		return_buffer.pointer = acpi_gbl_db_buffer;
 825		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 826
 827		status =
 828		    acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer);
 829		if (ACPI_FAILURE(status)) {
 830			acpi_os_printf("Could not evaluate _CRS: %s\n",
 831				       acpi_format_exception(status));
 832			goto get_prs;
 833		}
 834
 835		/* This code exercises the acpi_walk_resources interface */
 836
 837		status = acpi_walk_resources(node, METHOD_NAME__CRS,
 838					     acpi_db_resource_callback, NULL);
 839		if (ACPI_FAILURE(status)) {
 840			acpi_os_printf("AcpiWalkResources failed: %s\n",
 841				       acpi_format_exception(status));
 842			goto get_prs;
 843		}
 844
 845		/* Get the _CRS resource list (test ALLOCATE buffer) */
 846
 847		return_buffer.pointer = NULL;
 848		return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
 849
 850		status = acpi_get_current_resources(node, &return_buffer);
 851		if (ACPI_FAILURE(status)) {
 852			acpi_os_printf("AcpiGetCurrentResources failed: %s\n",
 853				       acpi_format_exception(status));
 854			goto get_prs;
 855		}
 856
 857		/* This code exercises the acpi_walk_resource_buffer interface */
 858
 859		status = acpi_walk_resource_buffer(&return_buffer,
 860						   acpi_db_resource_callback,
 861						   NULL);
 862		if (ACPI_FAILURE(status)) {
 863			acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n",
 864				       acpi_format_exception(status));
 865			goto end_crs;
 866		}
 867
 868		/* Dump the _CRS resource list */
 869
 870		acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource,
 871							 return_buffer.
 872							 pointer));
 873
 874		/*
 875		 * Perform comparison of original AML to newly created AML. This
 876		 * tests both the AML->Resource conversion and the Resource->AML
 877		 * conversion.
 878		 */
 879		(void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS);
 880
 881		/* Execute _SRS with the resource list */
 882
 883		acpi_os_printf("Evaluating _SRS\n");
 884
 885		status = acpi_set_current_resources(node, &return_buffer);
 886		if (ACPI_FAILURE(status)) {
 887			acpi_os_printf("AcpiSetCurrentResources failed: %s\n",
 888				       acpi_format_exception(status));
 889			goto end_crs;
 890		}
 891
 892end_crs:
 893		ACPI_FREE(return_buffer.pointer);
 894	}
 895
 896	/* _PRS */
 897
 898get_prs:
 899	if (prs_node) {
 900		acpi_os_printf("Evaluating _PRS\n");
 901
 902		return_buffer.pointer = acpi_gbl_db_buffer;
 903		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 904
 905		status =
 906		    acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer);
 907		if (ACPI_FAILURE(status)) {
 908			acpi_os_printf("Could not evaluate _PRS: %s\n",
 909				       acpi_format_exception(status));
 910			goto get_aei;
 911		}
 912
 913		return_buffer.pointer = acpi_gbl_db_buffer;
 914		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 915
 916		status = acpi_get_possible_resources(node, &return_buffer);
 917		if (ACPI_FAILURE(status)) {
 918			acpi_os_printf("AcpiGetPossibleResources failed: %s\n",
 919				       acpi_format_exception(status));
 920			goto get_aei;
 921		}
 922
 923		acpi_rs_dump_resource_list(ACPI_CAST_PTR
 924					   (struct acpi_resource,
 925					    acpi_gbl_db_buffer));
 926	}
 927
 928	/* _AEI */
 929
 930get_aei:
 931	if (aei_node) {
 932		acpi_os_printf("Evaluating _AEI\n");
 933
 934		return_buffer.pointer = acpi_gbl_db_buffer;
 935		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 936
 937		status =
 938		    acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer);
 939		if (ACPI_FAILURE(status)) {
 940			acpi_os_printf("Could not evaluate _AEI: %s\n",
 941				       acpi_format_exception(status));
 942			goto cleanup;
 943		}
 944
 945		return_buffer.pointer = acpi_gbl_db_buffer;
 946		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE;
 947
 948		status = acpi_get_event_resources(node, &return_buffer);
 949		if (ACPI_FAILURE(status)) {
 950			acpi_os_printf("AcpiGetEventResources failed: %s\n",
 951				       acpi_format_exception(status));
 952			goto cleanup;
 953		}
 954
 955		acpi_rs_dump_resource_list(ACPI_CAST_PTR
 956					   (struct acpi_resource,
 957					    acpi_gbl_db_buffer));
 958	}
 959
 960cleanup:
 961	ACPI_FREE(parent_path);
 962	return (AE_OK);
 963}
 964
 965/*******************************************************************************
 966 *
 967 * FUNCTION:    acpi_db_display_resources
 968 *
 969 * PARAMETERS:  object_arg          - String object name or object pointer.
 970 *                                    NULL or "*" means "display resources for
 971 *                                    all devices"
 972 *
 973 * RETURN:      None
 974 *
 975 * DESCRIPTION: Display the resource objects associated with a device.
 976 *
 977 ******************************************************************************/
 978
 979void acpi_db_display_resources(char *object_arg)
 980{
 981	struct acpi_namespace_node *node;
 982
 983	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT);
 984	acpi_dbg_level |= ACPI_LV_RESOURCES;
 985
 986	/* Asterisk means "display resources for all devices" */
 987
 988	if (!object_arg || (!strcmp(object_arg, "*"))) {
 989		(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
 990					  ACPI_UINT32_MAX,
 991					  acpi_db_device_resources, NULL, NULL,
 992					  NULL);
 993	} else {
 994		/* Convert string to object pointer */
 995
 996		node = acpi_db_convert_to_node(object_arg);
 997		if (node) {
 998			if (node->type != ACPI_TYPE_DEVICE) {
 999				acpi_os_printf
1000				    ("%4.4s: Name is not a device object (%s)\n",
1001				     node->name.ascii,
1002				     acpi_ut_get_type_name(node->type));
1003			} else {
1004				(void)acpi_db_device_resources(node, 0, NULL,
1005							       NULL);
1006			}
1007		}
1008	}
1009
1010	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT);
1011}
1012
1013/*******************************************************************************
1014 *
1015 * FUNCTION:    acpi_db_generate_ged
1016 *
1017 * PARAMETERS:  ged_arg             - Raw GED number, ascii string
1018 *
1019 * RETURN:      None
1020 *
1021 * DESCRIPTION: Simulate firing of a GED
1022 *
1023 ******************************************************************************/
1024
1025void acpi_db_generate_interrupt(char *gsiv_arg)
1026{
1027	u32 gsiv_number;
1028	struct acpi_ged_handler_info *ged_info = acpi_gbl_ged_handler_list;
1029
1030	if (!ged_info) {
1031		acpi_os_printf("No GED handling present\n");
1032	}
1033
1034	gsiv_number = strtoul(gsiv_arg, NULL, 0);
1035
1036	while (ged_info) {
1037
1038		if (ged_info->int_id == gsiv_number) {
1039			struct acpi_object_list arg_list;
1040			union acpi_object arg0;
1041			acpi_handle evt_handle = ged_info->evt_method;
1042			acpi_status status;
1043
1044			acpi_os_printf("Evaluate GED _EVT (GSIV=%d)\n",
1045				       gsiv_number);
1046
1047			if (!evt_handle) {
1048				acpi_os_printf("Undefined _EVT method\n");
1049				return;
1050			}
1051
1052			arg0.integer.type = ACPI_TYPE_INTEGER;
1053			arg0.integer.value = gsiv_number;
1054
1055			arg_list.count = 1;
1056			arg_list.pointer = &arg0;
1057
1058			status =
1059			    acpi_evaluate_object(evt_handle, NULL, &arg_list,
1060						 NULL);
1061			if (ACPI_FAILURE(status)) {
1062				acpi_os_printf("Could not evaluate _EVT\n");
1063				return;
1064			}
1065
1066		}
1067		ged_info = ged_info->next;
1068	}
1069}
1070
1071#if (!ACPI_REDUCED_HARDWARE)
1072/*******************************************************************************
1073 *
1074 * FUNCTION:    acpi_db_generate_gpe
1075 *
1076 * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string
1077 *              block_arg           - GPE block number, ascii string
1078 *                                    0 or 1 for FADT GPE blocks
1079 *
1080 * RETURN:      None
1081 *
1082 * DESCRIPTION: Simulate firing of a GPE
1083 *
1084 ******************************************************************************/
1085
1086void acpi_db_generate_gpe(char *gpe_arg, char *block_arg)
1087{
1088	u32 block_number = 0;
1089	u32 gpe_number;
1090	struct acpi_gpe_event_info *gpe_event_info;
1091
1092	gpe_number = strtoul(gpe_arg, NULL, 0);
1093
1094	/*
1095	 * If no block arg, or block arg == 0 or 1, use the FADT-defined
1096	 * GPE blocks.
1097	 */
1098	if (block_arg) {
1099		block_number = strtoul(block_arg, NULL, 0);
1100		if (block_number == 1) {
1101			block_number = 0;
1102		}
1103	}
1104
1105	gpe_event_info =
1106	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number),
1107				       gpe_number);
1108	if (!gpe_event_info) {
1109		acpi_os_printf("Invalid GPE\n");
1110		return;
1111	}
1112
1113	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number);
1114}
1115
1116/*******************************************************************************
1117 *
1118 * FUNCTION:    acpi_db_generate_sci
1119 *
1120 * PARAMETERS:  None
1121 *
1122 * RETURN:      None
1123 *
1124 * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch.
1125 *
1126 ******************************************************************************/
1127
1128void acpi_db_generate_sci(void)
1129{
1130	acpi_ev_sci_dispatch();
1131}
1132
1133#endif				/* !ACPI_REDUCED_HARDWARE */
1134
1135/*******************************************************************************
1136 *
1137 * FUNCTION:    acpi_db_trace
1138 *
1139 * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer
1140 *                                    DISABLE to disable tracer
1141 *              method_arg          - Method to trace
1142 *              once_arg            - Whether trace once
1143 *
1144 * RETURN:      None
1145 *
1146 * DESCRIPTION: Control method tracing facility
1147 *
1148 ******************************************************************************/
1149
1150void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg)
1151{
1152	u32 debug_level = 0;
1153	u32 debug_layer = 0;
1154	u32 flags = 0;
1155
1156	acpi_ut_strupr(enable_arg);
1157	acpi_ut_strupr(once_arg);
1158
1159	if (method_arg) {
1160		if (acpi_db_trace_method_name) {
1161			ACPI_FREE(acpi_db_trace_method_name);
1162			acpi_db_trace_method_name = NULL;
1163		}
1164
1165		acpi_db_trace_method_name =
1166		    ACPI_ALLOCATE(strlen(method_arg) + 1);
1167		if (!acpi_db_trace_method_name) {
1168			acpi_os_printf("Failed to allocate method name (%s)\n",
1169				       method_arg);
1170			return;
1171		}
1172
1173		strcpy(acpi_db_trace_method_name, method_arg);
1174	}
1175
1176	if (!strcmp(enable_arg, "ENABLE") ||
1177	    !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) {
1178		if (!strcmp(enable_arg, "ENABLE")) {
1179
1180			/* Inherit current console settings */
1181
1182			debug_level = acpi_gbl_db_console_debug_level;
1183			debug_layer = acpi_dbg_layer;
1184		} else {
1185			/* Restrict console output to trace points only */
1186
1187			debug_level = ACPI_LV_TRACE_POINT;
1188			debug_layer = ACPI_EXECUTER;
1189		}
1190
1191		flags = ACPI_TRACE_ENABLED;
1192
1193		if (!strcmp(enable_arg, "OPCODE")) {
1194			flags |= ACPI_TRACE_OPCODE;
1195		}
1196
1197		if (once_arg && !strcmp(once_arg, "ONCE")) {
1198			flags |= ACPI_TRACE_ONESHOT;
1199		}
1200	}
1201
1202	(void)acpi_debug_trace(acpi_db_trace_method_name,
1203			       debug_level, debug_layer, flags);
1204}