# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/03/13 00:35:17-05:00 len.brown@intel.com 
#   [ACPI] ACPICA 20040311 from Bob Moore
#   
#   Fixed a problem where errors occurring during the parse phase of control
#   method execution did not abort cleanly.  For example, objects created
#   and installed in the namespace were not deleted.  This caused all
#   subsequent invocations of the method to return the AE_ALREADY_EXISTS
#   exception.
#   
#   Implemented a mechanism to force a control method to "Serialized"
#   execution if the method attempts to create namespace objects.
#   (The root of the AE_ALREADY_EXISTS problem.)
#   
#   Implemented support for the predefined _OSI "internal" control method.
#   Initial supported strings are "Linux", "Windows 2000", "Windows 2001",
#   and "Windows 2001.1", and can be easily upgraded for new strings as
#   necessary.  This feature allows Linux to execute
#   the fully tested, "Windows" code path through the ASL code
#   
#   Global Lock Support:  Now allows multiple acquires and releases with any
#   internal thread.  Removed concept of "owning thread" for this special
#   mutex.
#   
#   Fixed two functions that were inappropriately declaring large objects on
#   the CPU stack: ps_parse_loop() and ns_evaluate_relative().
#   Reduces the stack usage during method execution considerably.
#   
#   Fixed a problem in the ACPI 2.0 FACS descriptor (actbl2.h) where the
#   S4Bios_f field was incorrectly defined as UINT32 instead of UINT32_BIT.
#   
#   Fixed a problem where acpi_ev_gpe_detect() would fault
#   if there were no GPEs defined on the machine.
#   
#   Implemented two runtime options:  One to force all control method
#   execution to "Serialized" to mimic Windows behavior, another to disable
#   _OSI support if it causes problems on a given machine.
# 
# include/acpi/amlcode.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +10 -4
#   ACPICA 20040311
# 
# include/acpi/acutils.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +4 -2
#   ACPICA 20040311
# 
# include/acpi/actypes.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +1 -4
#   ACPICA 20040311
# 
# include/acpi/acobject.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +6 -1
#   ACPICA 20040311
# 
# include/acpi/acmacros.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +0 -3
#   ACPICA 20040311
# 
# include/acpi/acglobal.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +10 -1
#   ACPICA 20040311
# 
# include/acpi/acconfig.h
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +5 -1
#   ACPICA 20040311
# 
# drivers/acpi/utilities/utglobal.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +17 -11
#   ACPICA 20040311
# 
# drivers/acpi/utilities/uteval.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +56 -0
#   ACPICA 20040311
# 
# drivers/acpi/parser/psscope.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +2 -7
#   ACPICA 20040311
# 
# drivers/acpi/parser/psparse.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +39 -5
#   ACPICA 20040311
# 
# drivers/acpi/namespace/nseval.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +11 -4
#   ACPICA 20040311
# 
# drivers/acpi/namespace/nsalloc.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +4 -3
#   ACPICA 20040311
# 
# drivers/acpi/namespace/nsaccess.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +22 -8
#   ACPICA 20040311
# 
# drivers/acpi/executer/exmutex.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +17 -11
#   ACPICA 20040311
# 
# drivers/acpi/executer/excreate.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +13 -7
#   ACPICA 20040311
# 
# drivers/acpi/events/evgpe.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +5 -0
#   ACPICA 20040311
# 
# drivers/acpi/dispatcher/dsmethod.c
#   2004/03/12 19:29:42-05:00 len.brown@intel.com +58 -27
#   ACPICA 20040311
# 
diff -Nru a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
--- a/drivers/acpi/dispatcher/dsmethod.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/dispatcher/dsmethod.c	Sat Mar 13 02:20:35 2004
@@ -106,7 +106,7 @@
 
 	/* Create a mutex for the method if there is a concurrency limit */
 
