patch-2.4.6 linux/drivers/acpi/debugger/dbinput.c

Next file: linux/drivers/acpi/debugger/dbstats.c
Previous file: linux/drivers/acpi/debugger/dbhistry.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.5/linux/drivers/acpi/debugger/dbinput.c linux/drivers/acpi/debugger/dbinput.c
@@ -0,0 +1,909 @@
+/*******************************************************************************
+ *
+ * Module Name: dbinput - user front-end to the AML debugger
+ *              $Revision: 61 $
+ *
+ ******************************************************************************/
+
+/*
+ *  Copyright (C) 2000, 2001 R. Byron Moore
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "acpi.h"
+#include "acparser.h"
+#include "actables.h"
+#include "acnamesp.h"
+#include "acinterp.h"
+#include "acdebug.h"
+
+
+#ifdef ENABLE_DEBUGGER
+
+#define _COMPONENT          ACPI_DEBUGGER
+	 MODULE_NAME         ("dbinput")
+
+
+/*
+ * Globals that are specific to the debugger
+ */
+
+NATIVE_CHAR             line_buf[80];
+NATIVE_CHAR             parsed_buf[80];
+NATIVE_CHAR             scope_buf[40];
+NATIVE_CHAR             debug_filename[40];
+NATIVE_CHAR             *args[DB_MAX_ARGS];
+NATIVE_CHAR             *buffer;
+NATIVE_CHAR             *filename = NULL;
+u8                      output_to_file = FALSE;
+
+
+u32                     acpi_gbl_db_debug_level = 0x0FFFFFFF;
+u32                     acpi_gbl_db_console_debug_level = NORMAL_DEFAULT | TRACE_TABLES;
+u8                      acpi_gbl_db_output_flags = DB_CONSOLE_OUTPUT;
+
+
+u8                      opt_tables      = FALSE;
+u8                      opt_disasm      = FALSE;
+u8                      opt_stats       = FALSE;
+u8                      opt_parse_jit   = FALSE;
+u8                      opt_verbose     = TRUE;
+u8                      opt_ini_methods = TRUE;
+
+
+/*
+ * Top-level debugger commands.
+ *
+ * This list of commands must match the string table below it
+ */
+
+enum acpi_ex_debugger_commands
+{
+	CMD_NOT_FOUND = 0,
+	CMD_NULL,
+	CMD_ALLOCATIONS,
+	CMD_ARGS,
+	CMD_ARGUMENTS,
+	CMD_BREAKPOINT,
+	CMD_CALL,
+	CMD_CLOSE,
+	CMD_DEBUG,
+	CMD_DUMP,
+	CMD_ENABLEACPI,
+	CMD_EVENT,
+	CMD_EXECUTE,
+	CMD_EXIT,
+	CMD_FIND,
+	CMD_GO,
+	CMD_HELP,
+	CMD_HELP2,
+	CMD_HISTORY,
+	CMD_HISTORY_EXE,
+	CMD_HISTORY_LAST,
+	CMD_INFORMATION,
+	CMD_INTO,
+	CMD_LEVEL,
+	CMD_LIST,
+	CMD_LOAD,
+	CMD_LOCALS,
+	CMD_LOCKS,
+	CMD_METHODS,
+	CMD_NAMESPACE,
+	CMD_NOTIFY,
+	CMD_OBJECT,
+	CMD_OPEN,
+	CMD_OWNER,
+	CMD_PREFIX,
+	CMD_QUIT,
+	CMD_REFERENCES,
+	CMD_RESOURCES,
+	CMD_RESULTS,
+	CMD_SET,
+	CMD_STATS,
+	CMD_STOP,
+	CMD_TABLES,
+	CMD_TERMINATE,
+	CMD_THREADS,
+	CMD_TREE,
+	CMD_UNLOAD
+};
+
+#define CMD_FIRST_VALID     2
+
+
+COMMAND_INFO                commands[] =
+{ {"<NOT FOUND>",  0},
+	{"<NULL>",       0},
+	{"ALLOCATIONS",  0},
+	{"ARGS",         0},
+	{"ARGUMENTS",    0},
+	{"BREAKPOINT",   1},
+	{"CALL",         0},
+	{"CLOSE",        0},
+	{"DEBUG",        1},
+	{"DUMP",         1},
+	{"ENABLEACPI",   0},
+	{"EVENT",        1},
+	{"EXECUTE",      1},
+	{"EXIT",         0},
+	{"FIND",         1},
+	{"GO",           0},
+	{"HELP",         0},
+	{"?",            0},
+	{"HISTORY",      0},
+	{"!",            1},
+	{"!!",           0},
+	{"INFORMATION",  0},
+	{"INTO",         0},
+	{"LEVEL",        0},
+	{"LIST",         0},
+	{"LOAD",         1},
+	{"LOCALS",       0},
+	{"LOCKS",        0},
+	{"METHODS",      0},
+	{"NAMESPACE",    0},
+	{"NOTIFY",       2},
+	{"OBJECT",       1},
+	{"OPEN",         1},
+	{"OWNER",        1},
+	{"PREFIX",       0},
+	{"QUIT",         0},
+	{"REFERENCES",   1},
+	{"RESOURCES",    1},
+	{"RESULTS",      0},
+	{"SET",          3},
+	{"STATS",        0},
+	{"STOP",         0},
+	{"TABLES",       0},
+	{"TERMINATE",    0},
+	{"THREADS",      3},
+	{"TREE",         0},
+	{"UNLOAD",       0},
+	{NULL,           0}
+};
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_display_help
+ *
+ * PARAMETERS:  Help_type       - Subcommand (optional)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print a usage message.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_display_help (
+	NATIVE_CHAR             *help_type)
+{
+
+
+	/* No parameter, just give the overview */
+
+	if (!help_type)
+	{
+		acpi_os_printf ("ACPI CA Debugger Commands\n\n");
+		acpi_os_printf ("The following classes of commands are available. Help is available for\n");
+		acpi_os_printf ("each class by entering \"help <class_name>\"\n\n");
+		acpi_os_printf ("  [GENERAL]       General-Purpose Commands\n");
+		acpi_os_printf ("  [NAMESPACE]     Namespace Access Commands\n");
+		acpi_os_printf ("  [METHOD]        Control Method Execution Commands\n");
+		acpi_os_printf ("  [FILE]          File I/O Commands\n");
+		return;
+
+	}
+
+
+	/*
+	 * Parameter is the command class
+	 *
+	 * The idea here is to keep each class of commands smaller than a screenful
+	 */
+
+	switch (help_type[0])
+	{
+	case 'G':
+		acpi_os_printf ("\n_general-Purpose Commands\n\n");
+		acpi_os_printf ("Allocations                       Display list of current memory allocations\n");
+		acpi_os_printf ("Dump <Address>|<Namepath>\n");
+		acpi_os_printf ("   [Byte|Word|Dword|Qword]        Display ACPI objects or memory\n");
+		acpi_os_printf ("Enable_acpi                       Enable ACPI (hardware) mode\n");
+		acpi_os_printf ("Help                              This help screen\n");
+		acpi_os_printf ("History                           Display command history buffer\n");
+		acpi_os_printf ("Level [<Debug_level>] [console]   Get/Set debug level for file or console\n");
+		acpi_os_printf ("Locks                             Current status of internal mutexes\n");
+		acpi_os_printf ("Quit or Exit                      Exit this command\n");
+		acpi_os_printf ("Stats [Allocations|Memory|Misc\n");
+		acpi_os_printf ("     |Objects|Tables]             Display namespace and memory statistics\n");
+		acpi_os_printf ("Tables                            Display info about loaded ACPI tables\n");
+		acpi_os_printf ("Unload                            Unload an ACPI table\n");
+		acpi_os_printf ("! <Command_number>                Execute command from history buffer\n");
+		acpi_os_printf ("!!                                Execute last command again\n");
+		return;
+
+	case 'N':
+		acpi_os_printf ("\n_namespace Access Commands\n\n");
+		acpi_os_printf ("Debug <Namepath> [Arguments]      Single Step a control method\n");
+		acpi_os_printf ("Event <F|G> <Value>               Generate Acpi_event (Fixed/GPE)\n");
+		acpi_os_printf ("Execute <Namepath> [Arguments]    Execute control method\n");
+		acpi_os_printf ("Find <Name> (? is wildcard)       Find ACPI name(s) with wildcards\n");
+		acpi_os_printf ("Method                            Display list of loaded control methods\n");
+		acpi_os_printf ("Namespace [<Addr>|<Path>] [Depth] Display loaded namespace tree/subtree\n");
+		acpi_os_printf ("Notify <Name_path> <Value>        Send a notification\n");
+		acpi_os_printf ("Objects <Object_type>             Display all objects of the given type\n");
+		acpi_os_printf ("Owner <Owner_id> [Depth]          Display loaded namespace by object owner\n");
+		acpi_os_printf ("Prefix [<Name_path>]              Set or Get current execution prefix\n");
+		acpi_os_printf ("References <Addr>                 Find all references to object at addr\n");
+		acpi_os_printf ("Resources xxx                     Get and display resources\n");
+		acpi_os_printf ("Terminate                         Delete namespace and all internal objects\n");
+		acpi_os_printf ("Thread <Threads><Loops><Name_path> Spawn threads to execute method(s)\n");
+		return;
+
+	case 'M':
+		acpi_os_printf ("\n_control Method Execution Commands\n\n");
+		acpi_os_printf ("Arguments (or Args)               Display method arguments\n");
+		acpi_os_printf ("Breakpoint <Aml_offset>           Set an AML execution breakpoint\n");
+		acpi_os_printf ("Call                              Run to next control method invocation\n");
+		acpi_os_printf ("Go                                Allow method to run to completion\n");
+		acpi_os_printf ("Information                       Display info about the current method\n");
+		acpi_os_printf ("Into                              Step into (not over) a method call\n");
+		acpi_os_printf ("List [# of Aml Opcodes]           Display method ASL statements\n");
+		acpi_os_printf ("Locals                            Display method local variables\n");
+		acpi_os_printf ("Results                           Display method result stack\n");
+		acpi_os_printf ("Set <A|L> <#> <Value>             Set method data (Arguments/Locals)\n");
+		acpi_os_printf ("Stop                              Terminate control method\n");
+		acpi_os_printf ("Tree                              Display control method calling tree\n");
+		acpi_os_printf ("<Enter>                           Single step next AML opcode (over calls)\n");
+		return;
+
+	case 'F':
+		acpi_os_printf ("\n_file I/O Commands\n\n");
+		acpi_os_printf ("Close                             Close debug output file\n");
+		acpi_os_printf ("Open <Output Filename>            Open a file for debug output\n");
+		acpi_os_printf ("Load <Input Filename>             Load ACPI table from a file\n");
+		return;
+
+	default:
+		acpi_os_printf ("Unrecognized Command Class: %x\n", help_type);
+		return;
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_next_token
+ *
+ * PARAMETERS:  String          - Command buffer
+ *              Next            - Return value, end of next token
+ *
+ * RETURN:      Pointer to the start of the next token.
+ *
+ * DESCRIPTION: Command line parsing.  Get the next token on the command line
+ *
+ ******************************************************************************/
+
+NATIVE_CHAR *
+acpi_db_get_next_token (
+	NATIVE_CHAR             *string,
+	NATIVE_CHAR             **next)
+{
+	NATIVE_CHAR             *start;
+
+	/* At end of buffer? */
+
+	if (!string || !(*string))
+	{
+		return (NULL);
+	}
+
+
+	/* Get rid of any spaces at the beginning */
+
+	if (*string == ' ')
+	{
+		while (*string && (*string == ' '))
+		{
+			string++;
+		}
+
+		if (!(*string))
+		{
+			return (NULL);
+		}
+	}
+
+	start = string;
+
+	/* Find end of token */
+
+	while (*string && (*string != ' '))
+	{
+		string++;
+	}
+
+
+	if (!(*string))
+	{
+		*next = NULL;
+	}
+
+	else
+	{
+		*string = 0;
+		*next = string + 1;
+	}
+
+	return (start);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_get_line
+ *
+ * PARAMETERS:  Input_buffer        - Command line buffer
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Get the next command line from the user.  Gets entire line
+ *              up to the next newline
+ *
+ ******************************************************************************/
+
+u32
+acpi_db_get_line (
+	NATIVE_CHAR             *input_buffer)
+{
+	u32                     i;
+	u32                     count;
+	NATIVE_CHAR             *next;
+	NATIVE_CHAR             *this;
+
+
+	STRCPY (parsed_buf, input_buffer);
+	STRUPR (parsed_buf);
+
+	this = parsed_buf;
+	for (i = 0; i < DB_MAX_ARGS; i++)
+	{
+		args[i] = acpi_db_get_next_token (this, &next);
+		if (!args[i])
+		{
+			break;
+		}
+
+		this = next;
+	}
+
+
+	/* Uppercase the actual command */
+
+	if (args[0])
+	{
+		STRUPR (args[0]);
+	}
+
+	count = i;
+	if (count)
+	{
+		count--;  /* Number of args only */
+	}
+
+	return (count);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_match_command
+ *
+ * PARAMETERS:  User_command            - User command line
+ *
+ * RETURN:      Index into command array, -1 if not found
+ *
+ * DESCRIPTION: Search command array for a command match
+ *
+ ******************************************************************************/
+
+u32
+acpi_db_match_command (
+	NATIVE_CHAR             *user_command)
+{
+	u32                     i;
+
+
+	if (!user_command || user_command[0] == 0)
+	{
+		return (CMD_NULL);
+	}
+
+	for (i = CMD_FIRST_VALID; commands[i].name; i++)
+	{
+		if (STRSTR (commands[i].name, user_command) == commands[i].name)
+		{
+			return (i);
+		}
+	}
+
+	/* Command not recognized */
+
+	return (CMD_NOT_FOUND);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_command_dispatch
+ *
+ * PARAMETERS:  Input_buffer        - Command line buffer
+ *              Walk_state          - Current walk
+ *              Op                  - Current (executing) parse op
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Command dispatcher.  Called from two places:
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_command_dispatch (
+	NATIVE_CHAR             *input_buffer,
+	ACPI_WALK_STATE         *walk_state,
+	ACPI_PARSE_OBJECT       *op)
+{
+	u32                     temp;
+	u32                     command_index;
+	u32                     param_count;
+	NATIVE_CHAR             *command_line;
+	ACPI_STATUS             status = AE_CTRL_TRUE;
+
+
+	/* If Acpi_terminate has been called, terminate this thread */
+
+	if (acpi_gbl_db_terminate_threads)
+	{
+		return (AE_CTRL_TERMINATE);
+	}
+
+	param_count = acpi_db_get_line (input_buffer);
+	command_index = acpi_db_match_command (args[0]);
+	temp = 0;
+
+	/* Verify that we have the minimum number of params */
+
+	if (param_count < commands[command_index].min_args)
+	{
+		acpi_os_printf ("%d parameters entered, [%s] requires %d parameters\n",
+				  param_count, commands[command_index].name, commands[command_index].min_args);
+		return (AE_CTRL_TRUE);
+	}
+
+	/* Decode and dispatch the command */
+
+	switch (command_index)
+	{
+	case CMD_NULL:
+		if (op)
+		{
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_ALLOCATIONS:
+		acpi_ut_dump_current_allocations ((u32) -1, NULL);
+		break;
+
+	case CMD_ARGS:
+	case CMD_ARGUMENTS:
+		acpi_db_display_arguments ();
+		break;
+
+	case CMD_BREAKPOINT:
+		acpi_db_set_method_breakpoint (args[1], walk_state, op);
+		break;
+
+	case CMD_CALL:
+		acpi_db_set_method_call_breakpoint (op);
+		status = AE_OK;
+		break;
+
+	case CMD_CLOSE:
+		acpi_db_close_debug_file ();
+		break;
+
+	case CMD_DEBUG:
+		acpi_db_execute (args[1], &args[2], EX_SINGLE_STEP);
+		break;
+
+	case CMD_DUMP:
+		acpi_db_decode_and_display_object (args[1], args[2]);
+		break;
+
+	case CMD_ENABLEACPI:
+		status = acpi_enable();
+		if (ACPI_FAILURE(status))
+		{
+			acpi_os_printf("Acpi_enable failed (Status=%X)\n", status);
+			return (status);
+		}
+		break;
+
+	case CMD_EVENT:
+		acpi_os_printf ("Event command not implemented\n");
+		break;
+
+	case CMD_EXECUTE:
+		acpi_db_execute (args[1], &args[2], EX_NO_SINGLE_STEP);
+		break;
+
+	case CMD_FIND:
+		acpi_db_find_name_in_namespace (args[1]);
+		break;
+
+	case CMD_GO:
+		acpi_gbl_cm_single_step = FALSE;
+		return (AE_OK);
+
+	case CMD_HELP:
+	case CMD_HELP2:
+		acpi_db_display_help (args[1]);
+		break;
+
+	case CMD_HISTORY:
+		acpi_db_display_history ();
+		break;
+
+	case CMD_HISTORY_EXE:
+		command_line = acpi_db_get_from_history (args[1]);
+		if (!command_line)
+		{
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch (command_line, walk_state, op);
+		if (ACPI_SUCCESS (status))
+		{
+			status = AE_CTRL_TRUE;
+		}
+		return (status);
+		break;
+
+	case CMD_HISTORY_LAST:
+		command_line = acpi_db_get_from_history (NULL);
+		if (!command_line)
+		{
+			return (AE_CTRL_TRUE);
+		}
+
+		status = acpi_db_command_dispatch (command_line, walk_state, op);
+		if (ACPI_SUCCESS (status))
+		{
+			status = AE_CTRL_TRUE;
+		}
+		return (status);
+
+	case CMD_INFORMATION:
+		acpi_db_display_method_info (op);
+		break;
+
+	case CMD_INTO:
+		if (op)
+		{
+			acpi_gbl_cm_single_step = TRUE;
+
+/* TBD: Must get current walk state */
+			/* Acpi_gbl_Method_breakpoint = 0; */
+			return (AE_OK);
+		}
+		break;
+
+	case CMD_LEVEL:
+		if (param_count == 0)
+		{
+			acpi_os_printf ("Current debug level for file output is:  %8.8lX\n", acpi_gbl_db_debug_level);
+			acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level);
+		}
+		else if (param_count == 2)
+		{
+			temp = acpi_gbl_db_console_debug_level;
+			acpi_gbl_db_console_debug_level = STRTOUL (args[1], NULL, 16);
+			acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level);
+		}
+		else
+		{
+			temp = acpi_gbl_db_debug_level;
+			acpi_gbl_db_debug_level = STRTOUL (args[1], NULL, 16);
+			acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level);
+		}
+		break;
+
+	case CMD_LIST:
+		acpi_db_disassemble_aml (args[1], op);
+		break;
+
+	case CMD_LOAD:
+		status = acpi_db_load_acpi_table (args[1]);
+		if (ACPI_FAILURE (status))
+		{
+			return (status);
+		}
+		break;
+
+	case CMD_LOCKS:
+		acpi_db_display_locks ();
+		break;
+
+	case CMD_LOCALS:
+		acpi_db_display_locals ();
+		break;
+
+	case CMD_METHODS:
+		acpi_db_display_objects ("METHOD", args[1]);
+		break;
+
+	case CMD_NAMESPACE:
+		acpi_db_dump_namespace (args[1], args[2]);
+		break;
+
+	case CMD_NOTIFY:
+		temp = STRTOUL (args[2], NULL, 0);
+		acpi_db_send_notify (args[1], temp);
+		break;
+
+	case CMD_OBJECT:
+		acpi_db_display_objects (STRUPR (args[1]), args[2]);
+		break;
+
+	case CMD_OPEN:
+		acpi_db_open_debug_file (args[1]);
+		break;
+
+	case CMD_OWNER:
+		acpi_db_dump_namespace_by_owner (args[1], args[2]);
+		break;
+
+	case CMD_PREFIX:
+		acpi_db_set_scope (args[1]);
+		break;
+
+	case CMD_REFERENCES:
+		acpi_db_find_references (args[1]);
+		break;
+
+	case CMD_RESOURCES:
+		acpi_db_display_resources (args[1]);
+		break;
+
+	case CMD_RESULTS:
+		acpi_db_display_results ();
+		break;
+
+	case CMD_SET:
+		acpi_db_set_method_data (args[1], args[2], args[3]);
+		break;
+
+	case CMD_STATS:
+		acpi_db_display_statistics (args[1]);
+		break;
+
+	case CMD_STOP:
+		return (AE_AML_ERROR);
+		break;
+
+	case CMD_TABLES:
+		acpi_db_display_table_info (args[1]);
+		break;
+
+	case CMD_TERMINATE:
+		acpi_db_set_output_destination (DB_REDIRECTABLE_OUTPUT);
+		acpi_ut_subsystem_shutdown ();
+
+		/* TBD: [Restructure] Need some way to re-initialize without re-creating the semaphores! */
+
+		/*  Acpi_initialize (NULL); */
+		break;
+
+	case CMD_THREADS:
+		acpi_db_create_execution_threads (args[1], args[2], args[3]);
+		break;
+
+	case CMD_TREE:
+		acpi_db_display_calling_tree ();
+		break;
+
+	case CMD_UNLOAD:
+		acpi_db_unload_acpi_table (args[1], args[2]);
+		break;
+
+	case CMD_EXIT:
+	case CMD_QUIT:
+		if (op)
+		{
+			acpi_os_printf ("Method execution terminated\n");
+			return (AE_CTRL_TERMINATE);
+		}
+
+		if (!output_to_file)
+		{
+			acpi_dbg_level = DEBUG_DEFAULT;
+		}
+
+		/* Shutdown */
+
+		/* Acpi_ut_subsystem_shutdown (); */
+		acpi_db_close_debug_file ();
+
+		acpi_gbl_db_terminate_threads = TRUE;
+
+		return (AE_CTRL_TERMINATE);
+
+	case CMD_NOT_FOUND:
+		acpi_os_printf ("Unknown Command\n");
+		return (AE_CTRL_TRUE);
+	}
+
+
+	/* Add all commands that come here to the history buffer */
+
+	acpi_db_add_to_history (input_buffer);
+	return (status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_execute_thread
+ *
+ * PARAMETERS:  Context         - Not used
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_execute_thread (
+	void                    *context)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	while (status != AE_CTRL_TERMINATE)
+	{
+		acpi_gbl_method_executing = FALSE;
+		acpi_gbl_step_to_next_call = FALSE;
+
+		acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_READY);
+		status = acpi_db_command_dispatch (line_buf, NULL, NULL);
+		acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+	}
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_single_thread
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Debugger execute thread.  Waits for a command line, then
+ *              simply dispatches it.
+ *
+ ******************************************************************************/
+
+void
+acpi_db_single_thread (
+	void)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	acpi_gbl_method_executing = FALSE;
+	acpi_gbl_step_to_next_call = FALSE;
+
+	status = acpi_db_command_dispatch (line_buf, NULL, NULL);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    Acpi_db_user_commands
+ *
+ * PARAMETERS:  Prompt              - User prompt (depends on mode)
+ *              Op                  - Current executing parse op
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Command line execution for the AML debugger.  Commands are
+ *              matched and dispatched here.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+acpi_db_user_commands (
+	NATIVE_CHAR             prompt,
+	ACPI_PARSE_OBJECT       *op)
+{
+	ACPI_STATUS             status = AE_OK;
+
+
+	/* TBD: [Restructure] Need a separate command line buffer for step mode */
+
+	while (!acpi_gbl_db_terminate_threads)
+	{
+		/* Force output to console until a command is entered */
+
+		acpi_db_set_output_destination (DB_CONSOLE_OUTPUT);
+
+		/* Different prompt if method is executing */
+
+		if (!acpi_gbl_method_executing)
+		{
+			acpi_os_printf ("%1c ", DB_COMMAND_PROMPT);
+		}
+		else
+		{
+			acpi_os_printf ("%1c ", DB_EXECUTE_PROMPT);
+		}
+
+		/* Get the user input line */
+
+		acpi_os_get_line (line_buf);
+
+
+		/* Check for single or multithreaded debug */
+
+		if (acpi_gbl_debugger_configuration & DEBUGGER_MULTI_THREADED)
+		{
+			/*
+			 * Signal the debug thread that we have a command to execute,
+			 * and wait for the command to complete.
+			 */
+
+			acpi_ut_release_mutex (ACPI_MTX_DEBUG_CMD_READY);
+			acpi_ut_acquire_mutex (ACPI_MTX_DEBUG_CMD_COMPLETE);
+		}
+
+		else
+		{
+			/* Just call to the command line interpreter */
+
+			acpi_db_single_thread ();
+		}
+	}
+
+
+	/*
+	 * Only this thread (the original thread) should actually terminate the subsystem,
+	 * because all the semaphores are deleted during termination
+	 */
+	acpi_terminate ();
+
+	return (status);
+}
+
+
+#endif  /* ENABLE_DEBUGGER */
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)