ACPICA: Add support to externally execute _OSI method
authorBob Moore <robert.moore@intel.com>
Thu, 13 Nov 2008 01:45:35 +0000 (09:45 +0800)
committerLen Brown <len.brown@intel.com>
Tue, 30 Dec 2008 03:38:37 +0000 (22:38 -0500)
The current implemenation of _OSI within ACPICA only allows other
control methods to execute _OSI. This change allows the host
OS to execute _OSI via the AcpiEvaluateObject interface. _OSI
is a special method -- it does not exist in the AML code, it is
implemented within ACPICA.

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/parser/psparse.c
drivers/acpi/parser/psxface.c
drivers/acpi/utilities/uteval.c

index 279a5a60a0dd492a2b27f144b12b353b9de78a2a..77b7039a26e4d6415df0f8552cdccff97b91c730 100644 (file)
@@ -412,6 +412,9 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
 
        if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
                status = obj_desc->method.implementation(next_walk_state);
+               if (status == AE_OK) {
+                       status = AE_CTRL_TERMINATE;
+               }
        }
 
        return_ACPI_STATUS(status);
index dfd3d90280187a19deac6d03ac914dd24c7bc914..5156203883d7c392c724b1ac1c34168cf7c58250 100644 (file)
@@ -447,6 +447,10 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state)
                          walk_state, walk_state->parser_state.aml,
                          walk_state->parser_state.aml_size));
 
+       if (!walk_state->parser_state.aml) {
+               return_ACPI_STATUS(AE_NULL_OBJECT);
+       }
+
        /* Create and initialize a new thread state */
 
        thread = acpi_ut_create_thread_state();
index 270469aae8429201df4edfae11db91d8c5628133..4985ce58c02432ff30169dd56dde35d478ada180 100644 (file)
@@ -45,6 +45,7 @@
 #include <acpi/acparser.h>
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
+#include <acpi/amlcode.h>
 
 #define _COMPONENT          ACPI_PARSER
 ACPI_MODULE_NAME("psxface")
@@ -278,6 +279,22 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
                goto cleanup;
        }
 
+       /* Invoke an internal method if necessary */
+
+       if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
+               status = info->obj_desc->method.implementation(walk_state);
+               info->return_object = walk_state->return_desc;
+
+               /* Cleanup states */
+
+               acpi_ds_scope_stack_clear(walk_state);
+               acpi_ps_cleanup_scope(&walk_state->parser_state);
+               acpi_ds_terminate_control_method(walk_state->method_desc,
+                                                walk_state);
+               acpi_ds_delete_walk_state(walk_state);
+               goto cleanup;
+       }
+
        /* Parse the AML */
 
        status = acpi_ps_parse_aml(walk_state);
index 352747e49c7a623930fd17491533a436394099ad..df2b511b595a063c69f12dc5f6d7202f340e9161 100644 (file)
@@ -129,7 +129,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
 
                        /* The interface is supported */
 
-                       return_ACPI_STATUS(AE_CTRL_TERMINATE);
+                       return_ACPI_STATUS(AE_OK);
                }
        }
 
@@ -143,13 +143,13 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
 
                /* The interface is supported */
 
-               return_ACPI_STATUS(AE_CTRL_TERMINATE);
+               return_ACPI_STATUS(AE_OK);
        }
 
        /* The interface is not supported */
 
        return_desc->integer.value = 0;
-       return_ACPI_STATUS(AE_CTRL_TERMINATE);
+       return_ACPI_STATUS(AE_OK);
 }
 
 /*******************************************************************************