-	if ((obj_desc->method.concurrency != INFINITE_CONCURRENCY) &&
+	if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
 		(!obj_desc->method.semaphore)) {
 		status = acpi_os_create_semaphore (obj_desc->method.concurrency,
 				   obj_desc->method.concurrency,
@@ -300,34 +300,37 @@
 		return_ACPI_STATUS (status);
 	}
 
-	/* 1) Parse: Create a new walk state for the preempting walk */
+	if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
+		/* 1) Parse: Create a new walk state for the preempting walk */
 
-	next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
-			  op, obj_desc, NULL);
-	if (!next_walk_state) {
-		return_ACPI_STATUS (AE_NO_MEMORY);
-	}
+		next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
+				  op, obj_desc, NULL);
+		if (!next_walk_state) {
+			return_ACPI_STATUS (AE_NO_MEMORY);
+		}
 
-	/* Create and init a Root Node */
 
-	op = acpi_ps_create_scope_op ();
-	if (!op) {
-		status = AE_NO_MEMORY;
-		goto cleanup;
-	}
+		/* Create and init a Root Node */
 
-	status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
-			  obj_desc->method.aml_start, obj_desc->method.aml_length,
-			  NULL, NULL, 1);
-	if (ACPI_FAILURE (status)) {
-		acpi_ds_delete_walk_state (next_walk_state);
-		goto cleanup;
-	}
+		op = acpi_ps_create_scope_op ();
+		if (!op) {
+			status = AE_NO_MEMORY;
+			goto cleanup;
+		}
+
+		status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
+				  obj_desc->method.aml_start, obj_desc->method.aml_length,
+				  NULL, NULL, 1);
+		if (ACPI_FAILURE (status)) {
+			acpi_ds_delete_walk_state (next_walk_state);
+			goto cleanup;
+		}
 
-	/* Begin AML parse */
+		/* Begin AML parse */
 
-	status = acpi_ps_parse_aml (next_walk_state);
-	acpi_ps_delete_parse_tree (op);
+		status = acpi_ps_parse_aml (next_walk_state);
+		acpi_ps_delete_parse_tree (op);
+	}
 
 	/* 2) Execute: Create a new state for the preempting walk */
 
@@ -337,7 +340,6 @@
 		status = AE_NO_MEMORY;
 		goto cleanup;
 	}
-
 	/*
 	 * The resolved arguments were put on the previous walk state's operand
 	 * stack.  Operands on the previous walk state stack always
@@ -369,16 +371,25 @@
 	ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
 		"Starting nested execution, newstate=%p\n", next_walk_state));
 
+	if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
+		status = obj_desc->method.implementation (next_walk_state);
+		return_ACPI_STATUS (status);
+	}
+
 	return_ACPI_STATUS (AE_OK);
 
 
 	/* On error, we must delete the new walk state */
 
 cleanup:
+	if (next_walk_state->method_desc) {
+		/* Decrement the thread count on the method parse tree */
+
+	   next_walk_state->method_desc->method.thread_count--;
+	}
 	(void) acpi_ds_terminate_control_method (next_walk_state);
 	acpi_ds_delete_walk_state (next_walk_state);
 	return_ACPI_STATUS (status);
-
 }
 
 
@@ -500,10 +511,30 @@
 		}
 	}
 
-	/* Decrement the thread count on the method parse tree */
+	if (walk_state->method_desc->method.thread_count) {
+		ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+			"*** Not deleting method namespace, there are still %d threads\n",
+			walk_state->method_desc->method.thread_count));
+	}
 
