| /******************************************************************************* | 
 |  * | 
 |  * Module Name: dbcmds - Miscellaneous debug commands and output routines | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | /* | 
 |  * Copyright (C) 2000 - 2015, Intel Corp. | 
 |  * All rights reserved. | 
 |  * | 
 |  * Redistribution and use in source and binary forms, with or without | 
 |  * modification, are permitted provided that the following conditions | 
 |  * are met: | 
 |  * 1. Redistributions of source code must retain the above copyright | 
 |  *    notice, this list of conditions, and the following disclaimer, | 
 |  *    without modification. | 
 |  * 2. Redistributions in binary form must reproduce at minimum a disclaimer | 
 |  *    substantially similar to the "NO WARRANTY" disclaimer below | 
 |  *    ("Disclaimer") and any redistribution must be conditioned upon | 
 |  *    including a substantially similar Disclaimer requirement for further | 
 |  *    binary redistribution. | 
 |  * 3. Neither the names of the above-listed copyright holders nor the names | 
 |  *    of any contributors may be used to endorse or promote products derived | 
 |  *    from this software without specific prior written permission. | 
 |  * | 
 |  * Alternatively, this software may be distributed under the terms of the | 
 |  * GNU General Public License ("GPL") version 2 as published by the Free | 
 |  * Software Foundation. | 
 |  * | 
 |  * NO WARRANTY | 
 |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
 |  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
 |  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | 
 |  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
 |  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 
 |  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | 
 |  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
 |  * POSSIBILITY OF SUCH DAMAGES. | 
 |  */ | 
 |  | 
 | #include <acpi/acpi.h> | 
 | #include "accommon.h" | 
 | #include "acevents.h" | 
 | #include "acdebug.h" | 
 | #include "acnamesp.h" | 
 | #include "acresrc.h" | 
 | #include "actables.h" | 
 |  | 
 | #define _COMPONENT          ACPI_CA_DEBUGGER | 
 | ACPI_MODULE_NAME("dbcmds") | 
 |  | 
 | /* Local prototypes */ | 
 | static void | 
 | acpi_dm_compare_aml_resources(u8 *aml1_buffer, | 
 | 			      acpi_rsdesc_size aml1_buffer_length, | 
 | 			      u8 *aml2_buffer, | 
 | 			      acpi_rsdesc_size aml2_buffer_length); | 
 |  | 
 | static acpi_status | 
 | acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name); | 
 |  | 
 | static acpi_status | 
 | acpi_db_resource_callback(struct acpi_resource *resource, void *context); | 
 |  | 
 | static acpi_status | 
 | acpi_db_device_resources(acpi_handle obj_handle, | 
 | 			 u32 nesting_level, void *context, void **return_value); | 
 |  | 
 | static void acpi_db_do_one_sleep_state(u8 sleep_state); | 
 |  | 
 | static char *acpi_db_trace_method_name = NULL; | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_convert_to_node | 
 |  * | 
 |  * PARAMETERS:  in_string           - String to convert | 
 |  * | 
 |  * RETURN:      Pointer to a NS node | 
 |  * | 
 |  * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or | 
 |  *              alphanumeric strings. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | struct acpi_namespace_node *acpi_db_convert_to_node(char *in_string) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 | 	acpi_size address; | 
 |  | 
 | 	if ((*in_string >= 0x30) && (*in_string <= 0x39)) { | 
 |  | 
 | 		/* Numeric argument, convert */ | 
 |  | 
 | 		address = strtoul(in_string, NULL, 16); | 
 | 		node = ACPI_TO_POINTER(address); | 
 | 		if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) { | 
 | 			acpi_os_printf("Address %p is invalid", node); | 
 | 			return (NULL); | 
 | 		} | 
 |  | 
 | 		/* Make sure pointer is valid NS node */ | 
 |  | 
 | 		if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { | 
 | 			acpi_os_printf | 
 | 			    ("Address %p is not a valid namespace node [%s]\n", | 
 | 			     node, acpi_ut_get_descriptor_name(node)); | 
 | 			return (NULL); | 
 | 		} | 
 | 	} else { | 
 | 		/* | 
 | 		 * Alpha argument: The parameter is a name string that must be | 
 | 		 * resolved to a Namespace object. | 
 | 		 */ | 
 | 		node = acpi_db_local_ns_lookup(in_string); | 
 | 		if (!node) { | 
 | 			acpi_os_printf | 
 | 			    ("Could not find [%s] in namespace, defaulting to root node\n", | 
 | 			     in_string); | 
 | 			node = acpi_gbl_root_node; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return (node); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_sleep | 
 |  * | 
 |  * PARAMETERS:  object_arg          - Desired sleep state (0-5). NULL means | 
 |  *                                    invoke all possible sleep states. | 
 |  * | 
 |  * RETURN:      Status | 
 |  * | 
 |  * DESCRIPTION: Simulate sleep/wake sequences | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | acpi_status acpi_db_sleep(char *object_arg) | 
 | { | 
 | 	u8 sleep_state; | 
 | 	u32 i; | 
 |  | 
 | 	ACPI_FUNCTION_TRACE(acpi_db_sleep); | 
 |  | 
 | 	/* Null input (no arguments) means to invoke all sleep states */ | 
 |  | 
 | 	if (!object_arg) { | 
 | 		acpi_os_printf("Invoking all possible sleep states, 0-%d\n", | 
 | 			       ACPI_S_STATES_MAX); | 
 |  | 
 | 		for (i = 0; i <= ACPI_S_STATES_MAX; i++) { | 
 | 			acpi_db_do_one_sleep_state((u8)i); | 
 | 		} | 
 |  | 
 | 		return_ACPI_STATUS(AE_OK); | 
 | 	} | 
 |  | 
 | 	/* Convert argument to binary and invoke the sleep state */ | 
 |  | 
 | 	sleep_state = (u8)strtoul(object_arg, NULL, 0); | 
 | 	acpi_db_do_one_sleep_state(sleep_state); | 
 | 	return_ACPI_STATUS(AE_OK); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_do_one_sleep_state | 
 |  * | 
 |  * PARAMETERS:  sleep_state         - Desired sleep state (0-5) | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Simulate a sleep/wake sequence | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | static void acpi_db_do_one_sleep_state(u8 sleep_state) | 
 | { | 
 | 	acpi_status status; | 
 | 	u8 sleep_type_a; | 
 | 	u8 sleep_type_b; | 
 |  | 
 | 	/* Validate parameter */ | 
 |  | 
 | 	if (sleep_state > ACPI_S_STATES_MAX) { | 
 | 		acpi_os_printf("Sleep state %d out of range (%d max)\n", | 
 | 			       sleep_state, ACPI_S_STATES_MAX); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	acpi_os_printf("\n---- Invoking sleep state S%d (%s):\n", | 
 | 		       sleep_state, acpi_gbl_sleep_state_names[sleep_state]); | 
 |  | 
 | 	/* Get the values for the sleep type registers (for display only) */ | 
 |  | 
 | 	status = | 
 | 	    acpi_get_sleep_type_data(sleep_state, &sleep_type_a, &sleep_type_b); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		acpi_os_printf("Could not evaluate [%s] method, %s\n", | 
 | 			       acpi_gbl_sleep_state_names[sleep_state], | 
 | 			       acpi_format_exception(status)); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	acpi_os_printf | 
 | 	    ("Register values for sleep state S%d: Sleep-A: %.2X, Sleep-B: %.2X\n", | 
 | 	     sleep_state, sleep_type_a, sleep_type_b); | 
 |  | 
 | 	/* Invoke the various sleep/wake interfaces */ | 
 |  | 
 | 	acpi_os_printf("**** Sleep: Prepare to sleep (S%d) ****\n", | 
 | 		       sleep_state); | 
 | 	status = acpi_enter_sleep_state_prep(sleep_state); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		goto error_exit; | 
 | 	} | 
 |  | 
 | 	acpi_os_printf("**** Sleep: Going to sleep (S%d) ****\n", sleep_state); | 
 | 	status = acpi_enter_sleep_state(sleep_state); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		goto error_exit; | 
 | 	} | 
 |  | 
 | 	acpi_os_printf("**** Wake: Prepare to return from sleep (S%d) ****\n", | 
 | 		       sleep_state); | 
 | 	status = acpi_leave_sleep_state_prep(sleep_state); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		goto error_exit; | 
 | 	} | 
 |  | 
 | 	acpi_os_printf("**** Wake: Return from sleep (S%d) ****\n", | 
 | 		       sleep_state); | 
 | 	status = acpi_leave_sleep_state(sleep_state); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		goto error_exit; | 
 | 	} | 
 |  | 
 | 	return; | 
 |  | 
 | error_exit: | 
 | 	ACPI_EXCEPTION((AE_INFO, status, "During invocation of sleep state S%d", | 
 | 			sleep_state)); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_display_locks | 
 |  * | 
 |  * PARAMETERS:  None | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Display information about internal mutexes. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_display_locks(void) | 
 | { | 
 | 	u32 i; | 
 |  | 
 | 	for (i = 0; i < ACPI_MAX_MUTEX; i++) { | 
 | 		acpi_os_printf("%26s : %s\n", acpi_ut_get_mutex_name(i), | 
 | 			       acpi_gbl_mutex_info[i].thread_id == | 
 | 			       ACPI_MUTEX_NOT_ACQUIRED ? "Locked" : "Unlocked"); | 
 | 	} | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_display_table_info | 
 |  * | 
 |  * PARAMETERS:  table_arg           - Name of table to be displayed | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Display information about loaded tables. Current | 
 |  *              implementation displays all loaded tables. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_display_table_info(char *table_arg) | 
 | { | 
 | 	u32 i; | 
 | 	struct acpi_table_desc *table_desc; | 
 | 	acpi_status status; | 
 |  | 
 | 	/* Header */ | 
 |  | 
 | 	acpi_os_printf("Idx ID  Status Type                    " | 
 | 		       "TableHeader (Sig, Address, Length, Misc)\n"); | 
 |  | 
 | 	/* Walk the entire root table list */ | 
 |  | 
 | 	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { | 
 | 		table_desc = &acpi_gbl_root_table_list.tables[i]; | 
 |  | 
 | 		/* Index and Table ID */ | 
 |  | 
 | 		acpi_os_printf("%3u %.2u ", i, table_desc->owner_id); | 
 |  | 
 | 		/* Decode the table flags */ | 
 |  | 
 | 		if (!(table_desc->flags & ACPI_TABLE_IS_LOADED)) { | 
 | 			acpi_os_printf("NotLoaded "); | 
 | 		} else { | 
 | 			acpi_os_printf(" Loaded "); | 
 | 		} | 
 |  | 
 | 		switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { | 
 | 		case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: | 
 |  | 
 | 			acpi_os_printf("External/virtual "); | 
 | 			break; | 
 |  | 
 | 		case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: | 
 |  | 
 | 			acpi_os_printf("Internal/physical "); | 
 | 			break; | 
 |  | 
 | 		case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: | 
 |  | 
 | 			acpi_os_printf("Internal/virtual "); | 
 | 			break; | 
 |  | 
 | 		default: | 
 |  | 
 | 			acpi_os_printf("INVALID TYPE    "); | 
 | 			break; | 
 | 		} | 
 |  | 
 | 		/* Make sure that the table is mapped */ | 
 |  | 
 | 		status = acpi_tb_validate_table(table_desc); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			return; | 
 | 		} | 
 |  | 
 | 		/* Dump the table header */ | 
 |  | 
 | 		if (table_desc->pointer) { | 
 | 			acpi_tb_print_table_header(table_desc->address, | 
 | 						   table_desc->pointer); | 
 | 		} else { | 
 | 			/* If the pointer is null, the table has been unloaded */ | 
 |  | 
 | 			ACPI_INFO((AE_INFO, "%4.4s - Table has been unloaded", | 
 | 				   table_desc->signature.ascii)); | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_unload_acpi_table | 
 |  * | 
 |  * PARAMETERS:  object_name         - Namespace pathname for an object that | 
 |  *                                    is owned by the table to be unloaded | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Unload an ACPI table, via any namespace node that is owned | 
 |  *              by the table. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_unload_acpi_table(char *object_name) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 | 	acpi_status status; | 
 |  | 
 | 	/* Translate name to an Named object */ | 
 |  | 
 | 	node = acpi_db_convert_to_node(object_name); | 
 | 	if (!node) { | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	status = acpi_unload_parent_table(ACPI_CAST_PTR(acpi_handle, node)); | 
 | 	if (ACPI_SUCCESS(status)) { | 
 | 		acpi_os_printf("Parent of [%s] (%p) unloaded and uninstalled\n", | 
 | 			       object_name, node); | 
 | 	} else { | 
 | 		acpi_os_printf("%s, while unloading parent table of [%s]\n", | 
 | 			       acpi_format_exception(status), object_name); | 
 | 	} | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_send_notify | 
 |  * | 
 |  * PARAMETERS:  name                - Name of ACPI object where to send notify | 
 |  *              value               - Value of the notify to send. | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Send an ACPI notification. The value specified is sent to the | 
 |  *              named object as an ACPI notify. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_send_notify(char *name, u32 value) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 | 	acpi_status status; | 
 |  | 
 | 	/* Translate name to an Named object */ | 
 |  | 
 | 	node = acpi_db_convert_to_node(name); | 
 | 	if (!node) { | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* Dispatch the notify if legal */ | 
 |  | 
 | 	if (acpi_ev_is_notify_object(node)) { | 
 | 		status = acpi_ev_queue_notify_request(node, value); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("Could not queue notify\n"); | 
 | 		} | 
 | 	} else { | 
 | 		acpi_os_printf("Named object [%4.4s] Type %s, " | 
 | 			       "must be Device/Thermal/Processor type\n", | 
 | 			       acpi_ut_get_node_name(node), | 
 | 			       acpi_ut_get_type_name(node->type)); | 
 | 	} | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_display_interfaces | 
 |  * | 
 |  * PARAMETERS:  action_arg          - Null, "install", or "remove" | 
 |  *              interface_name_arg  - Name for install/remove options | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Display or modify the global _OSI interface list | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_display_interfaces(char *action_arg, char *interface_name_arg) | 
 | { | 
 | 	struct acpi_interface_info *next_interface; | 
 | 	char *sub_string; | 
 | 	acpi_status status; | 
 |  | 
 | 	/* If no arguments, just display current interface list */ | 
 |  | 
 | 	if (!action_arg) { | 
 | 		(void)acpi_os_acquire_mutex(acpi_gbl_osi_mutex, | 
 | 					    ACPI_WAIT_FOREVER); | 
 |  | 
 | 		next_interface = acpi_gbl_supported_interfaces; | 
 | 		while (next_interface) { | 
 | 			if (!(next_interface->flags & ACPI_OSI_INVALID)) { | 
 | 				acpi_os_printf("%s\n", next_interface->name); | 
 | 			} | 
 |  | 
 | 			next_interface = next_interface->next; | 
 | 		} | 
 |  | 
 | 		acpi_os_release_mutex(acpi_gbl_osi_mutex); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* If action_arg exists, so must interface_name_arg */ | 
 |  | 
 | 	if (!interface_name_arg) { | 
 | 		acpi_os_printf("Missing Interface Name argument\n"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* Uppercase the action for match below */ | 
 |  | 
 | 	acpi_ut_strupr(action_arg); | 
 |  | 
 | 	/* install - install an interface */ | 
 |  | 
 | 	sub_string = strstr("INSTALL", action_arg); | 
 | 	if (sub_string) { | 
 | 		status = acpi_install_interface(interface_name_arg); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("%s, while installing \"%s\"\n", | 
 | 				       acpi_format_exception(status), | 
 | 				       interface_name_arg); | 
 | 		} | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* remove - remove an interface */ | 
 |  | 
 | 	sub_string = strstr("REMOVE", action_arg); | 
 | 	if (sub_string) { | 
 | 		status = acpi_remove_interface(interface_name_arg); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("%s, while removing \"%s\"\n", | 
 | 				       acpi_format_exception(status), | 
 | 				       interface_name_arg); | 
 | 		} | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* Invalid action_arg */ | 
 |  | 
 | 	acpi_os_printf("Invalid action argument: %s\n", action_arg); | 
 | 	return; | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_display_template | 
 |  * | 
 |  * PARAMETERS:  buffer_arg          - Buffer name or address | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Dump a buffer that contains a resource template | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_display_template(char *buffer_arg) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 | 	acpi_status status; | 
 | 	struct acpi_buffer return_buffer; | 
 |  | 
 | 	/* Translate buffer_arg to an Named object */ | 
 |  | 
 | 	node = acpi_db_convert_to_node(buffer_arg); | 
 | 	if (!node || (node == acpi_gbl_root_node)) { | 
 | 		acpi_os_printf("Invalid argument: %s\n", buffer_arg); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	/* We must have a buffer object */ | 
 |  | 
 | 	if (node->type != ACPI_TYPE_BUFFER) { | 
 | 		acpi_os_printf | 
 | 		    ("Not a Buffer object, cannot be a template: %s\n", | 
 | 		     buffer_arg); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 | 	return_buffer.pointer = acpi_gbl_db_buffer; | 
 |  | 
 | 	/* Attempt to convert the raw buffer to a resource list */ | 
 |  | 
 | 	status = acpi_rs_create_resource_list(node->object, &return_buffer); | 
 |  | 
 | 	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | 
 | 	acpi_dbg_level |= ACPI_LV_RESOURCES; | 
 |  | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		acpi_os_printf | 
 | 		    ("Could not convert Buffer to a resource list: %s, %s\n", | 
 | 		     buffer_arg, acpi_format_exception(status)); | 
 | 		goto dump_buffer; | 
 | 	} | 
 |  | 
 | 	/* Now we can dump the resource list */ | 
 |  | 
 | 	acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource, | 
 | 						 return_buffer.pointer)); | 
 |  | 
 | dump_buffer: | 
 | 	acpi_os_printf("\nRaw data buffer:\n"); | 
 | 	acpi_ut_debug_dump_buffer((u8 *)node->object->buffer.pointer, | 
 | 				  node->object->buffer.length, | 
 | 				  DB_BYTE_DISPLAY, ACPI_UINT32_MAX); | 
 |  | 
 | 	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | 
 | 	return; | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_dm_compare_aml_resources | 
 |  * | 
 |  * PARAMETERS:  aml1_buffer         - Contains first resource list | 
 |  *              aml1_buffer_length  - Length of first resource list | 
 |  *              aml2_buffer         - Contains second resource list | 
 |  *              aml2_buffer_length  - Length of second resource list | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in | 
 |  *              order to isolate a miscompare to an individual resource) | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | static void | 
 | acpi_dm_compare_aml_resources(u8 *aml1_buffer, | 
 | 			      acpi_rsdesc_size aml1_buffer_length, | 
 | 			      u8 *aml2_buffer, | 
 | 			      acpi_rsdesc_size aml2_buffer_length) | 
 | { | 
 | 	u8 *aml1; | 
 | 	u8 *aml2; | 
 | 	u8 *aml1_end; | 
 | 	u8 *aml2_end; | 
 | 	acpi_rsdesc_size aml1_length; | 
 | 	acpi_rsdesc_size aml2_length; | 
 | 	acpi_rsdesc_size offset = 0; | 
 | 	u8 resource_type; | 
 | 	u32 count = 0; | 
 | 	u32 i; | 
 |  | 
 | 	/* Compare overall buffer sizes (may be different due to size rounding) */ | 
 |  | 
 | 	if (aml1_buffer_length != aml2_buffer_length) { | 
 | 		acpi_os_printf("**** Buffer length mismatch in converted " | 
 | 			       "AML: Original %X, New %X ****\n", | 
 | 			       aml1_buffer_length, aml2_buffer_length); | 
 | 	} | 
 |  | 
 | 	aml1 = aml1_buffer; | 
 | 	aml2 = aml2_buffer; | 
 | 	aml1_end = aml1_buffer + aml1_buffer_length; | 
 | 	aml2_end = aml2_buffer + aml2_buffer_length; | 
 |  | 
 | 	/* Walk the descriptor lists, comparing each descriptor */ | 
 |  | 
 | 	while ((aml1 < aml1_end) && (aml2 < aml2_end)) { | 
 |  | 
 | 		/* Get the lengths of each descriptor */ | 
 |  | 
 | 		aml1_length = acpi_ut_get_descriptor_length(aml1); | 
 | 		aml2_length = acpi_ut_get_descriptor_length(aml2); | 
 | 		resource_type = acpi_ut_get_resource_type(aml1); | 
 |  | 
 | 		/* Check for descriptor length match */ | 
 |  | 
 | 		if (aml1_length != aml2_length) { | 
 | 			acpi_os_printf | 
 | 			    ("**** Length mismatch in descriptor [%.2X] type %2.2X, " | 
 | 			     "Offset %8.8X Len1 %X, Len2 %X ****\n", count, | 
 | 			     resource_type, offset, aml1_length, aml2_length); | 
 | 		} | 
 |  | 
 | 		/* Check for descriptor byte match */ | 
 |  | 
 | 		else if (memcmp(aml1, aml2, aml1_length)) { | 
 | 			acpi_os_printf | 
 | 			    ("**** Data mismatch in descriptor [%.2X] type %2.2X, " | 
 | 			     "Offset %8.8X ****\n", count, resource_type, | 
 | 			     offset); | 
 |  | 
 | 			for (i = 0; i < aml1_length; i++) { | 
 | 				if (aml1[i] != aml2[i]) { | 
 | 					acpi_os_printf | 
 | 					    ("Mismatch at byte offset %.2X: is %2.2X, " | 
 | 					     "should be %2.2X\n", i, aml2[i], | 
 | 					     aml1[i]); | 
 | 				} | 
 | 			} | 
 | 		} | 
 |  | 
 | 		/* Exit on end_tag descriptor */ | 
 |  | 
 | 		if (resource_type == ACPI_RESOURCE_NAME_END_TAG) { | 
 | 			return; | 
 | 		} | 
 |  | 
 | 		/* Point to next descriptor in each buffer */ | 
 |  | 
 | 		count++; | 
 | 		offset += aml1_length; | 
 | 		aml1 += aml1_length; | 
 | 		aml2 += aml2_length; | 
 | 	} | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_dm_test_resource_conversion | 
 |  * | 
 |  * PARAMETERS:  node                - Parent device node | 
 |  *              name                - resource method name (_CRS) | 
 |  * | 
 |  * RETURN:      Status | 
 |  * | 
 |  * DESCRIPTION: Compare the original AML with a conversion of the AML to | 
 |  *              internal resource list, then back to AML. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | static acpi_status | 
 | acpi_dm_test_resource_conversion(struct acpi_namespace_node *node, char *name) | 
 | { | 
 | 	acpi_status status; | 
 | 	struct acpi_buffer return_buffer; | 
 | 	struct acpi_buffer resource_buffer; | 
 | 	struct acpi_buffer new_aml; | 
 | 	union acpi_object *original_aml; | 
 |  | 
 | 	acpi_os_printf("Resource Conversion Comparison:\n"); | 
 |  | 
 | 	new_aml.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 
 | 	return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 
 | 	resource_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 
 |  | 
 | 	/* Get the original _CRS AML resource template */ | 
 |  | 
 | 	status = acpi_evaluate_object(node, name, NULL, &return_buffer); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		acpi_os_printf("Could not obtain %s: %s\n", | 
 | 			       name, acpi_format_exception(status)); | 
 | 		return (status); | 
 | 	} | 
 |  | 
 | 	/* Get the AML resource template, converted to internal resource structs */ | 
 |  | 
 | 	status = acpi_get_current_resources(node, &resource_buffer); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		acpi_os_printf("AcpiGetCurrentResources failed: %s\n", | 
 | 			       acpi_format_exception(status)); | 
 | 		goto exit1; | 
 | 	} | 
 |  | 
 | 	/* Convert internal resource list to external AML resource template */ | 
 |  | 
 | 	status = acpi_rs_create_aml_resources(&resource_buffer, &new_aml); | 
 | 	if (ACPI_FAILURE(status)) { | 
 | 		acpi_os_printf("AcpiRsCreateAmlResources failed: %s\n", | 
 | 			       acpi_format_exception(status)); | 
 | 		goto exit2; | 
 | 	} | 
 |  | 
 | 	/* Compare original AML to the newly created AML resource list */ | 
 |  | 
 | 	original_aml = return_buffer.pointer; | 
 |  | 
 | 	acpi_dm_compare_aml_resources(original_aml->buffer.pointer, | 
 | 				      (acpi_rsdesc_size) original_aml->buffer. | 
 | 				      length, new_aml.pointer, | 
 | 				      (acpi_rsdesc_size) new_aml.length); | 
 |  | 
 | 	/* Cleanup and exit */ | 
 |  | 
 | 	ACPI_FREE(new_aml.pointer); | 
 | exit2: | 
 | 	ACPI_FREE(resource_buffer.pointer); | 
 | exit1: | 
 | 	ACPI_FREE(return_buffer.pointer); | 
 | 	return (status); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_resource_callback | 
 |  * | 
 |  * PARAMETERS:  acpi_walk_resource_callback | 
 |  * | 
 |  * RETURN:      Status | 
 |  * | 
 |  * DESCRIPTION: Simple callback to exercise acpi_walk_resources and | 
 |  *              acpi_walk_resource_buffer. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | static acpi_status | 
 | acpi_db_resource_callback(struct acpi_resource *resource, void *context) | 
 | { | 
 |  | 
 | 	return (AE_OK); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_device_resources | 
 |  * | 
 |  * PARAMETERS:  acpi_walk_callback | 
 |  * | 
 |  * RETURN:      Status | 
 |  * | 
 |  * DESCRIPTION: Display the _PRT/_CRS/_PRS resources for a device object. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | static acpi_status | 
 | acpi_db_device_resources(acpi_handle obj_handle, | 
 | 			 u32 nesting_level, void *context, void **return_value) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 | 	struct acpi_namespace_node *prt_node = NULL; | 
 | 	struct acpi_namespace_node *crs_node = NULL; | 
 | 	struct acpi_namespace_node *prs_node = NULL; | 
 | 	struct acpi_namespace_node *aei_node = NULL; | 
 | 	char *parent_path; | 
 | 	struct acpi_buffer return_buffer; | 
 | 	acpi_status status; | 
 |  | 
 | 	node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); | 
 | 	parent_path = acpi_ns_get_normalized_pathname(node, TRUE); | 
 | 	if (!parent_path) { | 
 | 		return (AE_NO_MEMORY); | 
 | 	} | 
 |  | 
 | 	/* Get handles to the resource methods for this device */ | 
 |  | 
 | 	(void)acpi_get_handle(node, METHOD_NAME__PRT, | 
 | 			      ACPI_CAST_PTR(acpi_handle, &prt_node)); | 
 | 	(void)acpi_get_handle(node, METHOD_NAME__CRS, | 
 | 			      ACPI_CAST_PTR(acpi_handle, &crs_node)); | 
 | 	(void)acpi_get_handle(node, METHOD_NAME__PRS, | 
 | 			      ACPI_CAST_PTR(acpi_handle, &prs_node)); | 
 | 	(void)acpi_get_handle(node, METHOD_NAME__AEI, | 
 | 			      ACPI_CAST_PTR(acpi_handle, &aei_node)); | 
 |  | 
 | 	if (!prt_node && !crs_node && !prs_node && !aei_node) { | 
 | 		goto cleanup;	/* Nothing to do */ | 
 | 	} | 
 |  | 
 | 	acpi_os_printf("\nDevice: %s\n", parent_path); | 
 |  | 
 | 	/* Prepare for a return object of arbitrary size */ | 
 |  | 
 | 	return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 	return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 	/* _PRT */ | 
 |  | 
 | 	if (prt_node) { | 
 | 		acpi_os_printf("Evaluating _PRT\n"); | 
 |  | 
 | 		status = | 
 | 		    acpi_evaluate_object(prt_node, NULL, NULL, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("Could not evaluate _PRT: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_crs; | 
 | 		} | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = acpi_get_irq_routing_table(node, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("GetIrqRoutingTable failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_crs; | 
 | 		} | 
 |  | 
 | 		acpi_rs_dump_irq_list(ACPI_CAST_PTR(u8, acpi_gbl_db_buffer)); | 
 | 	} | 
 |  | 
 | 	/* _CRS */ | 
 |  | 
 | get_crs: | 
 | 	if (crs_node) { | 
 | 		acpi_os_printf("Evaluating _CRS\n"); | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = | 
 | 		    acpi_evaluate_object(crs_node, NULL, NULL, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("Could not evaluate _CRS: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_prs; | 
 | 		} | 
 |  | 
 | 		/* This code exercises the acpi_walk_resources interface */ | 
 |  | 
 | 		status = acpi_walk_resources(node, METHOD_NAME__CRS, | 
 | 					     acpi_db_resource_callback, NULL); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiWalkResources failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_prs; | 
 | 		} | 
 |  | 
 | 		/* Get the _CRS resource list (test ALLOCATE buffer) */ | 
 |  | 
 | 		return_buffer.pointer = NULL; | 
 | 		return_buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; | 
 |  | 
 | 		status = acpi_get_current_resources(node, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiGetCurrentResources failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_prs; | 
 | 		} | 
 |  | 
 | 		/* This code exercises the acpi_walk_resource_buffer interface */ | 
 |  | 
 | 		status = acpi_walk_resource_buffer(&return_buffer, | 
 | 						   acpi_db_resource_callback, | 
 | 						   NULL); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiWalkResourceBuffer failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto end_crs; | 
 | 		} | 
 |  | 
 | 		/* Dump the _CRS resource list */ | 
 |  | 
 | 		acpi_rs_dump_resource_list(ACPI_CAST_PTR(struct acpi_resource, | 
 | 							 return_buffer. | 
 | 							 pointer)); | 
 |  | 
 | 		/* | 
 | 		 * Perform comparison of original AML to newly created AML. This | 
 | 		 * tests both the AML->Resource conversion and the Resource->AML | 
 | 		 * conversion. | 
 | 		 */ | 
 | 		(void)acpi_dm_test_resource_conversion(node, METHOD_NAME__CRS); | 
 |  | 
 | 		/* Execute _SRS with the resource list */ | 
 |  | 
 | 		acpi_os_printf("Evaluating _SRS\n"); | 
 |  | 
 | 		status = acpi_set_current_resources(node, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiSetCurrentResources failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto end_crs; | 
 | 		} | 
 |  | 
 | end_crs: | 
 | 		ACPI_FREE(return_buffer.pointer); | 
 | 	} | 
 |  | 
 | 	/* _PRS */ | 
 |  | 
 | get_prs: | 
 | 	if (prs_node) { | 
 | 		acpi_os_printf("Evaluating _PRS\n"); | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = | 
 | 		    acpi_evaluate_object(prs_node, NULL, NULL, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("Could not evaluate _PRS: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_aei; | 
 | 		} | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = acpi_get_possible_resources(node, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiGetPossibleResources failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto get_aei; | 
 | 		} | 
 |  | 
 | 		acpi_rs_dump_resource_list(ACPI_CAST_PTR | 
 | 					   (struct acpi_resource, | 
 | 					    acpi_gbl_db_buffer)); | 
 | 	} | 
 |  | 
 | 	/* _AEI */ | 
 |  | 
 | get_aei: | 
 | 	if (aei_node) { | 
 | 		acpi_os_printf("Evaluating _AEI\n"); | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = | 
 | 		    acpi_evaluate_object(aei_node, NULL, NULL, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("Could not evaluate _AEI: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto cleanup; | 
 | 		} | 
 |  | 
 | 		return_buffer.pointer = acpi_gbl_db_buffer; | 
 | 		return_buffer.length = ACPI_DEBUG_BUFFER_SIZE; | 
 |  | 
 | 		status = acpi_get_event_resources(node, &return_buffer); | 
 | 		if (ACPI_FAILURE(status)) { | 
 | 			acpi_os_printf("AcpiGetEventResources failed: %s\n", | 
 | 				       acpi_format_exception(status)); | 
 | 			goto cleanup; | 
 | 		} | 
 |  | 
 | 		acpi_rs_dump_resource_list(ACPI_CAST_PTR | 
 | 					   (struct acpi_resource, | 
 | 					    acpi_gbl_db_buffer)); | 
 | 	} | 
 |  | 
 | cleanup: | 
 | 	ACPI_FREE(parent_path); | 
 | 	return (AE_OK); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_display_resources | 
 |  * | 
 |  * PARAMETERS:  object_arg          - String object name or object pointer. | 
 |  *                                    NULL or "*" means "display resources for | 
 |  *                                    all devices" | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Display the resource objects associated with a device. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_display_resources(char *object_arg) | 
 | { | 
 | 	struct acpi_namespace_node *node; | 
 |  | 
 | 	acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); | 
 | 	acpi_dbg_level |= ACPI_LV_RESOURCES; | 
 |  | 
 | 	/* Asterisk means "display resources for all devices" */ | 
 |  | 
 | 	if (!object_arg || (!strcmp(object_arg, "*"))) { | 
 | 		(void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 
 | 					  ACPI_UINT32_MAX, | 
 | 					  acpi_db_device_resources, NULL, NULL, | 
 | 					  NULL); | 
 | 	} else { | 
 | 		/* Convert string to object pointer */ | 
 |  | 
 | 		node = acpi_db_convert_to_node(object_arg); | 
 | 		if (node) { | 
 | 			if (node->type != ACPI_TYPE_DEVICE) { | 
 | 				acpi_os_printf | 
 | 				    ("%4.4s: Name is not a device object (%s)\n", | 
 | 				     node->name.ascii, | 
 | 				     acpi_ut_get_type_name(node->type)); | 
 | 			} else { | 
 | 				(void)acpi_db_device_resources(node, 0, NULL, | 
 | 							       NULL); | 
 | 			} | 
 | 		} | 
 | 	} | 
 |  | 
 | 	acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); | 
 | } | 
 |  | 
 | #if (!ACPI_REDUCED_HARDWARE) | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_generate_gpe | 
 |  * | 
 |  * PARAMETERS:  gpe_arg             - Raw GPE number, ascii string | 
 |  *              block_arg           - GPE block number, ascii string | 
 |  *                                    0 or 1 for FADT GPE blocks | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Simulate firing of a GPE | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_generate_gpe(char *gpe_arg, char *block_arg) | 
 | { | 
 | 	u32 block_number = 0; | 
 | 	u32 gpe_number; | 
 | 	struct acpi_gpe_event_info *gpe_event_info; | 
 |  | 
 | 	gpe_number = strtoul(gpe_arg, NULL, 0); | 
 |  | 
 | 	/* | 
 | 	 * If no block arg, or block arg == 0 or 1, use the FADT-defined | 
 | 	 * GPE blocks. | 
 | 	 */ | 
 | 	if (block_arg) { | 
 | 		block_number = strtoul(block_arg, NULL, 0); | 
 | 		if (block_number == 1) { | 
 | 			block_number = 0; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	gpe_event_info = | 
 | 	    acpi_ev_get_gpe_event_info(ACPI_TO_POINTER(block_number), | 
 | 				       gpe_number); | 
 | 	if (!gpe_event_info) { | 
 | 		acpi_os_printf("Invalid GPE\n"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	(void)acpi_ev_gpe_dispatch(NULL, gpe_event_info, gpe_number); | 
 | } | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_generate_sci | 
 |  * | 
 |  * PARAMETERS:  None | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Simulate an SCI -- just call the SCI dispatch. | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_generate_sci(void) | 
 | { | 
 | 	acpi_ev_sci_dispatch(); | 
 | } | 
 |  | 
 | #endif				/* !ACPI_REDUCED_HARDWARE */ | 
 |  | 
 | /******************************************************************************* | 
 |  * | 
 |  * FUNCTION:    acpi_db_trace | 
 |  * | 
 |  * PARAMETERS:  enable_arg          - ENABLE/AML to enable tracer | 
 |  *                                    DISABLE to disable tracer | 
 |  *              method_arg          - Method to trace | 
 |  *              once_arg            - Whether trace once | 
 |  * | 
 |  * RETURN:      None | 
 |  * | 
 |  * DESCRIPTION: Control method tracing facility | 
 |  * | 
 |  ******************************************************************************/ | 
 |  | 
 | void acpi_db_trace(char *enable_arg, char *method_arg, char *once_arg) | 
 | { | 
 | 	u32 debug_level = 0; | 
 | 	u32 debug_layer = 0; | 
 | 	u32 flags = 0; | 
 |  | 
 | 	acpi_ut_strupr(enable_arg); | 
 | 	acpi_ut_strupr(once_arg); | 
 |  | 
 | 	if (method_arg) { | 
 | 		if (acpi_db_trace_method_name) { | 
 | 			ACPI_FREE(acpi_db_trace_method_name); | 
 | 			acpi_db_trace_method_name = NULL; | 
 | 		} | 
 |  | 
 | 		acpi_db_trace_method_name = | 
 | 		    ACPI_ALLOCATE(strlen(method_arg) + 1); | 
 | 		if (!acpi_db_trace_method_name) { | 
 | 			acpi_os_printf("Failed to allocate method name (%s)\n", | 
 | 				       method_arg); | 
 | 			return; | 
 | 		} | 
 |  | 
 | 		strcpy(acpi_db_trace_method_name, method_arg); | 
 | 	} | 
 |  | 
 | 	if (!strcmp(enable_arg, "ENABLE") || | 
 | 	    !strcmp(enable_arg, "METHOD") || !strcmp(enable_arg, "OPCODE")) { | 
 | 		if (!strcmp(enable_arg, "ENABLE")) { | 
 |  | 
 | 			/* Inherit current console settings */ | 
 |  | 
 | 			debug_level = acpi_gbl_db_console_debug_level; | 
 | 			debug_layer = acpi_dbg_layer; | 
 | 		} else { | 
 | 			/* Restrict console output to trace points only */ | 
 |  | 
 | 			debug_level = ACPI_LV_TRACE_POINT; | 
 | 			debug_layer = ACPI_EXECUTER; | 
 | 		} | 
 |  | 
 | 		flags = ACPI_TRACE_ENABLED; | 
 |  | 
 | 		if (!strcmp(enable_arg, "OPCODE")) { | 
 | 			flags |= ACPI_TRACE_OPCODE; | 
 | 		} | 
 |  | 
 | 		if (once_arg && !strcmp(once_arg, "ONCE")) { | 
 | 			flags |= ACPI_TRACE_ONESHOT; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	(void)acpi_debug_trace(acpi_db_trace_method_name, | 
 | 			       debug_level, debug_layer, flags); | 
 | } |