diff options
Diffstat (limited to 'drivers/acpi/executer/exoparg2.c')
-rw-r--r-- | drivers/acpi/executer/exoparg2.c | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index e263a5ddd405..7d2cbc113160 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c | |||
@@ -92,7 +92,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) | |||
92 | u32 value; | 92 | u32 value; |
93 | acpi_status status = AE_OK; | 93 | acpi_status status = AE_OK; |
94 | 94 | ||
95 | ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_0R", | 95 | ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_0R, |
96 | acpi_ps_get_opcode_name(walk_state->opcode)); | 96 | acpi_ps_get_opcode_name(walk_state->opcode)); |
97 | 97 | ||
98 | /* Examine the opcode */ | 98 | /* Examine the opcode */ |
@@ -121,7 +121,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) | |||
121 | #ifdef ACPI_GPE_NOTIFY_CHECK | 121 | #ifdef ACPI_GPE_NOTIFY_CHECK |
122 | /* | 122 | /* |
123 | * GPE method wake/notify check. Here, we want to ensure that we | 123 | * GPE method wake/notify check. Here, we want to ensure that we |
124 | * don't receive any "device_wake" Notifies from a GPE _Lxx or _Exx | 124 | * don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx |
125 | * GPE method during system runtime. If we do, the GPE is marked | 125 | * GPE method during system runtime. If we do, the GPE is marked |
126 | * as "wake-only" and disabled. | 126 | * as "wake-only" and disabled. |
127 | * | 127 | * |
@@ -138,6 +138,7 @@ acpi_status acpi_ex_opcode_2A_0T_0R(struct acpi_walk_state *walk_state) | |||
138 | acpi_ev_check_for_wake_only_gpe(walk_state-> | 138 | acpi_ev_check_for_wake_only_gpe(walk_state-> |
139 | gpe_event_info); | 139 | gpe_event_info); |
140 | if (ACPI_FAILURE(status)) { | 140 | if (ACPI_FAILURE(status)) { |
141 | |||
141 | /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ | 142 | /* AE_WAKE_ONLY_GPE only error, means ignore this notify */ |
142 | 143 | ||
143 | return_ACPI_STATUS(AE_OK) | 144 | return_ACPI_STATUS(AE_OK) |
@@ -185,7 +186,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) | |||
185 | union acpi_operand_object *return_desc2 = NULL; | 186 | union acpi_operand_object *return_desc2 = NULL; |
186 | acpi_status status; | 187 | acpi_status status; |
187 | 188 | ||
188 | ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_2T_1R", | 189 | ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_2T_1R, |
189 | acpi_ps_get_opcode_name(walk_state->opcode)); | 190 | acpi_ps_get_opcode_name(walk_state->opcode)); |
190 | 191 | ||
191 | /* Execute the opcode */ | 192 | /* Execute the opcode */ |
@@ -252,6 +253,7 @@ acpi_status acpi_ex_opcode_2A_2T_1R(struct acpi_walk_state *walk_state) | |||
252 | acpi_ut_remove_reference(return_desc2); | 253 | acpi_ut_remove_reference(return_desc2); |
253 | 254 | ||
254 | if (ACPI_FAILURE(status)) { | 255 | if (ACPI_FAILURE(status)) { |
256 | |||
255 | /* Delete the return object */ | 257 | /* Delete the return object */ |
256 | 258 | ||
257 | acpi_ut_remove_reference(return_desc1); | 259 | acpi_ut_remove_reference(return_desc1); |
@@ -281,12 +283,13 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
281 | acpi_status status = AE_OK; | 283 | acpi_status status = AE_OK; |
282 | acpi_size length; | 284 | acpi_size length; |
283 | 285 | ||
284 | ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_1T_1R", | 286 | ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_1T_1R, |
285 | acpi_ps_get_opcode_name(walk_state->opcode)); | 287 | acpi_ps_get_opcode_name(walk_state->opcode)); |
286 | 288 | ||
287 | /* Execute the opcode */ | 289 | /* Execute the opcode */ |
288 | 290 | ||
289 | if (walk_state->op_info->flags & AML_MATH) { | 291 | if (walk_state->op_info->flags & AML_MATH) { |
292 | |||
290 | /* All simple math opcodes (add, etc.) */ | 293 | /* All simple math opcodes (add, etc.) */ |
291 | 294 | ||
292 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); | 295 | return_desc = acpi_ut_create_internal_object(ACPI_TYPE_INTEGER); |
@@ -383,54 +386,70 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
383 | goto cleanup; | 386 | goto cleanup; |
384 | } | 387 | } |
385 | 388 | ||
389 | /* Initialize the Index reference object */ | ||
390 | |||
386 | index = operand[1]->integer.value; | 391 | index = operand[1]->integer.value; |
392 | return_desc->reference.offset = (u32) index; | ||
393 | return_desc->reference.opcode = AML_INDEX_OP; | ||
387 | 394 | ||
388 | /* At this point, the Source operand is a Package, Buffer, or String */ | 395 | /* |
396 | * At this point, the Source operand is a String, Buffer, or Package. | ||
397 | * Verify that the index is within range. | ||
398 | */ | ||
399 | switch (ACPI_GET_OBJECT_TYPE(operand[0])) { | ||
400 | case ACPI_TYPE_STRING: | ||
389 | 401 | ||
390 | if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) { | 402 | if (index >= operand[0]->string.length) { |
391 | /* Object to be indexed is a Package */ | 403 | status = AE_AML_STRING_LIMIT; |
404 | } | ||
405 | |||
406 | return_desc->reference.target_type = | ||
407 | ACPI_TYPE_BUFFER_FIELD; | ||
408 | break; | ||
409 | |||
410 | case ACPI_TYPE_BUFFER: | ||
411 | |||
412 | if (index >= operand[0]->buffer.length) { | ||
413 | status = AE_AML_BUFFER_LIMIT; | ||
414 | } | ||
415 | |||
416 | return_desc->reference.target_type = | ||
417 | ACPI_TYPE_BUFFER_FIELD; | ||
418 | break; | ||
419 | |||
420 | case ACPI_TYPE_PACKAGE: | ||
392 | 421 | ||
393 | if (index >= operand[0]->package.count) { | 422 | if (index >= operand[0]->package.count) { |
394 | ACPI_ERROR((AE_INFO, | ||
395 | "Index value (%X%8.8X) beyond package end (%X)", | ||
396 | ACPI_FORMAT_UINT64(index), | ||
397 | operand[0]->package.count)); | ||
398 | status = AE_AML_PACKAGE_LIMIT; | 423 | status = AE_AML_PACKAGE_LIMIT; |
399 | goto cleanup; | ||
400 | } | 424 | } |
401 | 425 | ||
402 | return_desc->reference.target_type = ACPI_TYPE_PACKAGE; | 426 | return_desc->reference.target_type = ACPI_TYPE_PACKAGE; |
403 | return_desc->reference.object = operand[0]; | ||
404 | return_desc->reference.where = | 427 | return_desc->reference.where = |
405 | &operand[0]->package.elements[index]; | 428 | &operand[0]->package.elements[index]; |
406 | } else { | 429 | break; |
407 | /* Object to be indexed is a Buffer/String */ | ||
408 | 430 | ||
409 | if (index >= operand[0]->buffer.length) { | 431 | default: |
410 | ACPI_ERROR((AE_INFO, | ||
411 | "Index value (%X%8.8X) beyond end of buffer (%X)", | ||
412 | ACPI_FORMAT_UINT64(index), | ||
413 | operand[0]->buffer.length)); | ||
414 | status = AE_AML_BUFFER_LIMIT; | ||
415 | goto cleanup; | ||
416 | } | ||
417 | 432 | ||
418 | return_desc->reference.target_type = | 433 | status = AE_AML_INTERNAL; |
419 | ACPI_TYPE_BUFFER_FIELD; | 434 | goto cleanup; |
420 | return_desc->reference.object = operand[0]; | 435 | } |
436 | |||
437 | /* Failure means that the Index was beyond the end of the object */ | ||
438 | |||
439 | if (ACPI_FAILURE(status)) { | ||
440 | ACPI_EXCEPTION((AE_INFO, status, | ||
441 | "Index (%X%8.8X) is beyond end of object", | ||
442 | ACPI_FORMAT_UINT64(index))); | ||
443 | goto cleanup; | ||
421 | } | 444 | } |
422 | 445 | ||
423 | /* | 446 | /* |
424 | * Add a reference to the target package/buffer/string for the life | 447 | * Save the target object and add a reference to it for the life |
425 | * of the index. | 448 | * of the index |
426 | */ | 449 | */ |
450 | return_desc->reference.object = operand[0]; | ||
427 | acpi_ut_add_reference(operand[0]); | 451 | acpi_ut_add_reference(operand[0]); |
428 | 452 | ||
429 | /* Complete the Index reference object */ | ||
430 | |||
431 | return_desc->reference.opcode = AML_INDEX_OP; | ||
432 | return_desc->reference.offset = (u32) index; | ||
433 | |||
434 | /* Store the reference to the Target */ | 453 | /* Store the reference to the Target */ |
435 | 454 | ||
436 | status = acpi_ex_store(return_desc, operand[2], walk_state); | 455 | status = acpi_ex_store(return_desc, operand[2], walk_state); |
@@ -495,7 +514,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
495 | acpi_status status = AE_OK; | 514 | acpi_status status = AE_OK; |
496 | u8 logical_result = FALSE; | 515 | u8 logical_result = FALSE; |
497 | 516 | ||
498 | ACPI_FUNCTION_TRACE_STR("ex_opcode_2A_0T_1R", | 517 | ACPI_FUNCTION_TRACE_STR(ex_opcode_2A_0T_1R, |
499 | acpi_ps_get_opcode_name(walk_state->opcode)); | 518 | acpi_ps_get_opcode_name(walk_state->opcode)); |
500 | 519 | ||
501 | /* Create the internal return object */ | 520 | /* Create the internal return object */ |
@@ -509,6 +528,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
509 | /* Execute the Opcode */ | 528 | /* Execute the Opcode */ |
510 | 529 | ||
511 | if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) { | 530 | if (walk_state->op_info->flags & AML_LOGICAL_NUMERIC) { |
531 | |||
512 | /* logical_op (Operand0, Operand1) */ | 532 | /* logical_op (Operand0, Operand1) */ |
513 | 533 | ||
514 | status = acpi_ex_do_logical_numeric_op(walk_state->opcode, | 534 | status = acpi_ex_do_logical_numeric_op(walk_state->opcode, |
@@ -518,6 +538,7 @@ acpi_status acpi_ex_opcode_2A_0T_1R(struct acpi_walk_state *walk_state) | |||
518 | value, &logical_result); | 538 | value, &logical_result); |
519 | goto store_logical_result; | 539 | goto store_logical_result; |
520 | } else if (walk_state->op_info->flags & AML_LOGICAL) { | 540 | } else if (walk_state->op_info->flags & AML_LOGICAL) { |
541 | |||
521 | /* logical_op (Operand0, Operand1) */ | 542 | /* logical_op (Operand0, Operand1) */ |
522 | 543 | ||
523 | status = acpi_ex_do_logical_op(walk_state->opcode, operand[0], | 544 | status = acpi_ex_do_logical_op(walk_state->opcode, operand[0], |