summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dswexec.c7
-rw-r--r--drivers/acpi/executer/exoparg6.c135
-rw-r--r--drivers/acpi/executer/exresop.c2
-rw-r--r--drivers/acpi/executer/exstoren.c20
-rw-r--r--drivers/acpi/executer/exstorob.c12
-rw-r--r--drivers/acpi/namespace/nsxfname.c51
-rw-r--r--drivers/acpi/parser/psopcode.c2
-rw-r--r--drivers/acpi/tables/tbconvrt.c4
-rw-r--r--include/acpi/acconfig.h2
-rw-r--r--include/acpi/acinterp.h5
-rw-r--r--include/acpi/platform/aclinux.h2
11 files changed, 160 insertions, 82 deletions
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index c40922640bda..b02322e213de 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -578,6 +578,13 @@ acpi_ds_exec_end_op (
break;
}
+ /* Done with this result state (Now that operand stack is built) */
+
+ status = acpi_ds_result_stack_pop (walk_state);
+ if (ACPI_FAILURE (status)) {
+ goto cleanup;
+ }
+
/*
* If a result object was returned from above, push it on the
* current result stack
diff --git a/drivers/acpi/executer/exoparg6.c b/drivers/acpi/executer/exoparg6.c
index ea353f4f2c2c..d32624331626 100644
--- a/drivers/acpi/executer/exoparg6.c
+++ b/drivers/acpi/executer/exoparg6.c
@@ -81,75 +81,119 @@
* FUNCTION: acpi_ex_do_match
*
* PARAMETERS: match_op - The AML match operand
- * package_value - Value from the target package
- * match_value - Value to be matched
+ * package_obj - Object from the target package
+ * match_obj - Object to be matched
*
* RETURN: TRUE if the match is successful, FALSE otherwise
*
- * DESCRIPTION: Implements the low-level match for the ASL Match operator
+ * DESCRIPTION: Implements the low-level match for the ASL Match operator.
+ * Package elements will be implicitly converted to the type of
+ * the match object (Integer/Buffer/String).
*
******************************************************************************/
u8
acpi_ex_do_match (
u32 match_op,
- acpi_integer package_value,
- acpi_integer match_value)
+ union acpi_operand_object *package_obj,
+ union acpi_operand_object *match_obj)
{
-
+ u8 logical_result = TRUE;
+ acpi_status status;
+
+
+ /*
+ * Note: Since the package_obj/match_obj ordering is opposite to that of
+ * the standard logical operators, we have to reverse them when we call
+ * do_logical_op in order to make the implicit conversion rules work
+ * correctly. However, this means we have to flip the entire equation
+ * also. A bit ugly perhaps, but overall, better than fussing the
+ * parameters around at runtime, over and over again.
+ *
+ * Below, P[i] refers to the package element, M refers to the Match object.
+ */
switch (match_op) {
- case MATCH_MTR: /* always true */
+ case MATCH_MTR:
- break;
+ /* Always true */
+ break;
- case MATCH_MEQ: /* true if equal */
+ case MATCH_MEQ:
- if (package_value != match_value) {
+ /*
+ * True if equal: (P[i] == M)
+ * Change to: (M == P[i])
+ */
+ status = acpi_ex_do_logical_op (AML_LEQUAL_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE (status)) {
return (FALSE);
}
break;
+ case MATCH_MLE:
- case MATCH_MLE: /* true if less than or equal */
-
- if (package_value > match_value) {
+ /*
+ * True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
+ * Change to: (M >= P[i]) (M not_less than P[i])
+ */
+ status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE (status)) {
return (FALSE);
}
+ logical_result = (u8) !logical_result;
break;
+ case MATCH_MLT:
- case MATCH_MLT: /* true if less than */
-
- if (package_value >= match_value) {
+ /*
+ * True if less than: (P[i] < M)
+ * Change to: (M > P[i])
+ */
+ status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE (status)) {
return (FALSE);
}
break;
+ case MATCH_MGE:
- case MATCH_MGE: /* true if greater than or equal */
-
- if (package_value < match_value) {
+ /*
+ * True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
+ * Change to: (M <= P[i]) (M not_greater than P[i])
+ */
+ status = acpi_ex_do_logical_op (AML_LGREATER_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE (status)) {
return (FALSE);
}
+ logical_result = (u8)!logical_result;
break;
+ case MATCH_MGT:
- case MATCH_MGT: /* true if greater than */
-
- if (package_value <= match_value) {
+ /*
+ * True if greater than: (P[i] > M)
+ * Change to: (M < P[i])
+ */
+ status = acpi_ex_do_logical_op (AML_LLESS_OP, match_obj, package_obj,
+ &logical_result);
+ if (ACPI_FAILURE (status)) {
return (FALSE);
}
break;
+ default:
- default: /* undefined */
+ /* Undefined */
return (FALSE);
}
-
- return TRUE;
+ return logical_result;
}
@@ -182,19 +226,21 @@ acpi_ex_opcode_6A_0T_1R (
switch (walk_state->opcode) {
case AML_MATCH_OP:
/*
- * Match (search_package[0], match_op1[1], match_object1[2],
- * match_op2[3], match_object2[4], start_index[5])
+ * Match (search_pkg[0], match_op1[1], match_obj1[2],
+ * match_op2[3], match_obj2[4], start_index[5])
*/
- /* Validate match comparison sub-opcodes */
+ /* Validate both Match Term Operators (MTR, MEQ, etc.) */
if ((operand[1]->integer.value > MAX_MATCH_OPERATOR) ||
(operand[3]->integer.value > MAX_MATCH_OPERATOR)) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "operation encoding out of range\n"));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Match operator out of range\n"));
status = AE_AML_OPERAND_VALUE;
goto cleanup;
}
+ /* Get the package start_index, validate against the package length */
+
index = (u32) operand[5]->integer.value;
if (index >= (u32) operand[0]->package.count) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index beyond package end\n"));
@@ -202,6 +248,8 @@ acpi_ex_opcode_6A_0T_1R (
goto cleanup;
}
+ /* Create an integer for the return value */
+
return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
if (!return_desc) {
status = AE_NO_MEMORY;
@@ -214,37 +262,39 @@ acpi_ex_opcode_6A_0T_1R (
return_desc->integer.value = ACPI_INTEGER_MAX;
/*
- * Examine each element until a match is found. Within the loop,
+ * Examine each element until a match is found. Both match conditions
+ * must be satisfied for a match to occur. Within the loop,
* "continue" signifies that the current element does not match
* and the next should be examined.
*
* Upon finding a match, the loop will terminate via "break" at
- * the bottom. If it terminates "normally", match_value will be -1
- * (its initial value) indicating that no match was found. When
- * returned as a Number, this will produce the Ones value as specified.
+ * the bottom. If it terminates "normally", match_value will be
+ * ACPI_INTEGER_MAX (Ones) (its initial value) indicating that no
+ * match was found.
*/
for ( ; index < operand[0]->package.count; index++) {
+ /* Get the current package element */
+
this_element = operand[0]->package.elements[index];
- /*
- * Treat any NULL or non-numeric elements as non-matching.
- */
- if (!this_element ||
- ACPI_GET_OBJECT_TYPE (this_element) != ACPI_TYPE_INTEGER) {
+ /* Treat any uninitialized (NULL) elements as non-matching */
+
+ if (!this_element) {
continue;
}
/*
- * "continue" (proceed to next iteration of enclosing
- * "for" loop) signifies a non-match.
+ * Both match conditions must be satisfied. Execution of a continue
+ * (proceed to next iteration of enclosing for loop) signifies a
+ * non-match.
*/
if (!acpi_ex_do_match ((u32) operand[1]->integer.value,
- this_element->integer.value, operand[2]->integer.value)) {
+ this_element, operand[2])) {
continue;
}
if (!acpi_ex_do_match ((u32) operand[3]->integer.value,
- this_element->integer.value, operand[4]->integer.value)) {
+ this_element, operand[4])) {
continue;
}
@@ -253,7 +303,6 @@ acpi_ex_opcode_6A_0T_1R (
return_desc->integer.value = index;
break;
}
-
break;
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index 8dcfa427930e..c92890220c32 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -312,7 +312,7 @@ acpi_ex_resolve_operands (
goto next_operand;
- case ARGI_ANYTYPE:
+ case ARGI_DATAREFOBJ: /* Store operator only */
/*
* We don't want to resolve index_op reference objects during
diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c
index 8b908fc894e0..e663a48f8a1c 100644
--- a/drivers/acpi/executer/exstoren.c
+++ b/drivers/acpi/executer/exstoren.c
@@ -206,6 +206,7 @@ acpi_ex_store_object_to_object (
{
union acpi_operand_object *actual_src_desc;
acpi_status status = AE_OK;
+ acpi_object_type original_src_type;
ACPI_FUNCTION_TRACE_PTR ("ex_store_object_to_object", source_desc);
@@ -222,7 +223,8 @@ acpi_ex_store_object_to_object (
return_ACPI_STATUS (status);
}
- if (ACPI_GET_OBJECT_TYPE (source_desc) != ACPI_GET_OBJECT_TYPE (dest_desc)) {
+ original_src_type = ACPI_GET_OBJECT_TYPE (source_desc);
+ if (original_src_type != ACPI_GET_OBJECT_TYPE (dest_desc)) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -232,15 +234,15 @@ acpi_ex_store_object_to_object (
* Otherwise, actual_src_desc is a temporary object to hold the
* converted object.
*/
- status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc), source_desc,
- &actual_src_desc, walk_state);
+ status = acpi_ex_convert_to_target_type (ACPI_GET_OBJECT_TYPE (dest_desc),
+ source_desc, &actual_src_desc, walk_state);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
if (source_desc == actual_src_desc) {
/*
- * No conversion was performed. Return the source_desc as the
+ * No conversion was performed. Return the source_desc as the
* new object.
*/
*new_desc = source_desc;
@@ -269,12 +271,18 @@ acpi_ex_store_object_to_object (
case ACPI_TYPE_BUFFER:
- status = acpi_ex_store_buffer_to_buffer (actual_src_desc, dest_desc);
+ /*
+ * Note: There is different store behavior depending on the original
+ * source type
+ */
+ status = acpi_ex_store_buffer_to_buffer (original_src_type, actual_src_desc,
+ dest_desc);
break;
case ACPI_TYPE_PACKAGE:
- status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc, walk_state);
+ status = acpi_ut_copy_iobject_to_iobject (actual_src_desc, &dest_desc,
+ walk_state);
break;
default:
diff --git a/drivers/acpi/executer/exstorob.c b/drivers/acpi/executer/exstorob.c
index d5f5349543f8..4e2b442ee5a3 100644
--- a/drivers/acpi/executer/exstorob.c
+++ b/drivers/acpi/executer/exstorob.c
@@ -66,6 +66,7 @@
acpi_status
acpi_ex_store_buffer_to_buffer (
+ acpi_object_type original_src_type,
union acpi_operand_object *source_desc,
union acpi_operand_object *target_desc)
{
@@ -104,9 +105,16 @@ acpi_ex_store_buffer_to_buffer (
ACPI_MEMSET (target_desc->buffer.pointer, 0, target_desc->buffer.length);
ACPI_MEMCPY (target_desc->buffer.pointer, buffer, length);
- /* Set the new length of the target */
+ /*
+ * If the original source was a string, we must truncate the buffer,
+ * according to the ACPI spec. Integer-to-Buffer and Buffer-to-Buffer
+ * copy must not truncate the original buffer.
+ */
+ if (original_src_type == ACPI_TYPE_STRING) {
+ /* Set the new length of the target */
- target_desc->buffer.length = length;
+ target_desc->buffer.length = length;
+ }
}
else {
/* Truncate the source, copy only what will fit */
diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c
index a84d7004993b..f2405efd1b9a 100644
--- a/drivers/acpi/namespace/nsxfname.c
+++ b/drivers/acpi/namespace/nsxfname.c
@@ -237,7 +237,7 @@ acpi_get_object_info (
{
acpi_status status;
struct acpi_namespace_node *node;
- struct acpi_device_info info;
+ struct acpi_device_info *info;
struct acpi_device_info *return_info;
struct acpi_compatible_id_list *cid_list = NULL;
acpi_size size;
@@ -254,55 +254,59 @@ acpi_get_object_info (
return (status);
}
+ info = ACPI_MEM_CALLOCATE (sizeof (struct acpi_device_info));
+ if (!info) {
+ return (AE_NO_MEMORY);
+ }
+
status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
- return (status);
+ goto cleanup;
}
node = acpi_ns_map_handle_to_node (handle);
if (!node) {
(void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
- return (AE_BAD_PARAMETER);
+ goto cleanup;
}
/* Init return structure */
size = sizeof (struct acpi_device_info);
- ACPI_MEMSET (&info, 0, size);
- info.type = node->type;
- info.name = node->name.integer;
- info.valid = 0;
+ info->type = node->type;
+ info->name = node->name.integer;
+ info->valid = 0;
status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE (status)) {
- return (status);
+ goto cleanup;
}
/* If not a device, we are all done */
- if (info.type == ACPI_TYPE_DEVICE) {
+ if (info->type == ACPI_TYPE_DEVICE) {
/*
* Get extra info for ACPI Devices objects only:
* Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods.
*
* Note: none of these methods are required, so they may or may
- * not be present for this device. The Info.Valid bitfield is used
+ * not be present for this device. The Info->Valid bitfield is used
* to indicate which methods were found and ran successfully.
*/
/* Execute the Device._HID method */
- status = acpi_ut_execute_HID (node, &info.hardware_id);
+ status = acpi_ut_execute_HID (node, &info->hardware_id);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_HID;
+ info->valid |= ACPI_VALID_HID;
}
/* Execute the Device._UID method */
- status = acpi_ut_execute_UID (node, &info.unique_id);
+ status = acpi_ut_execute_UID (node, &info->unique_id);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_UID;
+ info->valid |= ACPI_VALID_UID;
}
/* Execute the Device._CID method */
@@ -311,32 +315,30 @@ acpi_get_object_info (
if (ACPI_SUCCESS (status)) {
size += ((acpi_size) cid_list->count - 1) *
sizeof (struct acpi_compatible_id);
- info.valid |= ACPI_VALID_CID;
+ info->valid |= ACPI_VALID_CID;
}
/* Execute the Device._STA method */
- status = acpi_ut_execute_STA (node, &info.current_status);
+ status = acpi_ut_execute_STA (node, &info->current_status);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_STA;
+ info->valid |= ACPI_VALID_STA;
}
/* Execute the Device._ADR method */
status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node,
- &info.address);
+ &info->address);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_ADR;
+ info->valid |= ACPI_VALID_ADR;
}
/* Execute the Device._sx_d methods */
- status = acpi_ut_execute_sxds (node, info.highest_dstates);
+ status = acpi_ut_execute_sxds (node, info->highest_dstates);
if (ACPI_SUCCESS (status)) {
- info.valid |= ACPI_VALID_SXDS;
+ info->valid |= ACPI_VALID_SXDS;
}
-
- status = AE_OK;
}
/* Validate/Allocate/Clear caller buffer */
@@ -349,7 +351,7 @@ acpi_get_object_info (
/* Populate the return buffer */
return_info = buffer->pointer;
- ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info));
+ ACPI_MEMCPY (return_info, info, sizeof (struct acpi_device_info));
if (cid_list) {
ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size);
@@ -357,6 +359,7 @@ acpi_get_object_info (
cleanup:
+ ACPI_MEM_FREE (info);
if (cid_list) {
ACPI_MEM_FREE (cid_list);
}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index eb1f4179128f..c1360fc23cee 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -289,7 +289,7 @@
#define ARGI_LOCAL6 ARG_NONE
#define ARGI_LOCAL7 ARG_NONE
#define ARGI_LOR_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER)
-#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER)
+#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_COMPUTEDATA, ARGI_INTEGER,ARGI_COMPUTEDATA,ARGI_INTEGER)
#define ARGI_METHOD_OP ARGI_INVALID_OPCODE
#define ARGI_METHODCALL_OP ARGI_INVALID_OPCODE
#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFER_OR_STRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c
index dfc1559b173d..334327c1f66f 100644
--- a/drivers/acpi/tables/tbconvrt.c
+++ b/drivers/acpi/tables/tbconvrt.c
@@ -269,8 +269,8 @@ acpi_tb_convert_fadt1 (
* that immediately follows.
*/
ACPI_MEMCPY (&local_fadt->reset_register,
- &((struct fadt_descriptor_rev2_minus *) original_fadt)->reset_register,
- sizeof (struct acpi_generic_address) + 1);
+ &(ACPI_CAST_PTR (struct fadt_descriptor_rev2_minus, original_fadt))->reset_register,
+ sizeof (struct acpi_generic_address) + 1);
}
else {
/*
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index a830919a1de4..6701c11b406b 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20050125
+#define ACPI_CA_VERSION 0x20050211
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index 6a5cbb355685..78395916e4cf 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -217,8 +217,8 @@ acpi_ex_opcode_6A_0T_1R (
u8
acpi_ex_do_match (
u32 match_op,
- acpi_integer package_value,
- acpi_integer match_value);
+ union acpi_operand_object *package_obj,
+ union acpi_operand_object *match_obj);
acpi_status
acpi_ex_get_object_reference (
@@ -617,6 +617,7 @@ acpi_ex_store_object_to_object (
acpi_status
acpi_ex_store_buffer_to_buffer (
+ acpi_object_type original_src_type,
union acpi_operand_object *source_desc,
union acpi_operand_object *target_desc);
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index d807f2981d95..a3de0db85694 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -81,6 +81,8 @@
#define ACPI_USE_NATIVE_DIVIDE
#endif
+#define __cdecl
+#define ACPI_FLUSH_CPU_CACHE()
#endif /* __KERNEL__ */
/* Linux uses GCC */