diff options
| author | Len Brown <len.brown@intel.com> | 2004-10-22 07:33:45 -0400 |
|---|---|---|
| committer | Len Brown <lenb@dhcppc3.> | 2004-10-22 07:33:45 -0400 |
| commit | 8d7b2d682a9740e2edfb4ab6ceb01a7551797c68 (patch) | |
| tree | b557c7817415600f468cb0242a46ed7ec4de91e7 /drivers | |
| parent | 66f574304c9093b48c44206038bf0cac50c5dff1 (diff) | |
[ACPI] ACPICA 20040827 update from Bob Moore
Signed-off-by: Len Brown <len.brown@intel.com>
Implemented support for implicit object conversion in
the non-numeric logical operators (LEqual, LGreater,
LGreaterEqual, LLess, LLessEqual, and LNotEqual.) Any
combination of Integers/Strings/Buffers may now be used;
the second operand is implicitly converted on the fly to
match the type of the first operand. For example:
LEqual (Source1, Source2)
Source1 and Source2 must each evaluate to an integer, a
string, or a buffer. The data type of Source1 dictates the
required type of Source2. Source2 is implicitly converted
if necessary to match the type of Source1.
Updated and corrected the behavior of the string
conversion support. The rules concerning conversion of
buffers to strings (according to the ACPI specification)
are as follows:
ToDecimalString - explicit byte-wise conversion of buffer
to string of decimal values (0-255) separated by commas.
ToHexString - explicit byte-wise conversion of buffer to
string of hex values (0-FF) separated by commas.
ToString - explicit byte-wise conversion of buffer to
string. Byte-by-byte copy with no transform except NULL
terminated. Any other implicit buffer-to-string conversion
byte-wise conversion of buffer to string of hex values
(0-FF) separated by spaces.
Fixed a problem in acpi_ns_get_pathname_length where the
returned length was one byte too short in the case of a
node in the root scope. This could cause a fault during
debug output.
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/acpi/dispatcher/dswexec.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/executer/exconvrt.c | 320 | ||||
| -rw-r--r-- | drivers/acpi/executer/exfldio.c | 2 | ||||
| -rw-r--r-- | drivers/acpi/executer/exmisc.c | 464 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg1.c | 22 | ||||
| -rw-r--r-- | drivers/acpi/executer/exoparg2.c | 95 | ||||
| -rw-r--r-- | drivers/acpi/executer/exresop.c | 12 | ||||
| -rw-r--r-- | drivers/acpi/namespace/nsnames.c | 6 | ||||
| -rw-r--r-- | drivers/acpi/parser/psopcode.c | 4 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utalloc.c | 5 | ||||
| -rw-r--r-- | drivers/acpi/utilities/utobject.c | 62 |
11 files changed, 572 insertions, 423 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 |
