]> git.neil.brown.name Git - history.git/commitdiff
[ACPI] ACPICA 20040311 from Bob Moore
authorLen Brown <len.brown@intel.com>
Fri, 12 Mar 2004 19:35:17 +0000 (14:35 -0500)
committerLen Brown <lenb@dhcppc3.>
Fri, 12 Mar 2004 19:35:17 +0000 (14:35 -0500)
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.

18 files changed:
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/events/evgpe.c
drivers/acpi/executer/excreate.c
drivers/acpi/executer/exmutex.c
drivers/acpi/namespace/nsaccess.c
drivers/acpi/namespace/nsalloc.c
drivers/acpi/namespace/nseval.c
drivers/acpi/parser/psparse.c
drivers/acpi/parser/psscope.c
drivers/acpi/utilities/uteval.c
drivers/acpi/utilities/utglobal.c
include/acpi/acconfig.h
include/acpi/acglobal.h
include/acpi/acmacros.h
include/acpi/acobject.h
include/acpi/actypes.h
include/acpi/acutils.h
include/acpi/amlcode.h

index 611cb7beedf890a1b470612ddd2dcdedb182e4c8..360fbe5e8beeb01b9df534443a52cc9b9ed41a19 100644 (file)
@@ -106,7 +106,7 @@ acpi_ds_parse_method (
 
        /* 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 @@ acpi_ds_call_control_method (
                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 @@ acpi_ds_call_control_method (
                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_ds_call_control_method (
        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 @@ acpi_ds_terminate_control_method (
                }
        }
 
-       /* 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.
index 736ccbaa613de8b992d7a12f48a6d1987be8fc95..8ef9e7046af00e23a890d01c393b7ab35d30fd50 100644 (file)
@@ -149,6 +149,11 @@ acpi_ev_gpe_detect (
 
        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 */
 
index b822c3e7c0603f60ed7469f8ec30c83dcdb2931e..3b54e4d9253899546d682b59564ae38159801a8e 100644 (file)
@@ -587,27 +587,33 @@ acpi_ex_create_method (
        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 */
index b7ef546b6a5e864da579201b7192e1eeebf5b752..cee2c126e7f9131b46c09b13706dea4478fd3965 100644 (file)
@@ -176,15 +176,18 @@ acpi_ex_acquire_mutex (
        /*
         * Support for multiple acquires by the owning thread
         */
-
-       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) {
+               /* Special case for Global Lock, allow all threads */
+
+               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 @@ acpi_ex_release_mutex (
                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,
index c4ad91b639c8d02644bd9f9e9105b6e077b33cd5..20ce3c0ee08c25281cbc78ccd9581fc90858bac1 100644 (file)
@@ -105,8 +105,15 @@ acpi_ns_root_initialize (void)
                "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 @@ acpi_ns_root_initialize (void)
                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 @@ acpi_ns_root_initialize (void)
                         */
                        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 @@ acpi_ns_root_initialize (void)
                        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 @@ acpi_ns_root_initialize (void)
 
 
                        default:
+
                                ACPI_REPORT_ERROR (("Unsupported initial type value %X\n",
                                        init_val->type));
                                acpi_ut_remove_reference (obj_desc);
index bfe9d836009cdb6bc4fe2d17e0e456e225cbff30..f7a216c2f6d5777fe954746e1e7d4e276264ee8e 100644 (file)
@@ -334,10 +334,11 @@ acpi_ns_install_node (
        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
index 8d51922b9967a43ff9b36df670e1cd33336eb73f..e64e15d69ceff55c8826e0efad3c635a06a474f1 100644 (file)
@@ -82,11 +82,11 @@ acpi_ns_evaluate_relative (
        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 @@ acpi_ns_evaluate_relative (
                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 @@ acpi_ns_evaluate_relative (
 
        /* 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 @@ acpi_ns_evaluate_relative (
                pathname));
 
 cleanup:
+       acpi_ut_delete_generic_state (scope_info);
 
+cleanup1:
        ACPI_MEM_FREE (internal_path);
        return_ACPI_STATUS (status);
 }
index b16ab2dca515bb03f599838ac15f30da04efa798..00a3540f0a88db8b8c97a067d12cd595e68de1fd 100644 (file)
@@ -426,7 +426,7 @@ acpi_ps_parse_loop (
        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 @@ acpi_ps_parse_loop (
                        /* 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 @@ acpi_ps_parse_loop (
                                                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 @@ acpi_ps_parse_loop (
                                        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 @@ close_this_op:
 
                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 @@ acpi_ps_parse_aml (
                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 */
index 54b93ea1a7dad59e8ad8fe04ee062889cdbb3460..b917edfb5041d7b5e4558ddfb393f2d5e187e282 100644 (file)
@@ -167,7 +167,6 @@ acpi_ps_push_scope (
                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_ps_push_scope (
 
        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_ps_pop_scope (
 
                acpi_ut_delete_generic_state (scope);
        }
-
        else {
                /* empty parse stack, prepare to fetch next opcode */
 
@@ -250,7 +246,6 @@ acpi_ps_pop_scope (
                *arg_count              = 0;
        }
 
-
        ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped Op %p Args %X\n", *op, *arg_count));
        return_VOID;
 }
@@ -275,14 +270,14 @@ acpi_ps_cleanup_scope (
 {
        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 */
 
        while (parser_state->scope) {
index 75e6265422ca9019a02df738c22a84a69738c683..c3f5900b6937c33fca5d25d3b4c598e75e387822 100644 (file)
         ACPI_MODULE_NAME    ("uteval")
 
 
+/*******************************************************************************
+ *
+ * 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
index 59b94613917b34f8f654c9f25737518d0cfc7338..242cfade210e8f6c827aa819cea1d84277932be6 100644 (file)
@@ -185,6 +185,15 @@ const char                          *acpi_gbl_highest_dstate_names[4] = {
                                           "_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 @@ const char                          *acpi_gbl_highest_dstate_names[4] = {
 /*
  * 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 @@ const struct acpi_predefined_names      acpi_gbl_pre_defined_names[] =
        {"_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 @@ const struct acpi_predefined_names      acpi_gbl_pre_defined_names[] =
  * 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 @@ acpi_ut_hex_to_ascii_char (
  *
  ******************************************************************************/
 
-
 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 @@ acpi_ut_get_event_name (
  *
  * 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 */
 
@@ -777,6 +778,11 @@ acpi_ut_init_globals (
 
        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 */
 
        ACPI_MEMSET (acpi_gbl_memory_lists, 0, sizeof (struct acpi_memory_list) * ACPI_NUM_MEM_LISTS);
index 6a152b1478cfc54e92fe43f012f1376bb88f9fb9..324bdccdace1efd8cc3dbfc32d6b3be5a5e9107c 100644 (file)
@@ -64,7 +64,7 @@
 
 /* Version string */
 
-#define ACPI_CA_VERSION                 0x20040220
+#define ACPI_CA_VERSION                 0x20040311
 
 /* Maximum objects in the various object caches */
 
 
 #define ACPI_SMBUS_BUFFER_SIZE          34
 
+/* Number of strings associated with the _OSI reserved method */
+
+#define ACPI_NUM_OSI_STRINGS            4
+
 
 /******************************************************************************
  *
index 2af4139a003010efd8a0423d28b287db80d82733..0c869e70dd231229424364bf839c99f1c8554387 100644 (file)
@@ -79,6 +79,14 @@ extern      u32                                 acpi_dbg_layer;
 
 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_sleep_state_names[ACPI_
 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 @@ extern const char                              *acpi_gbl_region_types[ACPI_NUM_P
 
 #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
index e1abf964bf3a0f43394e3399a82bd6418183fc84..245bc0bc5734bc3eb41a45755c8a1322892a680e 100644 (file)
 
 #endif /* ACPI_DBG_TRACK_ALLOCATIONS */
 
-
-#define ACPI_GET_STACK_POINTER          _asm {mov eax, ebx}
-
 #endif /* ACMACROS_H */
index 6caaf6ade2565c4ece94e8b6ea48b4909f3263b1..51abddaf15a21430cb4db9b843a84f0ce32e7936 100644 (file)
@@ -180,7 +180,11 @@ struct acpi_object_event
 };
 
 
-#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 @@ struct acpi_object_method
        u32                                     aml_length;
        void                                    *semaphore;
        u8                                      *aml_start;
+       ACPI_INTERNAL_METHOD            implementation;
        u8                                      concurrency;
        u8                                      thread_count;
        acpi_owner_id                           owning_id;
index 369b43a344d39689233d5ae53941e2d7e6d92b60..9cbb7565a9d7e03c136e125e24b4116fe37b2c08 100644 (file)
@@ -349,7 +349,6 @@ typedef u64                                     acpi_integer;
 /*
  * Power state values
  */
-
 #define ACPI_STATE_UNKNOWN              (u8) 0xFF
 
 #define ACPI_STATE_S0                   (u8) 0
@@ -393,7 +392,6 @@ typedef u64                                     acpi_integer;
 #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 @@ typedef u32                                     acpi_table_type;
 #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 @@ acpi_status (*acpi_init_handler) (
 #define ACPI_INIT_DEVICE_INI        1
 
 
-/* Address Spaces (Operation Regions */
+/* Address Spaces (For Operation Regions) */
 
 typedef
 acpi_status (*acpi_adr_space_handler) (
index 1979e93ba85716421d934008258111a4aea1043c..bdce731d067771908fb51af5ff5919c9803ac55e 100644 (file)
@@ -52,7 +52,6 @@ acpi_status (*acpi_pkg_callback) (
        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_ut_walk_package_tree (
        acpi_pkg_callback               walk_callback,
        void                            *context);
 
-
 struct acpi_pkg_info
 {
        u8                              *free_space;
@@ -475,6 +473,10 @@ acpi_ut_delete_internal_object_list (
 #define METHOD_NAME__PRS        "_PRS"
 
 
+acpi_status
+acpi_ut_osi_implementation (
+       struct acpi_walk_state          *walk_state);
+
 acpi_status
 acpi_ut_evaluate_object (
        struct acpi_namespace_node      *prefix_node,
index 512071acbcc6dd7ab3e52f56b3d52bff8c9a57cd..0344b94c863d65f287360f1816c48e1c7f373e4a 100644 (file)
@@ -496,11 +496,17 @@ typedef enum
 } 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__ */