Commit 3d53ecae authored by Len Brown's avatar Len Brown

Merge intel.com:/home/lenb/bk/26-latest-ref

into intel.com:/home/lenb/src/26-latest-dev
parents 9694f976 ce919ce1
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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:
......
......@@ -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 */
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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 {
/*
......
......@@ -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,
......
......@@ -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);
......
......@@ -81,6 +81,8 @@
#define ACPI_USE_NATIVE_DIVIDE
#endif
#define __cdecl
#define ACPI_FLUSH_CPU_CACHE()
#endif /* __KERNEL__ */
/* Linux uses GCC */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment