summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsopcode.c
diff options
context:
space:
mode:
authorLin Ming2008-04-10 17:06:41 +0200
committerLen Brown2008-04-22 20:29:28 +0200
commit941f48bb465b0b291f8435b1e3de95b0975b84bc (patch)
tree42327b3d29fbaa55827abfe620a94320f86b6eb4 /drivers/acpi/dispatcher/dsopcode.c
parentACPICA: Fixed a problem with Index Fields where the Index register was incorr... (diff)
downloadkernel-qcow2-linux-941f48bb465b0b291f8435b1e3de95b0975b84bc.tar.gz
kernel-qcow2-linux-941f48bb465b0b291f8435b1e3de95b0975b84bc.tar.xz
kernel-qcow2-linux-941f48bb465b0b291f8435b1e3de95b0975b84bc.zip
ACPICA: Implemented full support for deferred execution for the TermArg string arguments for DataTableRegion
This enables forward references and full operand resolution for the three string arguments. Similar to OperationRegion deferred argument execution.) http://www.acpica.org/bugzilla/show_bug.cgi?id=430 Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher/dsopcode.c')
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
index f0847eed5f3a..a3f29798d1d1 100644
--- a/drivers/acpi/dispatcher/dsopcode.c
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -49,6 +49,7 @@
#include <acpi/acinterp.h>
#include <acpi/acnamesp.h>
#include <acpi/acevents.h>
+#include <acpi/actables.h>
#define _COMPONENT ACPI_DISPATCHER
ACPI_MODULE_NAME("dsopcode")
@@ -782,6 +783,108 @@ acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
/*******************************************************************************
*
+ * FUNCTION: acpi_ds_eval_table_region_operands
+ *
+ * PARAMETERS: walk_state - Current walk
+ * Op - A valid region Op object
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get region address and length
+ * Called from acpi_ds_exec_end_op during data_table_region parse tree walk
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
+ union acpi_parse_object *op)
+{
+ acpi_status status;
+ union acpi_operand_object *obj_desc;
+ union acpi_operand_object **operand;
+ struct acpi_namespace_node *node;
+ union acpi_parse_object *next_op;
+ acpi_native_uint table_index;
+ struct acpi_table_header *table;
+
+ ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
+
+ /*
+ * This is where we evaluate the signature_string and oem_iDString
+ * and oem_table_iDString of the data_table_region declaration
+ */
+ node = op->common.node;
+
+ /* next_op points to signature_string op */
+
+ next_op = op->common.value.arg;
+
+ /*
+ * Evaluate/create the signature_string and oem_iDString
+ * and oem_table_iDString operands
+ */
+ status = acpi_ds_create_operands(walk_state, next_op);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * Resolve the signature_string and oem_iDString
+ * and oem_table_iDString operands
+ */
+ status = acpi_ex_resolve_operands(op->common.aml_opcode,
+ ACPI_WALK_OPERANDS, walk_state);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
+ acpi_ps_get_opcode_name(op->common.aml_opcode),
+ 1, "after AcpiExResolveOperands");
+
+ operand = &walk_state->operands[0];
+
+ /* Find the ACPI table */
+
+ status = acpi_tb_find_table(operand[0]->string.pointer,
+ operand[1]->string.pointer,
+ operand[2]->string.pointer, &table_index);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ acpi_ut_remove_reference(operand[0]);
+ acpi_ut_remove_reference(operand[1]);
+ acpi_ut_remove_reference(operand[2]);
+
+ status = acpi_get_table_by_index(table_index, &table);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ obj_desc = acpi_ns_get_attached_object(node);
+ if (!obj_desc) {
+ return_ACPI_STATUS(AE_NOT_EXIST);
+ }
+
+ obj_desc->region.address =
+ (acpi_physical_address) ACPI_TO_INTEGER(table);
+ obj_desc->region.length = table->length;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
+ obj_desc,
+ ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address),
+ obj_desc->region.length));
+
+ /* Now the address and length are valid for this opregion */
+
+ obj_desc->region.flags |= AOPOBJ_DATA_VALID;
+
+ return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ds_eval_data_object_operands
*
* PARAMETERS: walk_state - Current walk