-	walk_state->method_desc->method.thread_count--;
 	if (!walk_state->method_desc->method.thread_count) {
+		/*
+		 * Support to dynamically change a method from not_serialized to
+		 * Serialized if it appears that the method is written foolishly and
+		 * does not support multiple thread execution.  The best example of this
+		 * is if such a method creates namespace objects and blocks.  A second
+		 * thread will fail with an AE_ALREADY_EXISTS exception
+		 *
+		 * This code is here because we must wait until the last thread exits
+		 * before creating the synchronization semaphore.
+		 */
+		if ((walk_state->method_desc->method.concurrency == 1) &&
+			(!walk_state->method_desc->method.semaphore)) {
+			status = acpi_os_create_semaphore (1,
+					 1,
+					 &walk_state->method_desc->method.semaphore);
+		}
+
 		/*
 		 * There are no more threads executing this method.  Perform
 		 * additional cleanup.
diff -Nru a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
--- a/drivers/acpi/events/evgpe.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/events/evgpe.c	Sat Mar 13 02:20:35 2004
@@ -149,6 +149,11 @@
 
 	ACPI_FUNCTION_NAME ("ev_gpe_detect");
 
+	/* Check for the case where there are no GPEs */
+
+	if (!gpe_xrupt_list) {
+		return (int_status);
+	}
 
 	/* Examine all GPE blocks attached to this interrupt level */
 
diff -Nru a/drivers/acpi/executer/excreate.c b/drivers/acpi/executer/excreate.c
--- a/drivers/acpi/executer/excreate.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/executer/excreate.c	Sat Mar 13 02:20:35 2004
@@ -587,27 +587,33 @@
 	obj_desc->method.aml_start = aml_start;
 	obj_desc->method.aml_length = aml_length;
 
-	/* disassemble the method flags */
-
+	/*
+	 * Disassemble the method flags.  Split off the Arg Count
+	 * for efficiency
+	 */
 	method_flags = (u8) operand[1]->integer.value;
 
-	obj_desc->method.method_flags = method_flags;
-	obj_desc->method.param_count = (u8) (method_flags & METHOD_FLAGS_ARG_COUNT);
+	obj_desc->method.method_flags = (u8) (method_flags & ~AML_METHOD_ARG_COUNT);
+	obj_desc->method.param_count = (u8) (method_flags & AML_METHOD_ARG_COUNT);
 
 	/*
 	 * Get the concurrency count.  If required, a semaphore will be
 	 * created for this method when it is parsed.
 	 */
-	if (method_flags & METHOD_FLAGS_SERIALIZED) {
+	if (acpi_gbl_all_methods_serialized) {
+		obj_desc->method.concurrency = 1;
+		obj_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+	}
+	else if (method_flags & AML_METHOD_SERIALIZED) {
 		/*
 		 * ACPI 1.0: Concurrency = 1
 		 * ACPI 2.0: Concurrency = (sync_level (in method declaration) + 1)
 		 */
 		obj_desc->method.concurrency = (u8)
-				  (((method_flags & METHOD_FLAGS_SYNCH_LEVEL) >> 4) + 1);
+				  (((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4) + 1);
 	}
 	else {
-		obj_desc->method.concurrency = INFINITE_CONCURRENCY;
+		obj_desc->method.concurrency = ACPI_INFINITE_CONCURRENCY;
 	}
 
 	/* Attach the new object to the method Node */
diff -Nru a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
--- a/drivers/acpi/executer/exmutex.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/executer/exmutex.c	Sat Mar 13 02:20:35 2004
@@ -176,15 +176,18 @@
 	/*
 	 * Support for multiple acquires by the owning thread
 	 */
+	if (obj_desc->mutex.owner_thread) {
+		/* Special case for Global Lock, allow all threads */
 
-	if ((obj_desc->mutex.owner_thread) &&
-		(obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id)) {
-		/*
-		 * The mutex is already owned by this thread,
-		 * just increment the acquisition depth
-		 */
-		obj_desc->mutex.acquisition_depth++;
-		return_ACPI_STATUS (AE_OK);
+		if ((obj_desc->mutex.owner_thread->thread_id == walk_state->thread->thread_id) ||
+			(obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore)) {
+			/*
+			 * The mutex is already owned by this thread,
+			 * just increment the acquisition depth
+			 */
+			obj_desc->mutex.acquisition_depth++;
+			return_ACPI_STATUS (AE_OK);
+		}
 	}
 
 	/* Acquire the mutex, wait if necessary */
@@ -254,9 +257,12 @@
 		return_ACPI_STATUS (AE_AML_INTERNAL);
 	}
 
-	/* The Mutex is owned, but this thread must be the owner */
-
-	if (obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) {
+	/*
+	 * The Mutex is owned, but this thread must be the owner.
+	 * Special case for Global Lock, any thread can release
+	 */
+	if ((obj_desc->mutex.owner_thread->thread_id != walk_state->thread->thread_id) &&
+		(obj_desc->mutex.semaphore != acpi_gbl_global_lock_semaphore)) {
 		ACPI_REPORT_ERROR ((
 			"Thread %X cannot release Mutex [%4.4s] acquired by thread %X\n",
 			walk_state->thread->thread_id,
diff -Nru a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c
--- a/drivers/acpi/namespace/nsaccess.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/namespace/nsaccess.c	Sat Mar 13 02:20:35 2004
@@ -105,8 +105,15 @@
 		"Entering predefined entries into namespace\n"));
 
 	for (init_val = acpi_gbl_pre_defined_names; init_val->name; init_val++) {
+		/* _OSI is optional for now, will be permanent later */
+
+		if (!ACPI_STRCMP (init_val->name, "_OSI") && !acpi_gbl_create_osi_method) {
+			continue;
+		}
+
 		status = acpi_ns_lookup (NULL, init_val->name, init_val->type,
-				  ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &new_node);
+				  ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH,
+				  NULL, &new_node);
 
 		if (ACPI_FAILURE (status) || (!new_node)) /* Must be on same line for code converter */ {
 			ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -122,7 +129,8 @@
 		if (init_val->val) {
 			status = acpi_os_predefined_override (init_val, &val);
 			if (ACPI_FAILURE (status)) {
-				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not override predefined %s\n",
+				ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+					"Could not override predefined %s\n",
 					init_val->name));
 			}
 
@@ -147,15 +155,20 @@
 			 */
 			switch (init_val->type) {
 			case ACPI_TYPE_METHOD:
-				obj_desc->method.param_count =
-						(u8) ACPI_STRTOUL (val, NULL, 10);
+				obj_desc->method.param_count = (u8) ACPI_STRTOUL
+						  (val, NULL, 10);
 				obj_desc->common.flags |= AOPOBJ_DATA_VALID;
 
-#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#if defined (_ACPI_ASL_COMPILER) || defined (_ACPI_DUMP_App)
 
-				/* Compiler cheats by putting parameter count in the owner_iD */
+				/* i_aSL Compiler cheats by putting parameter count in the owner_iD */
 
 				new_node->owner_id = obj_desc->method.param_count;
+#else
+				/* Mark this as a very SPECIAL method */
+
+				obj_desc->method.method_flags = AML_METHOD_INTERNAL_ONLY;
+				obj_desc->method.implementation = acpi_ut_osi_implementation;
 #endif
 				break;
 
@@ -180,8 +193,8 @@
 			case ACPI_TYPE_MUTEX:
 
 				obj_desc->mutex.node = new_node;
-				obj_desc->mutex.sync_level =
-						 (u16) ACPI_STRTOUL (val, NULL, 10);
+				obj_desc->mutex.sync_level = (u16) ACPI_STRTOUL
+						  (val, NULL, 10);
 
 				if (ACPI_STRCMP (init_val->name, "_GL_") == 0) {
 					/*
@@ -213,6 +226,7 @@
 
 
 			default:
+
 				ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
 					init_val->type));
 				acpi_ut_remove_reference (obj_desc);
diff -Nru a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
--- a/drivers/acpi/namespace/nsalloc.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/namespace/nsalloc.c	Sat Mar 13 02:20:35 2004
@@ -334,10 +334,11 @@
 	node->owner_id = owner_id;
 	node->type = (u8) type;
 
-	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%4.4s (%s) added to %4.4s (%s) %p at %p\n",
-		acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type),
+	ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
+		"%4.4s (%s) [Node %p Owner %X] added to %4.4s (%s) [Node %p]\n",
+		acpi_ut_get_node_name (node), acpi_ut_get_type_name (node->type), node, owner_id,
 		acpi_ut_get_node_name (parent_node), acpi_ut_get_type_name (parent_node->type),
-		parent_node, node));
+		parent_node));
 
 	/*
 	 * Increment the reference count(s) of all parents up to
diff -Nru a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c
--- a/drivers/acpi/namespace/nseval.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/namespace/nseval.c	Sat Mar 13 02:20:35 2004
@@ -82,11 +82,11 @@
 	union acpi_operand_object       **params,
 	union acpi_operand_object       **return_object)
 {
-	struct acpi_namespace_node      *prefix_node;
 	acpi_status                     status;
+	struct acpi_namespace_node      *prefix_node;
 	struct acpi_namespace_node      *node = NULL;
+	union acpi_generic_state        *scope_info;
 	char                            *internal_path = NULL;
-	union acpi_generic_state        scope_info;
 
 
 	ACPI_FUNCTION_TRACE ("ns_evaluate_relative");
@@ -106,6 +106,11 @@
 		return_ACPI_STATUS (status);
 	}
 
+	scope_info = acpi_ut_create_generic_state ();
+	if (!scope_info) {
+		goto cleanup1;
+	}
+
 	/* Get the prefix handle and Node */
 
 	status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
@@ -122,8 +127,8 @@
 
 	/* Lookup the name in the namespace */
 
-	scope_info.scope.node = prefix_node;
-	status = acpi_ns_lookup (&scope_info, internal_path, ACPI_TYPE_ANY,
+	scope_info->scope.node = prefix_node;
+	status = acpi_ns_lookup (scope_info, internal_path, ACPI_TYPE_ANY,
 			 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
 			 &node);
 
@@ -148,7 +153,9 @@
 		pathname));
 
 cleanup:
+	acpi_ut_delete_generic_state (scope_info);
 
+cleanup1:
 	ACPI_MEM_FREE (internal_path);
 	return_ACPI_STATUS (status);
 }
diff -Nru a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c
--- a/drivers/acpi/parser/psparse.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/parser/psparse.c	Sat Mar 13 02:20:35 2004
@@ -426,7 +426,7 @@
 	acpi_status                     status = AE_OK;
 	union acpi_parse_object         *op = NULL;     /* current op */
 	union acpi_parse_object         *arg = NULL;
-	union acpi_parse_object         pre_op;
+	union acpi_parse_object         *pre_op = NULL;
 	struct acpi_parse_state         *parser_state;
 	u8                              *aml_op_start = NULL;
 
@@ -547,8 +547,17 @@
 			/* Create Op structure and append to parent's argument list */
 
 			if (walk_state->op_info->flags & AML_NAMED) {
-				pre_op.common.value.arg = NULL;
-				pre_op.common.aml_opcode = walk_state->opcode;
+				/* Allocate a new pre_op if necessary */
+
+				if (!pre_op) {
+					pre_op = acpi_ps_alloc_op (walk_state->opcode);
+					if (!pre_op) {
+						return_ACPI_STATUS (AE_NO_MEMORY);
+					}
+				}
+
+				pre_op->common.value.arg = NULL;
+				pre_op->common.aml_opcode = walk_state->opcode;
 
 				/*
 				 * Get and append arguments until we find the node that contains
@@ -562,7 +571,7 @@
 						goto close_this_op;
 					}
 
-					acpi_ps_append_arg (&pre_op, arg);
+					acpi_ps_append_arg (pre_op, arg);
 					INCREMENT_ARG_LIST (walk_state->arg_types);
 				}
 
@@ -603,7 +612,7 @@
 					goto close_this_op;
 				}
 
-				acpi_ps_append_arg (op, pre_op.common.value.arg);
+				acpi_ps_append_arg (op, pre_op->common.value.arg);
 				acpi_gbl_depth++;
 
 				if (op->common.aml_opcode == AML_REGION_OP) {
@@ -854,6 +863,10 @@
 
 		acpi_ps_complete_this_op (walk_state, op);
 		op = NULL;
+		if (pre_op) {
+			acpi_ps_free_op (pre_op);
+			pre_op = NULL;
+		}
 
 		switch (status) {
 		case AE_OK:
@@ -1118,6 +1131,27 @@
 		else if (status != AE_OK) {
 			ACPI_REPORT_METHOD_ERROR ("Method execution failed",
 				walk_state->method_node, NULL, status);
+
+			/* Check for possible multi-thread reentrancy problem */
+
+			if ((status == AE_ALREADY_EXISTS) &&
+				(!walk_state->method_desc->method.semaphore)) {
+				/*
+				 * This method is marked not_serialized, but it tried to create a named
+				 * object, causing the second thread entrance to fail.  We will workaround
+				 * this by marking the method permanently as Serialized.
+				 */
+				walk_state->method_desc->method.method_flags |= AML_METHOD_SERIALIZED;
+				walk_state->method_desc->method.concurrency = 1;
+			}
+		}
+
+		if (walk_state->method_desc) {
+			/* Decrement the thread count on the method parse tree */
+
+			if (walk_state->method_desc->method.thread_count) {
+				walk_state->method_desc->method.thread_count--;
+			}
 		}
 
 		/* We are done with this walk, move on to the parent if any */
diff -Nru a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c
--- a/drivers/acpi/parser/psscope.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/parser/psscope.c	Sat Mar 13 02:20:35 2004
@@ -167,7 +167,6 @@
 		return_ACPI_STATUS (AE_NO_MEMORY);
 	}
 
-
 	scope->common.data_type        = ACPI_DESC_TYPE_STATE_PSCOPE;
 	scope->parse_scope.op          = op;
 	scope->parse_scope.arg_list    = remaining_args;
@@ -178,13 +177,11 @@
 
 	acpi_ut_push_generic_state (&parser_state->scope, scope);
 
-
 	if (arg_count == ACPI_VAR_ARGS) {
 		/* multiple arguments */
 
 		scope->parse_scope.arg_end = parser_state->pkg_end;
 	}
-
 	else {
 		/* single argument */
 
@@ -241,7 +238,6 @@
 
 		acpi_ut_delete_generic_state (scope);
 	}
-
 	else {
 		/* empty parse stack, prepare to fetch next opcode */
 
@@ -250,7 +246,6 @@
 		*arg_count              = 0;
 	}
 
-
 	ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
 	return_VOID;
 }
@@ -275,13 +270,13 @@
 {
 	union acpi_generic_state        *scope;
 
+
 	ACPI_FUNCTION_TRACE_PTR ("ps_cleanup_scope", parser_state);
 
 
 	if (!parser_state) {
-		return;
+		return_VOID;
 	}
-
 
 	/* Delete anything on the scope stack */
 
diff -Nru a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c
--- a/drivers/acpi/utilities/uteval.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/utilities/uteval.c	Sat Mar 13 02:20:35 2004
@@ -53,6 +53,62 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ut_osi_implementation
+ *
+ * PARAMETERS:  walk_state          - Current walk state
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Implementation of _OSI predefined control method
+ *              Supported = _OSI (String)
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ut_osi_implementation (
+	struct acpi_walk_state          *walk_state)
+{
+	union acpi_operand_object       *string_desc;
+	union acpi_operand_object       *return_desc;
+	acpi_native_uint                i;
+
+
+	ACPI_FUNCTION_TRACE ("ut_osi_implementation");
+
+
+	/* Validate the string input argument */
+
+	string_desc = walk_state->arguments[0].object;
+	if (!string_desc || (string_desc->common.type != ACPI_TYPE_STRING)) {
+		return_ACPI_STATUS (AE_TYPE);
+	}
+
+	/* Create a return object (Default value = 0) */
+
+	return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+	if (!return_desc) {
+		return_ACPI_STATUS (AE_NO_MEMORY);
+	}
+
+	/* Compare input string to table of supported strings */
+
+	for (i = 0; i < ACPI_NUM_OSI_STRINGS; i++) {
+		if (!ACPI_STRCMP (string_desc->string.pointer,
+				   (char *) acpi_gbl_valid_osi_strings[i])) {
+			/* This string is supported */
+
+			return_desc->integer.value = 0xFFFFFFFF;
+			break;
+		}
+	}
+
+	walk_state->return_desc = return_desc;
+	return_ACPI_STATUS (AE_CTRL_TERMINATE);
+}
+
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ut_evaluate_object
  *
  * PARAMETERS:  prefix_node         - Starting node
diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
--- a/drivers/acpi/utilities/utglobal.c	Sat Mar 13 02:20:35 2004
+++ b/drivers/acpi/utilities/utglobal.c	Sat Mar 13 02:20:35 2004
@@ -185,6 +185,15 @@
 					   "_S3D",
 					   "_S4D"};
 
+/* Strings supported by the _OSI predefined (internal) method */
+
+const char                          *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS] = {
+							 "Linux",
+							 "Windows 2000",
+							 "Windows 2001",
+							 "Windows 2001.1"};
+
+
 /******************************************************************************
  *
  * Namespace globals
@@ -195,14 +204,10 @@
 /*
  * Predefined ACPI Names (Built-in to the Interpreter)
  *
- * Initial values are currently supported only for types String and Number.
- * Both are specified as strings in this table.
- *
  * NOTES:
- * 1) _SB_ is defined to be a device to allow _SB_/_INI to be run
+ * 1) _SB_ is defined to be a device to allow \_SB_._INI to be run
  *    during the initialization sequence.
  */
-
 const struct acpi_predefined_names      acpi_gbl_pre_defined_names[] =
 { {"_GPE",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
 	{"_PR_",    ACPI_TYPE_LOCAL_SCOPE,      NULL},
@@ -213,7 +218,7 @@
 	{"_OS_",    ACPI_TYPE_STRING,           ACPI_OS_NAME},
 	{"_GL_",    ACPI_TYPE_MUTEX,            "0"},
 
-#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
 	{"_OSI",    ACPI_TYPE_METHOD,           "1"},
 #endif
 	{NULL,      ACPI_TYPE_ANY,              NULL}              /* Table terminator */
@@ -224,7 +229,6 @@
  * Properties of the ACPI Object Types, both internal and external.
  * The table is indexed by values of acpi_object_type
  */
-
 const u8                                acpi_gbl_ns_properties[] =
 {
 	ACPI_NS_NORMAL,                     /* 00 Any              */
@@ -303,10 +307,8 @@
  *
  ******************************************************************************/
 
-
 struct acpi_table_list              acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
 
-
 struct acpi_table_support           acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
 {
 	/***********    Name,   Signature, Global typed pointer     Signature size,      Type                  How many allowed?,    Contains valid AML? */
@@ -470,9 +472,8 @@
  *
  * The type ACPI_TYPE_ANY (Untyped) is used as a "don't care" when searching; when
  * stored in a table it really means that we have thus far seen no evidence to
- * indicatewhat type is actually going to be stored for this entry.
+ * indicate what type is actually going to be stored for this entry.
  */
-
 static const char                   acpi_gbl_bad_type[] = "UNDEFINED";
 #define TYPE_NAME_LENGTH    12                           /* Maximum length of each string */
 
@@ -776,6 +777,11 @@
 
 
 	ACPI_FUNCTION_TRACE ("ut_init_globals");
+
+	/* Runtime configuration */
+
+	acpi_gbl_create_osi_method = TRUE;
+	acpi_gbl_all_methods_serialized = FALSE;
 
 	/* Memory allocation and cache lists */
 
diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h
--- a/include/acpi/acconfig.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/acconfig.h	Sat Mar 13 02:20:35 2004
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20040220
+#define ACPI_CA_VERSION                 0x20040311
 
 /* Maximum objects in the various object caches */
 
@@ -184,6 +184,10 @@
 /* SMBus bidirectional buffer size */
 
 #define ACPI_SMBUS_BUFFER_SIZE          34
+
+/* Number of strings associated with the _OSI reserved method */
+
+#define ACPI_NUM_OSI_STRINGS            4
 
 
 /******************************************************************************
diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h
--- a/include/acpi/acglobal.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/acglobal.h	Sat Mar 13 02:20:35 2004
@@ -79,6 +79,14 @@
 
 extern      u32                                 acpi_gbl_nesting_level;
 
+/*****************************************************************************
+ *
+ * Runtime configuration
+ *
+ ****************************************************************************/
+
+ACPI_EXTERN u8                                  acpi_gbl_create_osi_method;
+ACPI_EXTERN u8                                  acpi_gbl_all_methods_serialized;
 
 /*****************************************************************************
  *
@@ -169,6 +177,7 @@
 extern const char                              *acpi_gbl_highest_dstate_names[4];
 extern const struct acpi_opcode_info            acpi_gbl_aml_op_info[AML_NUM_OPCODES];
 extern const char                              *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS];
+extern const char                              *acpi_gbl_valid_osi_strings[ACPI_NUM_OSI_STRINGS];
 
 
 /*****************************************************************************
@@ -179,7 +188,7 @@
 
 #define NUM_NS_TYPES                    ACPI_TYPE_INVALID+1
 
-#if defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
+#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
 #define NUM_PREDEFINED_NAMES            10
 #else
 #define NUM_PREDEFINED_NAMES            9
diff -Nru a/include/acpi/acmacros.h b/include/acpi/acmacros.h
--- a/include/acpi/acmacros.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/acmacros.h	Sat Mar 13 02:20:35 2004
@@ -681,7 +681,4 @@
 
 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
 
-
-#define ACPI_GET_STACK_POINTER          _asm {mov eax, ebx}
-
 #endif /* ACMACROS_H */
diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h
--- a/include/acpi/acobject.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/acobject.h	Sat Mar 13 02:20:35 2004
@@ -180,7 +180,11 @@
 };
 
 
-#define INFINITE_CONCURRENCY        0xFF
+#define ACPI_INFINITE_CONCURRENCY   0xFF
+
+typedef
+acpi_status (*ACPI_INTERNAL_METHOD) (
+	struct acpi_walk_state          *walk_state);
 
 struct acpi_object_method
 {
@@ -190,6 +194,7 @@
 	u32                                     aml_length;
 	void                                    *semaphore;
 	u8                                      *aml_start;
+	ACPI_INTERNAL_METHOD            implementation;
 	u8                                      concurrency;
 	u8                                      thread_count;
 	acpi_owner_id                           owning_id;
diff -Nru a/include/acpi/actypes.h b/include/acpi/actypes.h
--- a/include/acpi/actypes.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/actypes.h	Sat Mar 13 02:20:35 2004
@@ -349,7 +349,6 @@
 /*
  * Power state values
  */
-
 #define ACPI_STATE_UNKNOWN              (u8) 0xFF
 
 #define ACPI_STATE_S0                   (u8) 0
@@ -393,7 +392,6 @@
 #define ACPI_NOTIFY_BUS_MODE_MISMATCH   (u8) 6
 #define ACPI_NOTIFY_POWER_FAULT         (u8) 7
 
-
 /*
  *  Table types.  These values are passed to the table related APIs
  */
@@ -409,7 +407,6 @@
 #define ACPI_TABLE_MAX                  6
 #define NUM_ACPI_TABLE_TYPES            (ACPI_TABLE_MAX+1)
 
-
 /*
  * Types associated with ACPI names and objects.  The first group of
  * values (up to ACPI_TYPE_EXTERNAL_MAX) correspond to the definition
@@ -794,7 +791,7 @@
 #define ACPI_INIT_DEVICE_INI        1
 
 
-/* Address Spaces (Operation Regions */
+/* Address Spaces (For Operation Regions) */
 
 typedef
 acpi_status (*acpi_adr_space_handler) (
diff -Nru a/include/acpi/acutils.h b/include/acpi/acutils.h
--- a/include/acpi/acutils.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/acutils.h	Sat Mar 13 02:20:35 2004
@@ -52,7 +52,6 @@
 	union acpi_generic_state        *state,
 	void                            *context);
 
-
 acpi_status
 acpi_ut_walk_package_tree (
 	union acpi_operand_object       *source_object,
@@ -60,7 +59,6 @@
 	acpi_pkg_callback               walk_callback,
 	void                            *context);
 
-
 struct acpi_pkg_info
 {
 	u8                              *free_space;
@@ -474,6 +472,10 @@
 #define METHOD_NAME__CRS        "_CRS"
 #define METHOD_NAME__PRS        "_PRS"
 
+
+acpi_status
+acpi_ut_osi_implementation (
+	struct acpi_walk_state          *walk_state);
 
 acpi_status
 acpi_ut_evaluate_object (
diff -Nru a/include/acpi/amlcode.h b/include/acpi/amlcode.h
--- a/include/acpi/amlcode.h	Sat Mar 13 02:20:35 2004
+++ b/include/acpi/amlcode.h	Sat Mar 13 02:20:35 2004
@@ -496,11 +496,17 @@
 } AML_ACCESS_ATTRIBUTE;
 
 
-/* bit fields in method_flags byte */
+/* Bit fields in method_flags byte */
 
-#define METHOD_FLAGS_ARG_COUNT      0x07
-#define METHOD_FLAGS_SERIALIZED     0x08
-#define METHOD_FLAGS_SYNCH_LEVEL    0xF0
+#define AML_METHOD_ARG_COUNT        0x07
+#define AML_METHOD_SERIALIZED       0x08
+#define AML_METHOD_SYNCH_LEVEL      0xF0
+
+/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */
+
+#define AML_METHOD_INTERNAL_ONLY    0x01
+#define AML_METHOD_RESERVED1        0x02
+#define AML_METHOD_RESERVED2        0x04
 
 
 #endif /* __AMLCODE_H__ */