diff options
Diffstat (limited to 'drivers/acpi/executer/exoparg2.c')
-rw-r--r-- | drivers/acpi/executer/exoparg2.c | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index e263a5ddd405..5e1abb12c748 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c | |||
@@ -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) |
@@ -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); |
@@ -287,6 +289,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) | |||
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; | ||
394 | return_desc->reference.object = operand[0]; | ||
387 | 395 | ||
388 | /* At this point, the Source operand is a Package, Buffer, or String */ | 396 | /* |
397 | * At this point, the Source operand is a String, Buffer, or Package. | ||
398 | * Verify that the index is within range. | ||
399 | */ | ||
400 | switch (ACPI_GET_OBJECT_TYPE(operand[0])) { | ||
401 | case ACPI_TYPE_STRING: | ||
389 | 402 | ||
390 | if (ACPI_GET_OBJECT_TYPE(operand[0]) == ACPI_TYPE_PACKAGE) { | 403 | if (index >= operand[0]->string.length) { |
391 | /* Object to be indexed is a Package */ | 404 | status = AE_AML_STRING_LIMIT; |
405 | } | ||
406 | |||
407 | return_desc->reference.target_type = | ||
408 | ACPI_TYPE_BUFFER_FIELD; | ||
409 | break; | ||
410 | |||
411 | case ACPI_TYPE_BUFFER: | ||
412 | |||
413 | if (index >= operand[0]->buffer.length) { | ||
414 | status = AE_AML_BUFFER_LIMIT; | ||
415 | } | ||
416 | |||
417 | return_desc->reference.target_type = | ||
418 | ACPI_TYPE_BUFFER_FIELD; | ||
419 | break; | ||
420 | |||
421 | case ACPI_TYPE_PACKAGE: | ||
392 | 422 | ||
393 | if (index >= operand[0]->package.count) { | 423 | 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; | 424 | status = AE_AML_PACKAGE_LIMIT; |
399 | goto cleanup; | ||
400 | } | 425 | } |
401 | 426 | ||
402 | return_desc->reference.target_type = ACPI_TYPE_PACKAGE; | 427 | return_desc->reference.target_type = ACPI_TYPE_PACKAGE; |
403 | return_desc->reference.object = operand[0]; | ||
404 | return_desc->reference.where = | 428 | return_desc->reference.where = |
405 | &operand[0]->package.elements[index]; | 429 | &operand[0]->package.elements[index]; |
406 | } else { | 430 | break; |
407 | /* Object to be indexed is a Buffer/String */ | ||
408 | 431 | ||
409 | if (index >= operand[0]->buffer.length) { | 432 | 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 | 433 | ||
418 | return_desc->reference.target_type = | 434 | status = AE_AML_INTERNAL; |
419 | ACPI_TYPE_BUFFER_FIELD; | 435 | goto cleanup; |
420 | return_desc->reference.object = operand[0]; | 436 | } |
437 | |||
438 | /* Failure means that the Index was beyond the end of the object */ | ||
439 | |||
440 | if (ACPI_FAILURE(status)) { | ||
441 | ACPI_EXCEPTION((AE_INFO, status, | ||
442 | "Index (%X%8.8X) is beyond end of object", | ||
443 | ACPI_FORMAT_UINT64(index))); | ||
444 | goto cleanup; | ||
421 | } | 445 | } |
422 | 446 | ||
423 | /* | 447 | /* |
424 | * Add a reference to the target package/buffer/string for the life | 448 | * Add a reference to the target package/buffer/string for the life |
425 | * of the index. | 449 | * of the index |
426 | */ | 450 | */ |
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); |
@@ -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], |