X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Fexecuter%2Fexoparg2.c;h=23964e70a89bf51bc1a3401324b357d751c61129;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=0b6f86a91572d635c4fb672511bb457c8e87bc4b;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 0b6f86a91..23964e70a 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2004, R. Byron Moore + * Copyright (C) 2000 - 2005, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -199,7 +199,8 @@ acpi_ex_opcode_2A_2T_1R ( acpi_status status; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_2T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* @@ -222,8 +223,10 @@ acpi_ex_opcode_2A_2T_1R ( /* Quotient to return_desc1, remainder to return_desc2 */ - status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, - &return_desc1->integer.value, &return_desc2->integer.value); + status = acpi_ut_divide (operand[0]->integer.value, + operand[1]->integer.value, + &return_desc1->integer.value, + &return_desc2->integer.value); if (ACPI_FAILURE (status)) { goto cleanup; } @@ -292,13 +295,13 @@ 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; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_1T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* @@ -331,52 +334,17 @@ acpi_ex_opcode_2A_1T_1R ( /* return_desc will contain the remainder */ - status = acpi_ut_divide (&operand[0]->integer.value, &operand[1]->integer.value, - NULL, &return_desc->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; @@ -387,55 +355,45 @@ acpi_ex_opcode_2A_1T_1R ( * been converted.) Copy the raw buffer data to a new object of type String. */ - /* Get the length of the new string */ - + /* + * Get the length of the new string. It is the smallest of: + * 1) Length of the input buffer + * 2) Max length as specified in the to_string operator + * 3) Length of input buffer up to a zero byte (null terminator) + * + * NOTE: A length of zero is ok, and will create a zero-length, null + * terminated string. + */ length = 0; - if (operand[1]->integer.value == 0) { - /* Handle optional length value */ - - operand[1]->integer.value = ACPI_INTEGER_MAX; - } - while ((length < operand[0]->buffer.length) && (length < operand[1]->integer.value) && (operand[0]->buffer.pointer[length])) { length++; + if (length > ACPI_MAX_STRING_CONVERSION) { + status = AE_AML_STRING_LIMIT; + goto cleanup; + } } - if (length > ACPI_MAX_STRING_CONVERSION) { - status = AE_AML_STRING_LIMIT; - goto cleanup; - } - - /* Create the internal return object */ + /* Allocate a new string object */ - return_desc = acpi_ut_create_internal_object (ACPI_TYPE_STRING); + return_desc = acpi_ut_create_string_object (length); 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; @@ -452,13 +410,14 @@ acpi_ex_opcode_2A_1T_1R ( index = (u32) operand[1]->integer.value; /* - * At this point, the Source operand is either a Package or a Buffer + * At this point, the Source operand is a Package, Buffer, or String */ if (ACPI_GET_OBJECT_TYPE (operand[0]) == ACPI_TYPE_PACKAGE) { /* 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; @@ -469,10 +428,11 @@ acpi_ex_opcode_2A_1T_1R ( return_desc->reference.where = &operand[0]->package.elements [index]; } else { - /* Object to be indexed is a Buffer */ + /* Object to be indexed is a Buffer/String */ 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; @@ -558,7 +518,8 @@ acpi_ex_opcode_2A_0T_1R ( u8 logical_result = FALSE; - ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R", acpi_ps_get_opcode_name (walk_state->opcode)); + ACPI_FUNCTION_TRACE_STR ("ex_opcode_2A_0T_1R", + acpi_ps_get_opcode_name (walk_state->opcode)); /* Create the internal return object */ @@ -572,18 +533,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; }