diff options
Diffstat (limited to 'drivers/acpi/executer/exmisc.c')
| -rw-r--r-- | drivers/acpi/executer/exmisc.c | 113 |
1 files changed, 63 insertions, 50 deletions
diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index a3f4d72bedc9..48c18d29222a 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | *****************************************************************************/ | 6 | *****************************************************************************/ |
| 7 | 7 | ||
| 8 | /* | 8 | /* |
| 9 | * Copyright (C) 2000 - 2005, R. Byron Moore | 9 | * Copyright (C) 2000 - 2006, R. Byron Moore |
| 10 | * All rights reserved. | 10 | * All rights reserved. |
| 11 | * | 11 | * |
| 12 | * Redistribution and use in source and binary forms, with or without | 12 | * Redistribution and use in source and binary forms, with or without |
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <acpi/acpi.h> | 45 | #include <acpi/acpi.h> |
| 46 | #include <acpi/acinterp.h> | 46 | #include <acpi/acinterp.h> |
| 47 | #include <acpi/amlcode.h> | 47 | #include <acpi/amlcode.h> |
| 48 | #include <acpi/amlresrc.h> | ||
| 48 | 49 | ||
| 49 | #define _COMPONENT ACPI_EXECUTER | 50 | #define _COMPONENT ACPI_EXECUTER |
| 50 | ACPI_MODULE_NAME("exmisc") | 51 | ACPI_MODULE_NAME("exmisc") |
| @@ -97,7 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
| 97 | 98 | ||
| 98 | default: | 99 | default: |
| 99 | 100 | ||
| 100 | ACPI_REPORT_ERROR(("Unknown Reference opcode in get_reference %X\n", obj_desc->reference.opcode)); | 101 | ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", |
| 102 | obj_desc->reference.opcode)); | ||
| 101 | return_ACPI_STATUS(AE_AML_INTERNAL); | 103 | return_ACPI_STATUS(AE_AML_INTERNAL); |
| 102 | } | 104 | } |
| 103 | break; | 105 | break; |
| @@ -112,7 +114,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, | |||
| 112 | 114 | ||
| 113 | default: | 115 | default: |
| 114 | 116 | ||
| 115 | ACPI_REPORT_ERROR(("Invalid descriptor type in get_reference: %X\n", ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); | 117 | ACPI_ERROR((AE_INFO, "Invalid descriptor type %X", |
| 118 | ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); | ||
| 116 | return_ACPI_STATUS(AE_TYPE); | 119 | return_ACPI_STATUS(AE_TYPE); |
| 117 | } | 120 | } |
| 118 | 121 | ||
| @@ -157,48 +160,65 @@ acpi_ex_concat_template(union acpi_operand_object *operand0, | |||
| 157 | union acpi_operand_object **actual_return_desc, | 160 | union acpi_operand_object **actual_return_desc, |
| 158 | struct acpi_walk_state *walk_state) | 161 | struct acpi_walk_state *walk_state) |
| 159 | { | 162 | { |
| 163 | acpi_status status; | ||
| 160 | union acpi_operand_object *return_desc; | 164 | union acpi_operand_object *return_desc; |
| 161 | u8 *new_buf; | 165 | u8 *new_buf; |
| 162 | u8 *end_tag1; | 166 | u8 *end_tag; |
| 163 | u8 *end_tag2; | 167 | acpi_size length0; |
| 164 | acpi_size length1; | 168 | acpi_size length1; |
| 165 | acpi_size length2; | 169 | acpi_size new_length; |
| 166 | 170 | ||
| 167 | ACPI_FUNCTION_TRACE("ex_concat_template"); | 171 | ACPI_FUNCTION_TRACE("ex_concat_template"); |
| 168 | 172 | ||
| 169 | /* Find the end_tags in each resource template */ | 173 | /* |
| 174 | * Find the end_tag descriptor in each resource template. | ||
| 175 | * Note1: returned pointers point TO the end_tag, not past it. | ||
| 176 | * Note2: zero-length buffers are allowed; treated like one end_tag | ||
| 177 | */ | ||
| 178 | |||
| 179 | /* Get the length of the first resource template */ | ||
| 170 | 180 | ||
| 171 | end_tag1 = acpi_ut_get_resource_end_tag(operand0); | 181 | status = acpi_ut_get_resource_end_tag(operand0, &end_tag); |
| 172 | end_tag2 = acpi_ut_get_resource_end_tag(operand1); | 182 | if (ACPI_FAILURE(status)) { |
| 173 | if (!end_tag1 || !end_tag2) { | 183 | return_ACPI_STATUS(status); |
| 174 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | ||
| 175 | } | 184 | } |
| 176 | 185 | ||
| 177 | /* Compute the length of each part */ | 186 | length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); |
| 187 | |||
| 188 | /* Get the length of the second resource template */ | ||
| 189 | |||
| 190 | status = acpi_ut_get_resource_end_tag(operand1, &end_tag); | ||
| 191 | if (ACPI_FAILURE(status)) { | ||
| 192 | return_ACPI_STATUS(status); | ||
| 193 | } | ||
| 178 | 194 | ||
| 179 | length1 = ACPI_PTR_DIFF(end_tag1, operand0->buffer.pointer); | 195 | length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer); |
| 180 | length2 = ACPI_PTR_DIFF(end_tag2, operand1->buffer.pointer) + 2; /* Size of END_TAG */ | ||
| 181 | 196 | ||
| 182 | /* Create a new buffer object for the result */ | 197 | /* Combine both lengths, minimum size will be 2 for end_tag */ |
| 183 | 198 | ||
| 184 | return_desc = acpi_ut_create_buffer_object(length1 + length2); | 199 | new_length = length0 + length1 + sizeof(struct aml_resource_end_tag); |
| 200 | |||
| 201 | /* Create a new buffer object for the result (with one end_tag) */ | ||
| 202 | |||
| 203 | return_desc = acpi_ut_create_buffer_object(new_length); | ||
| 185 | if (!return_desc) { | 204 | if (!return_desc) { |
| 186 | return_ACPI_STATUS(AE_NO_MEMORY); | 205 | return_ACPI_STATUS(AE_NO_MEMORY); |
| 187 | } | 206 | } |
| 188 | 207 | ||
| 189 | /* Copy the templates to the new descriptor */ | 208 | /* |
| 190 | 209 | * Copy the templates to the new buffer, 0 first, then 1 follows. One | |
| 210 | * end_tag descriptor is copied from Operand1. | ||
| 211 | */ | ||
| 191 | new_buf = return_desc->buffer.pointer; | 212 | new_buf = return_desc->buffer.pointer; |
| 192 | ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length1); | 213 | ACPI_MEMCPY(new_buf, operand0->buffer.pointer, length0); |
| 193 | ACPI_MEMCPY(new_buf + length1, operand1->buffer.pointer, length2); | 214 | ACPI_MEMCPY(new_buf + length0, operand1->buffer.pointer, length1); |
| 194 | 215 | ||
| 195 | /* Compute the new checksum */ | 216 | /* Insert end_tag and set the checksum to zero, means "ignore checksum" */ |
| 196 | 217 | ||
| 197 | new_buf[return_desc->buffer.length - 1] = | 218 | new_buf[new_length - 1] = 0; |
| 198 | acpi_ut_generate_checksum(return_desc->buffer.pointer, | 219 | new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; |
| 199 | (return_desc->buffer.length - 1)); | ||
| 200 | 220 | ||
| 201 | /* Return the completed template descriptor */ | 221 | /* Return the completed resource template */ |
| 202 | 222 | ||
| 203 | *actual_return_desc = return_desc; | 223 | *actual_return_desc = return_desc; |
| 204 | return_ACPI_STATUS(AE_OK); | 224 | return_ACPI_STATUS(AE_OK); |
| @@ -229,7 +249,6 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 229 | union acpi_operand_object *return_desc; | 249 | union acpi_operand_object *return_desc; |
| 230 | char *new_buf; | 250 | char *new_buf; |
| 231 | acpi_status status; | 251 | acpi_status status; |
| 232 | acpi_size new_length; | ||
| 233 | 252 | ||
| 234 | ACPI_FUNCTION_TRACE("ex_do_concatenate"); | 253 | ACPI_FUNCTION_TRACE("ex_do_concatenate"); |
| 235 | 254 | ||
| @@ -256,8 +275,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 256 | break; | 275 | break; |
| 257 | 276 | ||
| 258 | default: | 277 | default: |
| 259 | ACPI_REPORT_ERROR(("Concat - invalid obj type: %X\n", | 278 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", |
| 260 | ACPI_GET_OBJECT_TYPE(operand0))); | 279 | ACPI_GET_OBJECT_TYPE(operand0))); |
| 261 | status = AE_AML_INTERNAL; | 280 | status = AE_AML_INTERNAL; |
| 262 | } | 281 | } |
| 263 | 282 | ||
| @@ -296,8 +315,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 296 | 315 | ||
| 297 | /* Copy the first integer, LSB first */ | 316 | /* Copy the first integer, LSB first */ |
| 298 | 317 | ||
| 299 | ACPI_MEMCPY(new_buf, | 318 | ACPI_MEMCPY(new_buf, &operand0->integer.value, |
| 300 | &operand0->integer.value, | ||
| 301 | acpi_gbl_integer_byte_width); | 319 | acpi_gbl_integer_byte_width); |
| 302 | 320 | ||
| 303 | /* Copy the second integer (LSB first) after the first */ | 321 | /* Copy the second integer (LSB first) after the first */ |
| @@ -311,14 +329,11 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 311 | 329 | ||
| 312 | /* Result of two Strings is a String */ | 330 | /* Result of two Strings is a String */ |
| 313 | 331 | ||
| 314 | new_length = (acpi_size) operand0->string.length + | 332 | return_desc = acpi_ut_create_string_object((acpi_size) |
| 315 | (acpi_size) local_operand1->string.length; | 333 | (operand0->string. |
| 316 | if (new_length > ACPI_MAX_STRING_CONVERSION) { | 334 | length + |
| 317 | status = AE_AML_STRING_LIMIT; | 335 | local_operand1-> |
| 318 | goto cleanup; | 336 | string.length)); |
| 319 | } | ||
| 320 | |||
| 321 | return_desc = acpi_ut_create_string_object(new_length); | ||
| 322 | if (!return_desc) { | 337 | if (!return_desc) { |
| 323 | status = AE_NO_MEMORY; | 338 | status = AE_NO_MEMORY; |
| 324 | goto cleanup; | 339 | goto cleanup; |
| @@ -338,11 +353,10 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 338 | /* Result of two Buffers is a Buffer */ | 353 | /* Result of two Buffers is a Buffer */ |
| 339 | 354 | ||
| 340 | return_desc = acpi_ut_create_buffer_object((acpi_size) | 355 | return_desc = acpi_ut_create_buffer_object((acpi_size) |
| 341 | operand0->buffer. | 356 | (operand0->buffer. |
| 342 | length + | 357 | length + |
| 343 | (acpi_size) | 358 | local_operand1-> |
| 344 | local_operand1-> | 359 | buffer.length)); |
| 345 | buffer.length); | ||
| 346 | if (!return_desc) { | 360 | if (!return_desc) { |
| 347 | status = AE_NO_MEMORY; | 361 | status = AE_NO_MEMORY; |
| 348 | goto cleanup; | 362 | goto cleanup; |
| @@ -352,8 +366,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 352 | 366 | ||
| 353 | /* Concatenate the buffers */ | 367 | /* Concatenate the buffers */ |
| 354 | 368 | ||
| 355 | ACPI_MEMCPY(new_buf, | 369 | ACPI_MEMCPY(new_buf, operand0->buffer.pointer, |
| 356 | operand0->buffer.pointer, operand0->buffer.length); | 370 | operand0->buffer.length); |
| 357 | ACPI_MEMCPY(new_buf + operand0->buffer.length, | 371 | ACPI_MEMCPY(new_buf + operand0->buffer.length, |
| 358 | local_operand1->buffer.pointer, | 372 | local_operand1->buffer.pointer, |
| 359 | local_operand1->buffer.length); | 373 | local_operand1->buffer.length); |
| @@ -363,8 +377,8 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0, | |||
| 363 | 377 | ||
| 364 | /* Invalid object type, should not happen here */ | 378 | /* Invalid object type, should not happen here */ |
| 365 | 379 | ||
| 366 | ACPI_REPORT_ERROR(("Concatenate - Invalid object type: %X\n", | 380 | ACPI_ERROR((AE_INFO, "Invalid object type: %X", |
| 367 | ACPI_GET_OBJECT_TYPE(operand0))); | 381 | ACPI_GET_OBJECT_TYPE(operand0))); |
| 368 | status = AE_AML_INTERNAL; | 382 | status = AE_AML_INTERNAL; |
| 369 | goto cleanup; | 383 | goto cleanup; |
| 370 | } | 384 | } |
| @@ -625,9 +639,8 @@ acpi_ex_do_logical_op(u16 opcode, | |||
| 625 | 639 | ||
| 626 | /* Lexicographic compare: compare the data bytes */ | 640 | /* Lexicographic compare: compare the data bytes */ |
| 627 | 641 | ||
| 628 | compare = ACPI_MEMCMP((const char *)operand0->buffer.pointer, | 642 | compare = ACPI_MEMCMP(operand0->buffer.pointer, |
| 629 | (const char *)local_operand1->buffer. | 643 | local_operand1->buffer.pointer, |
| 630 | pointer, | ||
| 631 | (length0 > length1) ? length1 : length0); | 644 | (length0 > length1) ? length1 : length0); |
| 632 | 645 | ||
| 633 | switch (opcode) { | 646 | switch (opcode) { |
