summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dispatcher/dswexec.c3
-rw-r--r--drivers/acpi/executer/exconvrt.c320
-rw-r--r--drivers/acpi/executer/exfldio.c2
-rw-r--r--drivers/acpi/executer/exmisc.c464
-rw-r--r--drivers/acpi/executer/exoparg1.c22
-rw-r--r--drivers/acpi/executer/exoparg2.c95
-rw-r--r--drivers/acpi/executer/exresop.c12
-rw-r--r--drivers/acpi/namespace/nsnames.c6
-rw-r--r--drivers/acpi/parser/psopcode.c4
-rw-r--r--drivers/acpi/utilities/utalloc.c5
-rw-r--r--drivers/acpi/utilities/utobject.c62
-rw-r--r--include/acpi/acconfig.h2
-rw-r--r--include/acpi/acinterp.h32
-rw-r--r--include/acpi/acobject.h5
-rw-r--r--include/acpi/actypes.h9
-rw-r--r--include/acpi/acutils.h4
-rw-r--r--include/acpi/amlcode.h25
-rw-r--r--include/acpi/amlresrc.h4
18 files changed, 626 insertions, 450 deletions
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index 02872ca223d2..148040c09a75 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -639,7 +639,8 @@ acpi_ds_exec_end_op (
* conditional predicate
*/
- if ((walk_state->control_state) &&
+ if ((ACPI_SUCCESS (status)) &&
+ (walk_state->control_state) &&
(walk_state->control_state->common.state ==
ACPI_CONTROL_PREDICATE_EXECUTING) &&
(walk_state->control_state->control.predicate_op == op)) {
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index 04c04e4ae39b..8b9df9274f83 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -58,7 +58,7 @@
* PARAMETERS: obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* result_desc - Where the new Integer object is returned
- * walk_state - Current method state
+ * Opcode - AML opcode
*
* RETURN: Status
*
@@ -70,13 +70,13 @@ acpi_status
acpi_ex_convert_to_integer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state)
+ u16 opcode)
{
- u32 i;
- union acpi_operand_object *ret_desc;
- u32 count;
+ union acpi_operand_object *return_desc;
u8 *pointer;
acpi_integer result;
+ u32 i;
+ u32 count;
acpi_status status;
@@ -85,15 +85,17 @@ acpi_ex_convert_to_integer (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_INTEGER:
+
+ /* No conversion necessary */
+
*result_desc = obj_desc;
return_ACPI_STATUS (AE_OK);
+ case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
- pointer = (u8 *) obj_desc->string.pointer;
- count = obj_desc->string.length;
- break;
- case ACPI_TYPE_BUFFER:
+ /* Note: Takes advantage of common buffer/string fields */
+
pointer = obj_desc->buffer.pointer;
count = obj_desc->buffer.length;
break;
@@ -126,8 +128,8 @@ acpi_ex_convert_to_integer (
case ACPI_TYPE_STRING:
/*
- * Convert string to an integer
- * String must be hexadecimal as per the ACPI specification
+ * Convert string to an integer - the string must be hexadecimal
+ * as per the ACPI specification
*/
status = acpi_ut_strtoul64 ((char *) pointer, 16, &result);
if (ACPI_FAILURE (status)) {
@@ -139,8 +141,8 @@ acpi_ex_convert_to_integer (
case ACPI_TYPE_BUFFER:
/*
- * Buffer conversion - we simply grab enough raw data from the
- * buffer to fill an integer
+ * Convert buffer to an integer - we simply grab enough raw data
+ * from the buffer to fill an integer
*/
for (i = 0; i < count; i++) {
/*
@@ -161,14 +163,14 @@ acpi_ex_convert_to_integer (
/*
* Create a new integer
*/
- ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
- if (!ret_desc) {
+ return_desc = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
+ if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Save the Result */
- ret_desc->integer.value = result;
+ return_desc->integer.value = result;
/*
* If we are about to overwrite the original object on the operand stack,
@@ -176,12 +178,12 @@ acpi_ex_convert_to_integer (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
- if (walk_state->opcode != AML_STORE_OP) {
+ if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
- *result_desc = ret_desc;
+ *result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
@@ -193,7 +195,7 @@ acpi_ex_convert_to_integer (
* PARAMETERS: obj_desc - Object to be converted. Must be an
* Integer, Buffer, or String
* result_desc - Where the new buffer object is returned
- * walk_state - Current method state
+ * Opcode - AML opcode
*
* RETURN: Status
*
@@ -205,10 +207,9 @@ acpi_status
acpi_ex_convert_to_buffer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state)
+ u16 opcode)
{
- union acpi_operand_object *ret_desc;
- u32 i;
+ union acpi_operand_object *return_desc;
u8 *new_buf;
@@ -230,17 +231,17 @@ acpi_ex_convert_to_buffer (
* Create a new Buffer object.
* Need enough space for one integer
*/
- ret_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
- if (!ret_desc) {
+ return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width);
+ if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /* Copy the integer to the buffer */
+ /* Copy the integer to the buffer, LSB first */
- new_buf = ret_desc->buffer.pointer;
- for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
- new_buf[i] = (u8) (obj_desc->integer.value >> (i * 8));
- }
+ new_buf = return_desc->buffer.pointer;
+ ACPI_MEMCPY (new_buf,
+ &obj_desc->integer.value,
+ acpi_gbl_integer_byte_width);
break;
@@ -250,14 +251,14 @@ acpi_ex_convert_to_buffer (
* Create a new Buffer object
* Size will be the string length
*/
- ret_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
- if (!ret_desc) {
+ return_desc = acpi_ut_create_buffer_object ((acpi_size) obj_desc->string.length);
+ if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
/* Copy the string to the buffer */
- new_buf = ret_desc->buffer.pointer;
+ new_buf = return_desc->buffer.pointer;
ACPI_STRNCPY ((char *) new_buf, (char *) obj_desc->string.pointer,
obj_desc->string.length);
break;
@@ -269,7 +270,7 @@ acpi_ex_convert_to_buffer (
/* Mark buffer initialized */
- ret_desc->common.flags |= AOPOBJ_DATA_VALID;
+ return_desc->common.flags |= AOPOBJ_DATA_VALID;
/*
* If we are about to overwrite the original object on the operand stack,
@@ -277,24 +278,24 @@ acpi_ex_convert_to_buffer (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
- if (walk_state->opcode != AML_STORE_OP) {
+ if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
- *result_desc = ret_desc;
+ *result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: acpi_ex_convert_ascii
+ * FUNCTION: acpi_ex_convert_to_ascii
*
* PARAMETERS: Integer - Value to be converted
- * Base - 10 or 16
+ * Base - ACPI_STRING_DECIMAL or ACPI_STRING_HEX
* String - Where the string is returned
- * data_width - Size of data item to be converted
+ * data_width - Size of data item to be converted, in bytes
*
* RETURN: Actual string length
*
@@ -305,37 +306,47 @@ acpi_ex_convert_to_buffer (
u32
acpi_ex_convert_to_ascii (
acpi_integer integer,
- u32 base,
+ u16 base,
u8 *string,
u8 data_width)
{
- u32 i;
- u32 j;
- u32 k = 0;
- char hex_digit;
acpi_integer digit;
+ acpi_native_uint i;
+ acpi_native_uint j;
+ acpi_native_uint k = 0;
+ acpi_native_uint hex_length;
+ acpi_native_uint decimal_length;
u32 remainder;
- u32 length;
- u8 leading_zero;
+ u8 supress_zeros;
ACPI_FUNCTION_ENTRY ();
- if (data_width < sizeof (acpi_integer)) {
- leading_zero = FALSE;
- length = data_width;
- }
- else {
- leading_zero = TRUE;
- length = sizeof (acpi_integer);
- }
-
switch (base) {
case 10:
+ /* Setup max length for the decimal number */
+
+ switch (data_width) {
+ case 1:
+ decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
+ break;
+
+ case 4:
+ decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
+ break;
+
+ case 8:
+ default:
+ decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
+ break;
+ }
+
+ supress_zeros = TRUE; /* No leading zeros */
remainder = 0;
- for (i = ACPI_MAX_DECIMAL_DIGITS; i > 0; i--) {
+
+ for (i = decimal_length; i > 0; i--) {
/* Divide by nth factor of 10 */
digit = integer;
@@ -343,41 +354,33 @@ acpi_ex_convert_to_ascii (
(void) acpi_ut_short_divide (&digit, 10, &digit, &remainder);
}
- /* Create the decimal digit */
+ /* Handle leading zeros */
if (remainder != 0) {
- leading_zero = FALSE;
+ supress_zeros = FALSE;
}
- if (!leading_zero) {
+ if (!supress_zeros) {
string[k] = (u8) (ACPI_ASCII_ZERO + remainder);
k++;
}
}
break;
-
case 16:
- /* Copy the integer to the buffer */
+ hex_length = ACPI_MUL_2 (data_width); /* 2 ascii hex chars per data byte */
- for (i = 0, j = ((length * 2) -1); i < (length * 2); i++, j--) {
-
- hex_digit = acpi_ut_hex_to_ascii_char (integer, (j * 4));
- if (hex_digit != ACPI_ASCII_ZERO) {
- leading_zero = FALSE;
- }
+ for (i = 0, j = (hex_length-1); i < hex_length; i++, j--) {
+ /* Get one hex digit, most significant digits first */
- if (!leading_zero) {
- string[k] = (u8) hex_digit;
- k++;
- }
+ string[k] = (u8) acpi_ut_hex_to_ascii_char (integer, ACPI_MUL_4 (j));
+ k++;
}
break;
-
default:
- break;
+ return (0);
}
/*
@@ -392,7 +395,7 @@ acpi_ex_convert_to_ascii (
}
string [k] = 0;
- return (k);
+ return ((u32) k);
}
@@ -401,11 +404,10 @@ acpi_ex_convert_to_ascii (
* FUNCTION: acpi_ex_convert_to_string
*
* PARAMETERS: obj_desc - Object to be converted. Must be an
- * Integer, Buffer, or String
+ * Integer, Buffer, or String
* result_desc - Where the string object is returned
- * Base - 10 or 16
- * max_length - Max length of the returned string
- * walk_state - Current method state
+ * Type - String flags (base and conversion type)
+ * Opcode - AML opcode
*
* RETURN: Status
*
@@ -417,15 +419,15 @@ acpi_status
acpi_ex_convert_to_string (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- u32 base,
- u32 max_length,
- struct acpi_walk_state *walk_state)
+ u32 type,
+ u16 opcode)
{
- union acpi_operand_object *ret_desc;
+ union acpi_operand_object *return_desc;
u8 *new_buf;
- u8 *pointer;
- u32 string_length;
+ u32 string_length = 0;
+ u16 base = 16;
u32 i;
+ u8 separator = ',';
ACPI_FUNCTION_TRACE_PTR ("ex_convert_to_string", obj_desc);
@@ -434,114 +436,117 @@ acpi_ex_convert_to_string (
switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
case ACPI_TYPE_STRING:
- if (max_length >= obj_desc->string.length) {
- *result_desc = obj_desc;
- return_ACPI_STATUS (AE_OK);
- }
- else {
- /* Must copy the string first and then truncate it */
+ /* No conversion necessary */
- return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
- }
+ *result_desc = obj_desc;
+ return_ACPI_STATUS (AE_OK);
case ACPI_TYPE_INTEGER:
- string_length = acpi_gbl_integer_byte_width * 2;
- if (base == 10) {
+ switch (type) {
+ case ACPI_EXPLICIT_CONVERT_DECIMAL:
+
+ /* Make room for maximum decimal number */
+
string_length = ACPI_MAX_DECIMAL_DIGITS;
+ base = 10;
+ break;
+
+ default:
+
+ /* Two hex string characters for each integer byte */
+
+ string_length = ACPI_MUL_2 (acpi_gbl_integer_byte_width);
+ break;
}
/*
* Create a new String
+ * Need enough space for one ASCII integer plus null terminator
*/
- ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
- if (!ret_desc) {
+ return_desc = acpi_ut_create_string_object ((acpi_size) string_length + 1);
+ if (!return_desc) {
return_ACPI_STATUS (AE_NO_MEMORY);
}
- /* Need enough space for one ASCII integer plus null terminator */
+ new_buf = return_desc->buffer.pointer;
- new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
- if (!new_buf) {
- ACPI_REPORT_ERROR
- (("ex_convert_to_string: Buffer allocation failure\n"));
- acpi_ut_remove_reference (ret_desc);
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
-
- /* Convert */
+ /* Convert integer to string */
- i = acpi_ex_convert_to_ascii (obj_desc->integer.value, base, new_buf, sizeof (acpi_integer));
+ string_length = acpi_ex_convert_to_ascii (obj_desc->integer.value, base,
+ new_buf, acpi_gbl_integer_byte_width);
/* Null terminate at the correct place */
- if (max_length < i) {
- new_buf[max_length] = 0;
- ret_desc->string.length = max_length;
- }
- else {
- new_buf [i] = 0;
- ret_desc->string.length = i;
- }
-
- ret_desc->buffer.pointer = new_buf;
+ new_buf [string_length] = 0;
break;
case ACPI_TYPE_BUFFER:
- /* Find the string length */
+ switch (type) {
+ case ACPI_EXPLICIT_CONVERT_DECIMAL: /* Used by to_decimal_string operator */
+ /*
+ * From ACPI: "If Data is a buffer, it is converted to a string of
+ * decimal values separated by commas."
+ */
+ base = 10;
+ string_length = obj_desc->buffer.length; /* 4 chars for each decimal */
- pointer = obj_desc->buffer.pointer;
- for (string_length = 0; string_length < obj_desc->buffer.length; string_length++) {
- /* Exit on null terminator */
+ /*lint -fallthrough */
- if (!pointer[string_length]) {
- break;
+ case ACPI_IMPLICIT_CONVERT_HEX:
+ /*
+ * From the ACPI spec:
+ *"The entire contents of the buffer are converted to a string of
+ * two-character hexadecimal numbers, each separated by a space."
+ */
+ if (type == ACPI_IMPLICIT_CONVERT_HEX) {
+ separator = ' ';
}
- }
- if (max_length > ACPI_MAX_STRING_CONVERSION) {
- if (string_length > ACPI_MAX_STRING_CONVERSION) {
+ /*lint -fallthrough */
+
+ case ACPI_EXPLICIT_CONVERT_HEX: /* Used by to_hex_string operator */
+ /*
+ * From ACPI: "If Data is a buffer, it is converted to a string of
+ * hexadecimal values separated by commas."
+ */
+ string_length += (obj_desc->buffer.length * 3);
+ if (string_length > ACPI_MAX_STRING_CONVERSION) /* ACPI limit */ {
return_ACPI_STATUS (AE_AML_STRING_LIMIT);
}
- }
- /*
- * Create a new string object
- */
- ret_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
- if (!ret_desc) {
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
+ /* Create a new string object and string buffer */
- /* String length is the lesser of the Max or the actual length */
+ return_desc = acpi_ut_create_string_object ((acpi_size) string_length);
+ if (!return_desc) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
- if (max_length < string_length) {
- string_length = max_length;
- }
+ new_buf = return_desc->buffer.pointer;
- new_buf = ACPI_MEM_CALLOCATE ((acpi_size) string_length + 1);
- if (!new_buf) {
- ACPI_REPORT_ERROR
- (("ex_convert_to_string: Buffer allocation failure\n"));
- acpi_ut_remove_reference (ret_desc);
- return_ACPI_STATUS (AE_NO_MEMORY);
- }
+ /* Convert buffer bytes to hex or decimal values (separated by commas) */
- /* Copy the appropriate number of buffer characters */
+ for (i = 0; i < obj_desc->buffer.length; i++) {
+ new_buf += acpi_ex_convert_to_ascii (
+ (acpi_integer) obj_desc->buffer.pointer[i], base,
+ new_buf, 1);
+ *new_buf++ = separator; /* each separated by a comma or space */
+ }
- ACPI_MEMCPY (new_buf, pointer, string_length);
+ /* Null terminate the string (overwrites final comma from above) */
- /* Null terminate */
+ new_buf--;
+ *new_buf = 0;
+ break;
- new_buf [string_length] = 0;
- ret_desc->buffer.pointer = new_buf;
- ret_desc->string.length = string_length;
+ default:
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
break;
-
default:
return_ACPI_STATUS (AE_TYPE);
}
@@ -552,12 +557,12 @@ acpi_ex_convert_to_string (
* essentially removing it from the stack.
*/
if (*result_desc == obj_desc) {
- if (walk_state->opcode != AML_STORE_OP) {
+ if (opcode != AML_STORE_OP) {
acpi_ut_remove_reference (obj_desc);
}
}
- *result_desc = ret_desc;
+ *result_desc = return_desc;
return_ACPI_STATUS (AE_OK);
}
@@ -635,7 +640,8 @@ acpi_ex_convert_to_target_type (
* These types require an Integer operand. We can convert
* a Buffer or a String to an Integer if necessary.
*/
- status = acpi_ex_convert_to_integer (source_desc, result_desc, walk_state);
+ status = acpi_ex_convert_to_integer (source_desc, result_desc,
+ walk_state->opcode);
break;
@@ -645,7 +651,8 @@ acpi_ex_convert_to_target_type (
* The operand must be a String. We can convert an
* Integer or Buffer if necessary
*/
- status = acpi_ex_convert_to_string (source_desc, result_desc, 16, ACPI_UINT32_MAX, walk_state);
+ status = acpi_ex_convert_to_string (source_desc, result_desc,
+ ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
break;
@@ -655,7 +662,8 @@ acpi_ex_convert_to_target_type (
* The operand must be a Buffer. We can convert an
* Integer or String if necessary
*/
- status = acpi_ex_convert_to_buffer (source_desc, result_desc, walk_state);
+ status = acpi_ex_convert_to_buffer (source_desc, result_desc,
+ walk_state->opcode);
break;
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 03ccfb9e10f0..5f8fbdb16e11 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -139,7 +139,7 @@ acpi_ex_setup_region (
if (ACPI_ROUND_UP (rgn_desc->region.length,
obj_desc->common_field.access_byte_width) >=
(obj_desc->common_field.base_byte_offset +
- obj_desc->common_field.access_byte_width +
+ (acpi_native_uint) obj_desc->common_field.access_byte_width +
field_datum_byte_offset)) {
return_ACPI_STATUS (AE_OK);
}
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c
index 961a949e9797..a8aaeafc5e9c 100644
--- a/drivers/acpi/executer/exmisc.c
+++ b/drivers/acpi/executer/exmisc.c
@@ -149,8 +149,9 @@ acpi_ex_get_object_reference (
*
* FUNCTION: acpi_ex_concat_template
*
- * PARAMETERS: *obj_desc - Object to be converted. Must be an
- * Integer, Buffer, or String
+ * PARAMETERS: Operand0 - First source object
+ * Operand1 - Second source object
+ * actual_return_desc - Where to place the return object
* walk_state - Current walk state
*
* RETURN: Status
@@ -161,8 +162,8 @@ acpi_ex_get_object_reference (
acpi_status
acpi_ex_concat_template (
- union acpi_operand_object *obj_desc1,
- union acpi_operand_object *obj_desc2,
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state)
{
@@ -179,16 +180,16 @@ acpi_ex_concat_template (
/* Find the end_tags in each resource template */
- end_tag1 = acpi_ut_get_resource_end_tag (obj_desc1);
- end_tag2 = acpi_ut_get_resource_end_tag (obj_desc2);
+ end_tag1 = acpi_ut_get_resource_end_tag (operand0);
+ end_tag2 = acpi_ut_get_resource_end_tag (operand1);
if (!end_tag1 || !end_tag2) {
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
}
/* Compute the length of each part */
- length1 = ACPI_PTR_DIFF (end_tag1, obj_desc1->buffer.pointer);
- length2 = ACPI_PTR_DIFF (end_tag2, obj_desc2->buffer.pointer) +
+ length1 = ACPI_PTR_DIFF (end_tag1, operand0->buffer.pointer);
+ length2 = ACPI_PTR_DIFF (end_tag2, operand1->buffer.pointer) +
2; /* Size of END_TAG */
/* Create a new buffer object for the result */
@@ -201,8 +202,8 @@ acpi_ex_concat_template (
/* Copy the templates to the new descriptor */
new_buf = return_desc->buffer.pointer;
- ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer, length1);
- ACPI_MEMCPY (new_buf + length1, obj_desc2->buffer.pointer, length2);
+ ACPI_MEMCPY (new_buf, operand0->buffer.pointer, length1);
+ ACPI_MEMCPY (new_buf + length1, operand1->buffer.pointer, length2);
/* Compute the new checksum */
@@ -221,8 +222,8 @@ acpi_ex_concat_template (
*
* FUNCTION: acpi_ex_do_concatenate
*
- * PARAMETERS: obj_desc1 - First source object
- * obj_desc2 - Second source object
+ * PARAMETERS: Operand0 - First source object
+ * Operand1 - Second source object
* actual_return_desc - Where to place the return object
* walk_state - Current walk state
*
@@ -234,20 +235,58 @@ acpi_ex_concat_template (
acpi_status
acpi_ex_do_concatenate (
- union acpi_operand_object *obj_desc1,
- union acpi_operand_object *obj_desc2,
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state)
{
- acpi_status status;
- u32 i;
- acpi_integer this_integer;
+ union acpi_operand_object *local_operand1 = operand1;
union acpi_operand_object *return_desc;
char *new_buf;
+ acpi_status status;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_TRACE ("ex_do_concatenate");
+
+
+ /*
+ * Convert the second operand if necessary. The first operand
+ * determines the type of the second operand, (See the Data Types
+ * section of the ACPI specification.) Both object types are
+ * guaranteed to be either Integer/String/Buffer by the operand
+ * resolution mechanism.
+ */
+ switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+ case ACPI_TYPE_INTEGER:
+ status = acpi_ex_convert_to_integer (operand1, &local_operand1,
+ walk_state->opcode);
+ break;
+
+ case ACPI_TYPE_STRING:
+ status = acpi_ex_convert_to_string (operand1, &local_operand1,
+ ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
+ break;
+
+ case ACPI_TYPE_BUFFER:
+ status = acpi_ex_convert_to_buffer (operand1, &local_operand1,
+ walk_state->opcode);
+ break;
+
+ default:
+ ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
+ ACPI_GET_OBJECT_TYPE (operand0)));
+ status = AE_AML_INTERNAL;
+ }
+ if (ACPI_FAILURE (status)) {
+ goto cleanup;
+ }
+
+ /*
+ * Both operands are now known to be the same object type
+ * (Both are Integer, String, or Buffer), and we can now perform the
+ * concatenation.
+ */
/*
* There are three cases to handle:
@@ -256,113 +295,97 @@ acpi_ex_do_concatenate (
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
- switch (ACPI_GET_OBJECT_TYPE (obj_desc1)) {
+ switch (ACPI_GET_OBJECT_TYPE (operand0)) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
/* Need enough buffer space for two integers */
- return_desc = acpi_ut_create_buffer_object (acpi_gbl_integer_byte_width * 2);
+ return_desc = acpi_ut_create_buffer_object (
+ ACPI_MUL_2 (acpi_gbl_integer_byte_width));
if (!return_desc) {
- return (AE_NO_MEMORY);
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
new_buf = (char *) return_desc->buffer.pointer;
- /* Convert the first integer */
-
- this_integer = obj_desc1->integer.value;
- for (i = 0; i < acpi_gbl_integer_byte_width; i++) {
- new_buf[i] = (char) this_integer;
- this_integer >>= 8;
- }
+ /* Copy the first integer, LSB first */
- /* Convert the second integer */
+ ACPI_MEMCPY (new_buf,
+ &operand0->integer.value,
+ acpi_gbl_integer_byte_width);
- this_integer = obj_desc2->integer.value;
- for (; i < (ACPI_MUL_2 (acpi_gbl_integer_byte_width)); i++) {
- new_buf[i] = (char) this_integer;
- this_integer >>= 8;
- }
+ /* Copy the second integer (LSB first) after the first */
+ ACPI_MEMCPY (new_buf + acpi_gbl_integer_byte_width,
+ &local_operand1->integer.value,
+ acpi_gbl_integer_byte_width);
break;
-
case ACPI_TYPE_STRING:
/* Result of two Strings is a String */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+ return_desc = acpi_ut_create_string_object (
+ (acpi_size) operand0->string.length +
+ (acpi_size) local_operand1->string.length + 1);
if (!return_desc) {
- return (AE_NO_MEMORY);
- }
-
- /* Operand0 is string */
-
- new_buf = ACPI_MEM_CALLOCATE ((acpi_size) obj_desc1->string.length +
- (acpi_size) obj_desc2->string.length + 1);
- if (!new_buf) {
- ACPI_REPORT_ERROR
- (("ex_do_concatenate: String allocation failure\n"));
status = AE_NO_MEMORY;
goto cleanup;
}
- /* Concatenate the strings */
-
- ACPI_STRCPY (new_buf, obj_desc1->string.pointer);
- ACPI_STRCPY (new_buf + obj_desc1->string.length,
- obj_desc2->string.pointer);
+ new_buf = return_desc->string.pointer;
- /* Complete the String object initialization */
+ /* Concatenate the strings */
- return_desc->string.pointer = new_buf;
- return_desc->string.length = obj_desc1->string.length +
- obj_desc2->string.length;
+ ACPI_STRCPY (new_buf,
+ operand0->string.pointer);
+ ACPI_STRCPY (new_buf + operand0->string.length,
+ local_operand1->string.pointer);
break;
-
case ACPI_TYPE_BUFFER:
/* Result of two Buffers is a Buffer */
return_desc = acpi_ut_create_buffer_object (
- (acpi_size) obj_desc1->buffer.length +
- (acpi_size) obj_desc2->buffer.length);
+ (acpi_size) operand0->buffer.length +
+ (acpi_size) local_operand1->buffer.length);
if (!return_desc) {
- return (AE_NO_MEMORY);
+ status = AE_NO_MEMORY;
+ goto cleanup;
}
new_buf = (char *) return_desc->buffer.pointer;
/* Concatenate the buffers */
- ACPI_MEMCPY (new_buf, obj_desc1->buffer.pointer,
- obj_desc1->buffer.length);
- ACPI_MEMCPY (new_buf + obj_desc1->buffer.length, obj_desc2->buffer.pointer,
- obj_desc2->buffer.length);
-
+ ACPI_MEMCPY (new_buf,
+ operand0->buffer.pointer,
+ operand0->buffer.length);
+ ACPI_MEMCPY (new_buf + operand0->buffer.length,
+ local_operand1->buffer.pointer,
+ local_operand1->buffer.length);
break;
-
default:
/* Invalid object type, should not happen here */
- ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
- ACPI_GET_OBJECT_TYPE (obj_desc1)));
- status = AE_AML_INTERNAL;
- return_desc = NULL;
+ ACPI_REPORT_ERROR (("Concatenate - Invalid object type: %X\n",
+ ACPI_GET_OBJECT_TYPE (operand0)));
+ status =AE_AML_INTERNAL;
+ goto cleanup;
}
*actual_return_desc = return_desc;
- return (AE_OK);
-
cleanup:
-
- acpi_ut_remove_reference (return_desc);
- return (status);
+ if (local_operand1 != operand1) {
+ acpi_ut_remove_reference (local_operand1);
+ }
+ return_ACPI_STATUS (AE_OK);
}
@@ -371,8 +394,8 @@ cleanup:
* FUNCTION: acpi_ex_do_math_op
*
* PARAMETERS: Opcode - AML opcode
- * Operand0 - Integer operand #0
- * Operand1 - Integer operand #1
+ * Integer0 - Integer operand #0
+ * Integer1 - Integer operand #1
*
* RETURN: Integer result of the operation
*
@@ -385,62 +408,62 @@ cleanup:
acpi_integer
acpi_ex_do_math_op (
u16 opcode,
- acpi_integer operand0,
- acpi_integer operand1)
+ acpi_integer integer0,
+ acpi_integer integer1)
{
ACPI_FUNCTION_ENTRY ();
switch (opcode) {
- case AML_ADD_OP: /* Add (Operand0, Operand1, Result) */
+ case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */
- return (operand0 + operand1);
+ return (integer0 + integer1);
- case AML_BIT_AND_OP: /* And (Operand0, Operand1, Result) */
+ case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */
- return (operand0 & operand1);
+ return (integer0 & integer1);
- case AML_BIT_NAND_OP: /* NAnd (Operand0, Operand1, Result) */
+ case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */
- return (~(operand0 & operand1));
+ return (~(integer0 & integer1));
- case AML_BIT_OR_OP: /* Or (Operand0, Operand1, Result) */
+ case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */
- return (operand0 | operand1);
+ return (integer0 | integer1);
- case AML_BIT_NOR_OP: /* NOr (Operand0, Operand1, Result) */
+ case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */
- return (~(operand0 | operand1));
+ return (~(integer0 | integer1));
- case AML_BIT_XOR_OP: /* XOr (Operand0, Operand1, Result) */
+ case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */
- return (operand0 ^ operand1);
+ return (integer0 ^ integer1);
- case AML_MULTIPLY_OP: /* Multiply (Operand0, Operand1, Result) */
+ case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */
- return (operand0 * operand1);
+ return (integer0 * integer1);
case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */
- return (operand0 << operand1);
+ return (integer0 << integer1);
case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */
- return (operand0 >> operand1);
+ return (integer0 >> integer1);
- case AML_SUBTRACT_OP: /* Subtract (Operand0, Operand1, Result) */
+ case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */
- return (operand0 - operand1);
+ return (integer0 - integer1);
default:
@@ -451,20 +474,84 @@ acpi_ex_do_math_op (
/*******************************************************************************
*
+ * FUNCTION: acpi_ex_do_logical_numeric_op
+ *
+ * PARAMETERS: Opcode - AML opcode
+ * Integer0 - Integer operand #0
+ * Integer1 - Integer operand #1
+ * logical_result - TRUE/FALSE result of the operation
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric
+ * operators (LAnd and LOr), both operands must be integers.
+ *
+ * Note: cleanest machine code seems to be produced by the code
+ * below, rather than using statements of the form:
+ * Result = (Integer0 && Integer1);
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ex_do_logical_numeric_op (
+ u16 opcode,
+ acpi_integer integer0,
+ acpi_integer integer1,
+ u8 *logical_result)
+{
+ acpi_status status = AE_OK;
+ u8 local_result = FALSE;
+
+
+ ACPI_FUNCTION_TRACE ("ex_do_logical_numeric_op");
+
+
+ switch (opcode) {
+ case AML_LAND_OP: /* LAnd (Integer0, Integer1) */
+
+ if (integer0 && integer1) {
+ local_result = TRUE;
+ }
+ break;
+
+ case AML_LOR_OP: /* LOr (Integer0, Integer1) */
+
+ if (integer0 || integer1) {
+ local_result = TRUE;
+ }
+ break;
+
+ default:
+ status = AE_AML_INTERNAL;
+ break;
+ }
+
+ /* Return the logical result and status */
+
+ *logical_result = local_result;
+ return_ACPI_STATUS (status);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ex_do_logical_op
*
* PARAMETERS: Opcode - AML opcode
- * obj_desc0 - operand #0
- * obj_desc1 - operand #1
+ * Operand0 - operand #0
+ * Operand1 - operand #1
+ * logical_result - TRUE/FALSE result of the operation
*
- * RETURN: TRUE/FALSE result of the operation
+ * RETURN: Status
*
* DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
* functions here is to prevent a lot of pointer dereferencing
* to obtain the operands and to simplify the generation of the
- * logical value. Both operands must already be validated as
- * 1) Both the same type, and
- * 2) Either Integer, Buffer, or String type.
+ * logical value. For the Numeric operators (LAnd and LOr), both
+ * operands must be integers. For the other logical operators,
+ * operands can be any combination of Integer/String/Buffer. The
+ * first operand determines the type to which the second operand
+ * will be converted.
*
* Note: cleanest machine code seems to be produced by the code
* below, rather than using statements of the form:
@@ -472,143 +559,174 @@ acpi_ex_do_math_op (
*
******************************************************************************/
-u8
+acpi_status
acpi_ex_do_logical_op (
u16 opcode,
- union acpi_operand_object *obj_desc0,
- union acpi_operand_object *obj_desc1)
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
+ u8 *logical_result)
{
- acpi_integer operand0;
- acpi_integer operand1;
- u8 *ptr0;
- u8 *ptr1;
+ union acpi_operand_object *local_operand1 = operand1;
+ acpi_integer integer0;
+ acpi_integer integer1;
u32 length0;
u32 length1;
- u32 i;
+ acpi_status status = AE_OK;
+ u8 local_result = FALSE;
+ int compare;
- ACPI_FUNCTION_ENTRY ();
+ ACPI_FUNCTION_TRACE ("ex_do_logical_op");
- if (ACPI_GET_OBJECT_TYPE (obj_desc0) == ACPI_TYPE_INTEGER) {
- /* Both operands are of type integer */
+ /*
+ * Convert the second operand if necessary. The first operand
+ * determines the type of the second operand, (See the Data Types
+ * section of the ACPI 3.0+ specification.) Both object types are
+ * guaranteed to be either Integer/String/Buffer by the operand
+ * resolution mechanism.
+ */
+ switch (ACPI_GET_OBJECT_TYPE (operand0)) {
+ case ACPI_TYPE_INTEGER:
+ status = acpi_ex_convert_to_integer (operand1, &local_operand1, opcode);
+ break;
- operand0 = obj_desc0->integer.value;
- operand1 = obj_desc1->integer.value;
+ case ACPI_TYPE_STRING:
+ status = acpi_ex_convert_to_string (operand1, &local_operand1,
+ ACPI_IMPLICIT_CONVERT_HEX, opcode);
+ break;
- switch (opcode) {
- case AML_LAND_OP: /* LAnd (Operand0, Operand1) */
+ case ACPI_TYPE_BUFFER:
+ status = acpi_ex_convert_to_buffer (operand1, &local_operand1, opcode);
+ break;
- if (operand0 && operand1) {
- return (TRUE);
- }
- break;
+ default:
+ status = AE_AML_INTERNAL;
+ break;
+ }
+
+ if (ACPI_FAILURE (status)) {
+ goto cleanup;
+ }
+ /*
+ * Two cases: 1) Both Integers, 2) Both Strings or Buffers
+ */
+ if (ACPI_GET_OBJECT_TYPE (operand0) == ACPI_TYPE_INTEGER) {
+ /*
+ * 1) Both operands are of type integer
+ * Note: local_operand1 may have changed above
+ */
+ integer0 = operand0->integer.value;
+ integer1 = local_operand1->integer.value;
+
+ switch (opcode) {
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
- if (operand0 == operand1) {
- return (TRUE);
+ if (integer0 == integer1) {
+ local_result = TRUE;
}
break;
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
- if (operand0 > operand1) {
- return (TRUE);
+ if (integer0 > integer1) {
+ local_result = TRUE;
}
break;
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
- if (operand0 < operand1) {
- return (TRUE);
- }
- break;
-
- case AML_LOR_OP: /* LOr (Operand0, Operand1) */
-
- if (operand0 || operand1) {
- return (TRUE);
+ if (integer0 < integer1) {
+ local_result = TRUE;
}
break;
default:
+ status = AE_AML_INTERNAL;
break;
}
}
else {
/*
- * Case for Buffer/String objects.
- * NOTE: takes advantage of common Buffer/String object fields
+ * 2) Both operands are Strings or both are Buffers
+ * Note: Code below takes advantage of common Buffer/String
+ * object fields. local_operand1 may have changed above
*/
- length0 = obj_desc0->buffer.length;
- ptr0 = obj_desc0->buffer.pointer;
+ length0 = operand0->buffer.length;
+ length1 = local_operand1->buffer.length;
- length1 = obj_desc1->buffer.length;
- ptr1 = obj_desc1->buffer.pointer;
+ /* Lexicographic compare: compare the data bytes */
+
+ compare = ACPI_STRNCMP ((const char * ) operand0->buffer.pointer,
+ (const char * ) local_operand1->buffer.pointer,
+ (length0 > length1) ? length1 : length0);
switch (opcode) {
case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */
/* Length and all bytes must be equal */
- if (length0 != length1) {
- return (FALSE);
- }
+ if ((length0 == length1) &&
+ (compare == 0)) {
+ /* Length and all bytes match ==> TRUE */
- for (i = 0; i < length0; i++) {
- if (ptr0[i] != ptr1[i]) {
- return (FALSE);
- }
+ local_result = TRUE;
}
- return (TRUE);
+ break;
case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */
- /* Lexicographic compare: Scan the 1-to-1 data */
-
- for (i = 0; (i < length0) && (i < length1); i++) {
- if (ptr0[i] > ptr1[i]) {
- return (TRUE);
- }
+ if (compare > 0) {
+ local_result = TRUE;
+ goto cleanup; /* TRUE */
+ }
+ if (compare < 0) {
+ goto cleanup; /* FALSE */
}
- /* Bytes match, now check lengths */
+ /* Bytes match (to shortest length), compare lengths */
if (length0 > length1) {
- return (TRUE);
+ local_result = TRUE;
}
-
- /* Length0 <= Length1 */
-
- return (FALSE);
+ break;
case AML_LLESS_OP: /* LLess (Operand0, Operand1) */
- /* Lexicographic compare: Scan the 1-to-1 data */
-
- for (i = 0; (i < length0) && (i < length1); i++) {
- if (ptr0[i] < ptr1[i]) {
- return (TRUE);
- }
+ if (compare > 0) {
+ goto cleanup; /* FALSE */
+ }
+ if (compare < 0) {
+ local_result = TRUE;
+ goto cleanup; /* TRUE */
}
- /* Bytes match, now check lengths */
+ /* Bytes match (to shortest length), compare lengths */
if (length0 < length1) {
- return (TRUE);
+ local_result = TRUE;
}
-
- /* Length0 >= Length1 */
-
- return (FALSE);
+ break;
default:
+ status = AE_AML_INTERNAL;
break;
}
}
- return (FALSE);
+cleanup:
+
+ /* New object was created if implicit conversion performed - delete */
+
+ if (local_operand1 != operand1) {
+ acpi_ut_remove_reference (local_operand1);
+ }
+
+ /* Return the logical result and status */
+
+ *logical_result = local_result;
+ return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c
index 8ba1e646974d..33adceb1bf5d 100644
--- a/drivers/acpi/executer/exoparg1.c
+++ b/drivers/acpi/executer/exoparg1.c
@@ -344,7 +344,7 @@ acpi_ex_opcode_1A_1T_1R (
/* Insert the BCD digit that resides in the remainder from above */
- return_desc->integer.value |= (((acpi_integer) temp32) << (i * 4));
+ return_desc->integer.value |= (((acpi_integer) temp32) << ACPI_MUL_4 (i));
}
/* Overflow if there is any data left in Digit */
@@ -429,31 +429,36 @@ acpi_ex_opcode_1A_1T_1R (
*/
case AML_COPY_OP: /* Copy (Source, Target) */
- status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc, walk_state);
+ status = acpi_ut_copy_iobject_to_iobject (operand[0], &return_desc,
+ walk_state);
break;
case AML_TO_DECSTRING_OP: /* to_decimal_string (Data, Result) */
- status = acpi_ex_convert_to_string (operand[0], &return_desc, 10, ACPI_UINT32_MAX, walk_state);
+ status = acpi_ex_convert_to_string (operand[0], &return_desc,
+ ACPI_EXPLICIT_CONVERT_DECIMAL, walk_state->opcode);
break;
case AML_TO_HEXSTRING_OP: /* to_hex_string (Data, Result) */
- status = acpi_ex_convert_to_string (operand[0], &return_desc, 16, ACPI_UINT32_MAX, walk_state);
+ status = acpi_ex_convert_to_string (operand[0], &return_desc,
+ ACPI_EXPLICIT_CONVERT_HEX, walk_state->opcode);
break;
case AML_TO_BUFFER_OP: /* to_buffer (Data, Result) */
- status = acpi_ex_convert_to_buffer (operand[0], &return_desc, walk_state);
+ status = acpi_ex_convert_to_buffer (operand[0], &return_desc,
+ walk_state->opcode);
break;
case AML_TO_INTEGER_OP: /* to_integer (Data, Result) */
- status = acpi_ex_convert_to_integer (operand[0], &return_desc, walk_state);
+ status = acpi_ex_convert_to_integer (operand[0], &return_desc,
+ walk_state->opcode);
break;
@@ -463,8 +468,9 @@ acpi_ex_opcode_1A_1T_1R (
/*
* These are two obsolete opcodes
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s is obsolete and not implemented\n",
- acpi_ps_get_opcode_name (walk_state->opcode)));
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "%s is obsolete and not implemented\n",
+ acpi_ps_get_opcode_name (walk_state->opcode)));
status = AE_SUPPORT;
goto cleanup;
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c
index 0b6f86a91572..2660afa7b4f8 100644
--- a/drivers/acpi/executer/exoparg2.c
+++ b/drivers/acpi/executer/exoparg2.c
@@ -292,7 +292,6 @@ acpi_ex_opcode_2A_1T_1R (
{
union acpi_operand_object **operand = &walk_state->operands[0];
union acpi_operand_object *return_desc = NULL;
- union acpi_operand_object *temp_desc = NULL;
u32 index;
acpi_status status = AE_OK;
acpi_size length;
@@ -331,52 +330,15 @@ acpi_ex_opcode_2A_1T_1R (
/* return_desc will contain the remainder */
- status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value,
+ status = acpi_ut_divide (&operand[0]->integer.value,
+ &operand[1]->integer.value,
NULL, &return_desc->integer.value);
break;
case AML_CONCAT_OP: /* Concatenate (Data1, Data2, Result) */
- /*
- * Convert the second operand if necessary. The first operand
- * determines the type of the second operand, (See the Data Types
- * section of the ACPI specification.) Both object types are
- * guaranteed to be either Integer/String/Buffer by the operand
- * resolution mechanism above.
- */
- switch (ACPI_GET_OBJECT_TYPE (operand[0])) {
- case ACPI_TYPE_INTEGER:
- status = acpi_ex_convert_to_integer (operand[1], &temp_desc, walk_state);
- break;
-
- case ACPI_TYPE_STRING:
- status = acpi_ex_convert_to_string (operand[1], &temp_desc, 16, ACPI_UINT32_MAX, walk_state);
- break;
-
- case ACPI_TYPE_BUFFER:
- status = acpi_ex_convert_to_buffer (operand[1], &temp_desc, walk_state);
- break;
-
- default:
- ACPI_REPORT_ERROR (("Concat - invalid obj type: %X\n",
- ACPI_GET_OBJECT_TYPE (operand[0])));
- status = AE_AML_INTERNAL;
- }
-
- if (ACPI_FAILURE (status)) {
- goto cleanup;
- }
-
- /*
- * Both operands are now known to be the same object type
- * (Both are Integer, String, or Buffer), and we can now perform the
- * concatenation.
- */
- status = acpi_ex_do_concatenate (operand[0], temp_desc, &return_desc, walk_state);
- if (temp_desc != operand[1]) {
- acpi_ut_remove_reference (temp_desc);
- }
+ status = acpi_ex_do_concatenate (operand[0], operand[1], &return_desc, walk_state);
break;
@@ -407,35 +369,25 @@ acpi_ex_opcode_2A_1T_1R (
goto cleanup;
}
- /* Create the internal return object */
+ /* Allocate a new string (Length + 1 for null terminator) */
- return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+ return_desc = acpi_ut_create_string_object (length + 1);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
}
- /* Allocate a new string buffer (Length + 1 for null terminator) */
-
- return_desc->string.pointer = ACPI_MEM_CALLOCATE (length + 1);
- if (!return_desc->string.pointer) {
- status = AE_NO_MEMORY;
- goto cleanup;
- }
-
- /* Copy the raw buffer data with no transform */
-
- ACPI_MEMCPY (return_desc->string.pointer, operand[0]->buffer.pointer, length);
+ /* Copy the raw buffer data with no transform. NULL terminated already. */
- /* Set the string length */
-
- return_desc->string.length = (u32) length;
+ ACPI_MEMCPY (return_desc->string.pointer,
+ operand[0]->buffer.pointer, length);
break;
case AML_CONCAT_RES_OP: /* concatenate_res_template (Buffer, Buffer, Result) (ACPI 2.0) */
- status = acpi_ex_concat_template (operand[0], operand[1], &return_desc, walk_state);
+ status = acpi_ex_concat_template (operand[0], operand[1],
+ &return_desc, walk_state);
break;
@@ -458,7 +410,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Package */
if (index >= operand[0]->package.count) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond package end (%X)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Index value (%X) beyond package end (%X)\n",
index, operand[0]->package.count));
status = AE_AML_PACKAGE_LIMIT;
goto cleanup;
@@ -472,7 +425,8 @@ acpi_ex_opcode_2A_1T_1R (
/* Object to be indexed is a Buffer */
if (index >= operand[0]->buffer.length) {
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Index value (%X) beyond end of buffer (%X)\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Index value (%X) beyond end of buffer (%X)\n",
index, operand[0]->buffer.length));
status = AE_AML_BUFFER_LIMIT;
goto cleanup;
@@ -572,18 +526,15 @@ acpi_ex_opcode_2A_0T_1R (
/*
* Execute the Opcode
*/
- if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
- /* Both operands must be of the same type */
-
- if (ACPI_GET_OBJECT_TYPE (operand[0]) !=
- ACPI_GET_OBJECT_TYPE (operand[1])) {
- status = AE_AML_OPERAND_TYPE;
- goto cleanup;
- }
-
- logical_result = acpi_ex_do_logical_op (walk_state->opcode,
- operand[0],
- operand[1]);
+ if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) /* logical_op (Operand0, Operand1) */ {
+ status = acpi_ex_do_logical_numeric_op (walk_state->opcode,
+ operand[0]->integer.value, operand[1]->integer.value,
+ &logical_result);
+ goto store_logical_result;
+ }
+ else if (walk_state->op_info->flags & AML_LOGICAL) /* logical_op (Operand0, Operand1) */ {
+ status = acpi_ex_do_logical_op (walk_state->opcode, operand[0],
+ operand[1], &logical_result);
goto store_logical_result;
}
diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c
index d410bd7f1fe3..3f6e6f9f9745 100644
--- a/drivers/acpi/executer/exresop.c
+++ b/drivers/acpi/executer/exresop.c
@@ -398,7 +398,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or BUFFER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_integer (obj_desc, stack_ptr, walk_state);
+ status = acpi_ex_convert_to_integer (obj_desc, stack_ptr,
+ walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -420,7 +421,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a STRING or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state);
+ status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr,
+ walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -442,7 +444,8 @@ acpi_ex_resolve_operands (
* But we can implicitly convert from a BUFFER or INTEGER
* Aka - "Implicit Source Operand Conversion"
*/
- status = acpi_ex_convert_to_string (obj_desc, stack_ptr, 16, ACPI_UINT32_MAX, walk_state);
+ status = acpi_ex_convert_to_string (obj_desc, stack_ptr,
+ ACPI_IMPLICIT_CONVERT_HEX, walk_state->opcode);
if (ACPI_FAILURE (status)) {
if (status == AE_TYPE) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
@@ -494,7 +497,8 @@ acpi_ex_resolve_operands (
/* Highest priority conversion is to type Buffer */
- status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr, walk_state);
+ status = acpi_ex_convert_to_buffer (obj_desc, stack_ptr,
+ walk_state->opcode);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c
index e0b9663aef80..3f633d97e051 100644
--- a/drivers/acpi/namespace/nsnames.c
+++ b/drivers/acpi/namespace/nsnames.c
@@ -202,7 +202,11 @@ acpi_ns_get_pathname_length (
next_node = acpi_ns_get_parent_node (next_node);
}
- return (size + 1);
+ if (!size) {
+ size = 1; /* Root node case */
+ }
+
+ return (size + 1); /* +1 for null string terminator */
}
diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c
index 30620375bd88..832193b93a78 100644
--- a/drivers/acpi/parser/psopcode.c
+++ b/drivers/acpi/parser/psopcode.c
@@ -527,8 +527,8 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] =
/* 35 */ ACPI_OP ("CreateByteField", ARGP_CREATE_BYTE_FIELD_OP, ARGI_CREATE_BYTE_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
/* 36 */ ACPI_OP ("CreateBitField", ARGP_CREATE_BIT_FIELD_OP, ARGI_CREATE_BIT_FIELD_OP, ACPI_TYPE_BUFFER_FIELD, AML_CLASS_CREATE, AML_TYPE_CREATE_FIELD, AML_HAS_ARGS | AML_NSOBJECT | AML_NSNODE | AML_DEFER | AML_CREATE),
/* 37 */ ACPI_OP ("ObjectType", ARGP_TYPE_OP, ARGI_TYPE_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R),
-/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
-/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
+/* 38 */ ACPI_OP ("LAnd", ARGP_LAND_OP, ARGI_LAND_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
+/* 39 */ ACPI_OP ("LOr", ARGP_LOR_OP, ARGI_LOR_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL_NUMERIC | AML_CONSTANT),
/* 3A */ ACPI_OP ("LNot", ARGP_LNOT_OP, ARGI_LNOT_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_1A_0T_1R, AML_FLAGS_EXEC_1A_0T_1R | AML_CONSTANT),
/* 3B */ ACPI_OP ("LEqual", ARGP_LEQUAL_OP, ARGI_LEQUAL_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
/* 3C */ ACPI_OP ("LGreater", ARGP_LGREATER_OP, ARGI_LGREATER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_2A_0T_1R, AML_FLAGS_EXEC_2A_0T_1R | AML_LOGICAL | AML_CONSTANT),
diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c
index 58ec6733efaa..7fb51f4e9dcb 100644
--- a/drivers/acpi/utilities/utalloc.c
+++ b/drivers/acpi/utilities/utalloc.c
@@ -472,7 +472,7 @@ acpi_ut_allocate_and_track (
acpi_status status;
- allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_block), component,
+ allocation = acpi_ut_allocate (size + sizeof (struct acpi_debug_mem_header), component,
module, line);
if (!allocation) {
return (NULL);
@@ -518,7 +518,7 @@ acpi_ut_callocate_and_track (
acpi_status status;
- allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_block), component,
+ allocation = acpi_ut_callocate (size + sizeof (struct acpi_debug_mem_header), component,
module, line);
if (!allocation) {
/* Report allocation error */
@@ -712,6 +712,7 @@ acpi_ut_track_allocation (
allocation->line = line;
ACPI_STRNCPY (allocation->module, module, ACPI_MAX_MODULE_NAME);
+ allocation->module[ACPI_MAX_MODULE_NAME-1] = 0;
/* Insert at list head */
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index b3b8757c1a20..72b0347d2564 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -155,9 +155,8 @@ acpi_ut_create_buffer_object (
ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size);
- /*
- * Create a new Buffer object
- */
+ /* Create a new Buffer object */
+
buffer_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
if (!buffer_desc) {
return_PTR (NULL);
@@ -191,6 +190,63 @@ acpi_ut_create_buffer_object (
/*******************************************************************************
*
+ * FUNCTION: acpi_ut_create_string_object
+ *
+ * PARAMETERS: string_size - Size of string to be created, plus one
+ * for the NULL terminater. Actual sting
+ * length will be this size minus one.
+ *
+ * RETURN: Pointer to a new String object
+ *
+ * DESCRIPTION: Create a fully initialized string object
+ *
+ ******************************************************************************/
+
+union acpi_operand_object *
+acpi_ut_create_string_object (
+ acpi_size string_size)
+{
+ union acpi_operand_object *string_desc;
+ char *string = NULL;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("ut_create_string_object", string_size);
+
+
+ /* Create a new String object */
+
+ string_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING);
+ if (!string_desc) {
+ return_PTR (NULL);
+ }
+
+ /* Create an actual string only if size > 0 */
+
+ if (string_size > 0) {
+ /* Allocate the actual string */
+
+ string = ACPI_MEM_CALLOCATE (string_size);
+ if (!string) {
+ ACPI_REPORT_ERROR (("create_string: could not allocate size %X\n",
+ (u32) string_size));
+ acpi_ut_remove_reference (string_desc);
+ return_PTR (NULL);
+ }
+ }
+
+ /* Complete string object initialization */
+
+ string_desc->string.pointer = string;
+ string_desc->string.length = (u32) string_size - 1;
+
+ /* Return the new string descriptor */
+
+ return_PTR (string_desc);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ut_valid_internal_object
*
* PARAMETERS: Object - Object to be validated
diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h
index e4a0f1e6f814..5911d1b3c589 100644
--- a/include/acpi/acconfig.h
+++ b/include/acpi/acconfig.h
@@ -64,7 +64,7 @@
/* Version string */
-#define ACPI_CA_VERSION 0x20040816
+#define ACPI_CA_VERSION 0x20040827
/*
* 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 a43e91fb972c..f87445f46b54 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -83,21 +83,27 @@ acpi_status
acpi_ex_convert_to_integer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state);
+ u16 opcode);
acpi_status
acpi_ex_convert_to_buffer (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- struct acpi_walk_state *walk_state);
+ u16 opcode);
acpi_status
acpi_ex_convert_to_string (
union acpi_operand_object *obj_desc,
union acpi_operand_object **result_desc,
- u32 base,
- u32 max_length,
- struct acpi_walk_state *walk_state);
+ u32 type,
+ u16 opcode);
+
+/* Types for String conversion */
+
+#define ACPI_EXPLICIT_BYTE_COPY 0x00000000
+#define ACPI_EXPLICIT_CONVERT_HEX 0x00000001
+#define ACPI_IMPLICIT_CONVERT_HEX 0x00000002
+#define ACPI_EXPLICIT_CONVERT_DECIMAL 0x00000003
acpi_status
acpi_ex_convert_to_target_type (
@@ -109,7 +115,7 @@ acpi_ex_convert_to_target_type (
u32
acpi_ex_convert_to_ascii (
acpi_integer integer,
- u32 base,
+ u16 base,
u8 *string,
u8 max_length);
@@ -243,11 +249,19 @@ acpi_ex_do_concatenate (
union acpi_operand_object **actual_return_desc,
struct acpi_walk_state *walk_state);
-u8
+acpi_status
+acpi_ex_do_logical_numeric_op (
+ u16 opcode,
+ acpi_integer integer0,
+ acpi_integer integer1,
+ u8 *logical_result);
+
+acpi_status
acpi_ex_do_logical_op (
u16 opcode,
- union acpi_operand_object *obj_desc,
- union acpi_operand_object *obj_desc2);
+ union acpi_operand_object *operand0,
+ union acpi_operand_object *operand1,
+ u8 *logical_result);
acpi_integer
acpi_ex_do_math_op (
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 0d479722f4aa..09d6a5af268c 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -135,7 +135,10 @@ struct acpi_object_integer
acpi_integer value;
};
-
+/*
+ * Note: The String and Buffer object must be identical through the Pointer
+ * element. There is code that depends on this.
+ */
struct acpi_object_string /* Null terminated, ASCII characters only */
{
ACPI_OBJECT_COMMON_HEADER
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 8bee457d81d6..c5bd3036c57a 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -303,7 +303,7 @@ struct uint32_struct
typedef u32 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT32_MAX
#define ACPI_INTEGER_BIT_SIZE 32
-#define ACPI_MAX_DECIMAL_DIGITS 10
+#define ACPI_MAX_DECIMAL_DIGITS 10 /* 2^32 = 4,294,967,296 */
#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 32-bit divide */
@@ -315,13 +315,18 @@ typedef u32 acpi_integer;
typedef u64 acpi_integer;
#define ACPI_INTEGER_MAX ACPI_UINT64_MAX
#define ACPI_INTEGER_BIT_SIZE 64
-#define ACPI_MAX_DECIMAL_DIGITS 19
+#define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */
+
#if ACPI_MACHINE_WIDTH == 64
#define ACPI_USE_NATIVE_DIVIDE /* Use compiler native 64-bit divide */
#endif
#endif
+#define ACPI_MAX64_DECIMAL_DIGITS 20
+#define ACPI_MAX32_DECIMAL_DIGITS 10
+#define ACPI_MAX16_DECIMAL_DIGITS 5
+#define ACPI_MAX8_DECIMAL_DIGITS 3
/*
* Constants with special meanings
diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h
index d786ae5ec820..ab3784a0cf58 100644
--- a/include/acpi/acutils.h
+++ b/include/acpi/acutils.h
@@ -577,6 +577,10 @@ union acpi_operand_object *
acpi_ut_create_buffer_object (
acpi_size buffer_size);
+union acpi_operand_object *
+acpi_ut_create_string_object (
+ acpi_size string_size);
+
/*
* ut_ref_cnt - Object reference count management
diff --git a/include/acpi/amlcode.h b/include/acpi/amlcode.h
index 0344b94c863d..1d06e16648cc 100644
--- a/include/acpi/amlcode.h
+++ b/include/acpi/amlcode.h
@@ -305,19 +305,20 @@
/* Opcode flags */
-#define AML_HAS_ARGS 0x0800
-#define AML_HAS_TARGET 0x0400
-#define AML_HAS_RETVAL 0x0200
-#define AML_NSOBJECT 0x0100
-#define AML_NSOPCODE 0x0080
-#define AML_NSNODE 0x0040
-#define AML_NAMED 0x0020
-#define AML_DEFER 0x0010
-#define AML_FIELD 0x0008
-#define AML_CREATE 0x0004
-#define AML_MATH 0x0002
#define AML_LOGICAL 0x0001
-#define AML_CONSTANT 0x1000
+#define AML_LOGICAL_NUMERIC 0x0002
+#define AML_MATH 0x0004
+#define AML_CREATE 0x0008
+#define AML_FIELD 0x0010
+#define AML_DEFER 0x0020
+#define AML_NAMED 0x0040
+#define AML_NSNODE 0x0080
+#define AML_NSOPCODE 0x0100
+#define AML_NSOBJECT 0x0200
+#define AML_HAS_RETVAL 0x0400
+#define AML_HAS_TARGET 0x0800
+#define AML_HAS_ARGS 0x1000
+#define AML_CONSTANT 0x2000
/* Convenient flag groupings */
diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h
index b28b6905b71e..89a52ddae530 100644
--- a/include/acpi/amlresrc.h
+++ b/include/acpi/amlresrc.h
@@ -99,7 +99,7 @@ struct asl_resource_node
/*
* Resource descriptors defined in the ACPI specification.
*
- * Alignment must be BYTE because these descriptors
+ * Packing/alignment must be BYTE because these descriptors
* are used to overlay the AML byte stream.
*/
#pragma pack(1)
@@ -297,7 +297,7 @@ struct asl_general_register_desc
#pragma pack()
-/* Union of all resource descriptors, sow we can allocate the worst case */
+/* Union of all resource descriptors, so we can allocate the worst case */
union asl_resource_desc
{