diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-10 17:15:09 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-10 17:15:09 -0400 |
commit | 8ca11824eebdcb41885fee118a76b9dd44a67200 (patch) | |
tree | f0d3cfb65d7f96fe02857cdb41a357984a27efa6 /drivers/acpi | |
parent | 08e97ff2779ffd3e6eb05d28bafdbc1fbb531d20 (diff) | |
parent | 4be4be8fee2ee99a52f94f90d03d2f287ee1db86 (diff) |
Merge branch 'acpica'
* acpica:
ACPICA: Fix for a Store->ArgX when ArgX contains a reference to a field.
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/exstore.c | 166 |
1 files changed, 102 insertions, 64 deletions
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c index 2bdba6f7d762..f0b09bf9887d 100644 --- a/drivers/acpi/acpica/exstore.c +++ b/drivers/acpi/acpica/exstore.c | |||
@@ -57,6 +57,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *val_desc, | |||
57 | union acpi_operand_object *dest_desc, | 57 | union acpi_operand_object *dest_desc, |
58 | struct acpi_walk_state *walk_state); | 58 | struct acpi_walk_state *walk_state); |
59 | 59 | ||
60 | static acpi_status | ||
61 | acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc, | ||
62 | struct acpi_namespace_node *node, | ||
63 | struct acpi_walk_state *walk_state); | ||
64 | |||
60 | /******************************************************************************* | 65 | /******************************************************************************* |
61 | * | 66 | * |
62 | * FUNCTION: acpi_ex_store | 67 | * FUNCTION: acpi_ex_store |
@@ -375,7 +380,11 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, | |||
375 | * When storing into an object the data is converted to the | 380 | * When storing into an object the data is converted to the |
376 | * target object type then stored in the object. This means | 381 | * target object type then stored in the object. This means |
377 | * that the target object type (for an initialized target) will | 382 | * that the target object type (for an initialized target) will |
378 | * not be changed by a store operation. | 383 | * not be changed by a store operation. A copy_object can change |
384 | * the target type, however. | ||
385 | * | ||
386 | * The implicit_conversion flag is set to NO/FALSE only when | ||
387 | * storing to an arg_x -- as per the rules of the ACPI spec. | ||
379 | * | 388 | * |
380 | * Assumes parameters are already validated. | 389 | * Assumes parameters are already validated. |
381 | * | 390 | * |
@@ -399,7 +408,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
399 | target_type = acpi_ns_get_type(node); | 408 | target_type = acpi_ns_get_type(node); |
400 | target_desc = acpi_ns_get_attached_object(node); | 409 | target_desc = acpi_ns_get_attached_object(node); |
401 | 410 | ||
402 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p(%s) into node %p(%s)\n", | 411 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p (%s) to node %p (%s)\n", |
403 | source_desc, | 412 | source_desc, |
404 | acpi_ut_get_object_type_name(source_desc), node, | 413 | acpi_ut_get_object_type_name(source_desc), node, |
405 | acpi_ut_get_type_name(target_type))); | 414 | acpi_ut_get_type_name(target_type))); |
@@ -413,45 +422,30 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
413 | return_ACPI_STATUS(status); | 422 | return_ACPI_STATUS(status); |
414 | } | 423 | } |
415 | 424 | ||
416 | /* If no implicit conversion, drop into the default case below */ | ||
417 | |||
418 | if ((!implicit_conversion) || | ||
419 | ((walk_state->opcode == AML_COPY_OP) && | ||
420 | (target_type != ACPI_TYPE_LOCAL_REGION_FIELD) && | ||
421 | (target_type != ACPI_TYPE_LOCAL_BANK_FIELD) && | ||
422 | (target_type != ACPI_TYPE_LOCAL_INDEX_FIELD))) { | ||
423 | /* | ||
424 | * Force execution of default (no implicit conversion). Note: | ||
425 | * copy_object does not perform an implicit conversion, as per the ACPI | ||
426 | * spec -- except in case of region/bank/index fields -- because these | ||
427 | * objects must retain their original type permanently. | ||
428 | */ | ||
429 | target_type = ACPI_TYPE_ANY; | ||
430 | } | ||
431 | |||
432 | /* Do the actual store operation */ | 425 | /* Do the actual store operation */ |
433 | 426 | ||
434 | switch (target_type) { | 427 | switch (target_type) { |
435 | case ACPI_TYPE_BUFFER_FIELD: | ||
436 | case ACPI_TYPE_LOCAL_REGION_FIELD: | ||
437 | case ACPI_TYPE_LOCAL_BANK_FIELD: | ||
438 | case ACPI_TYPE_LOCAL_INDEX_FIELD: | ||
439 | |||
440 | /* For fields, copy the source data to the target field. */ | ||
441 | |||
442 | status = acpi_ex_write_data_to_field(source_desc, target_desc, | ||
443 | &walk_state->result_obj); | ||
444 | break; | ||
445 | |||
446 | case ACPI_TYPE_INTEGER: | 428 | case ACPI_TYPE_INTEGER: |
447 | case ACPI_TYPE_STRING: | 429 | case ACPI_TYPE_STRING: |
448 | case ACPI_TYPE_BUFFER: | 430 | case ACPI_TYPE_BUFFER: |
449 | /* | 431 | /* |
450 | * These target types are all of type Integer/String/Buffer, and | 432 | * The simple data types all support implicit source operand |
451 | * therefore support implicit conversion before the store. | 433 | * conversion before the store. |
452 | * | ||
453 | * Copy and/or convert the source object to a new target object | ||
454 | */ | 434 | */ |
435 | |||
436 | if ((walk_state->opcode == AML_COPY_OP) || !implicit_conversion) { | ||
437 | /* | ||
438 | * However, copy_object and Stores to arg_x do not perform | ||
439 | * an implicit conversion, as per the ACPI specification. | ||
440 | * A direct store is performed instead. | ||
441 | */ | ||
442 | status = acpi_ex_store_direct_to_node(source_desc, node, | ||
443 | walk_state); | ||
444 | break; | ||
445 | } | ||
446 | |||
447 | /* Store with implicit source operand conversion support */ | ||
448 | |||
455 | status = | 449 | status = |
456 | acpi_ex_store_object_to_object(source_desc, target_desc, | 450 | acpi_ex_store_object_to_object(source_desc, target_desc, |
457 | &new_desc, walk_state); | 451 | &new_desc, walk_state); |
@@ -465,13 +459,12 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
465 | * the Name's type to that of the value being stored in it. | 459 | * the Name's type to that of the value being stored in it. |
466 | * source_desc reference count is incremented by attach_object. | 460 | * source_desc reference count is incremented by attach_object. |
467 | * | 461 | * |
468 | * Note: This may change the type of the node if an explicit store | 462 | * Note: This may change the type of the node if an explicit |
469 | * has been performed such that the node/object type has been | 463 | * store has been performed such that the node/object type |
470 | * changed. | 464 | * has been changed. |
471 | */ | 465 | */ |
472 | status = | 466 | status = acpi_ns_attach_object(node, new_desc, |
473 | acpi_ns_attach_object(node, new_desc, | 467 | new_desc->common.type); |
474 | new_desc->common.type); | ||
475 | 468 | ||
476 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 469 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
477 | "Store %s into %s via Convert/Attach\n", | 470 | "Store %s into %s via Convert/Attach\n", |
@@ -482,38 +475,83 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc, | |||
482 | } | 475 | } |
483 | break; | 476 | break; |
484 | 477 | ||
485 | default: | 478 | case ACPI_TYPE_BUFFER_FIELD: |
486 | 479 | case ACPI_TYPE_LOCAL_REGION_FIELD: | |
487 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 480 | case ACPI_TYPE_LOCAL_BANK_FIELD: |
488 | "Storing [%s] (%p) directly into node [%s] (%p)" | 481 | case ACPI_TYPE_LOCAL_INDEX_FIELD: |
489 | " with no implicit conversion\n", | 482 | /* |
490 | acpi_ut_get_object_type_name(source_desc), | 483 | * For all fields, always write the source data to the target |
491 | source_desc, | 484 | * field. Any required implicit source operand conversion is |
492 | acpi_ut_get_object_type_name(target_desc), | 485 | * performed in the function below as necessary. Note, field |
493 | node)); | 486 | * objects must retain their original type permanently. |
487 | */ | ||
488 | status = acpi_ex_write_data_to_field(source_desc, target_desc, | ||
489 | &walk_state->result_obj); | ||
490 | break; | ||
494 | 491 | ||
492 | default: | ||
495 | /* | 493 | /* |
496 | * No conversions for all other types. Directly store a copy of | 494 | * No conversions for all other types. Directly store a copy of |
497 | * the source object. NOTE: This is a departure from the ACPI | 495 | * the source object. This is the ACPI spec-defined behavior for |
498 | * spec, which states "If conversion is impossible, abort the | 496 | * the copy_object operator. |
499 | * running control method". | ||
500 | * | 497 | * |
501 | * This code implements "If conversion is impossible, treat the | 498 | * NOTE: For the Store operator, this is a departure from the |
502 | * Store operation as a CopyObject". | 499 | * ACPI spec, which states "If conversion is impossible, abort |
500 | * the running control method". Instead, this code implements | ||
501 | * "If conversion is impossible, treat the Store operation as | ||
502 | * a CopyObject". | ||
503 | */ | 503 | */ |
504 | status = | 504 | status = acpi_ex_store_direct_to_node(source_desc, node, |
505 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, | 505 | walk_state); |
506 | walk_state); | ||
507 | if (ACPI_FAILURE(status)) { | ||
508 | return_ACPI_STATUS(status); | ||
509 | } | ||
510 | |||
511 | status = | ||
512 | acpi_ns_attach_object(node, new_desc, | ||
513 | new_desc->common.type); | ||
514 | acpi_ut_remove_reference(new_desc); | ||
515 | break; | 506 | break; |
516 | } | 507 | } |
517 | 508 | ||
518 | return_ACPI_STATUS(status); | 509 | return_ACPI_STATUS(status); |
519 | } | 510 | } |
511 | |||
512 | /******************************************************************************* | ||
513 | * | ||
514 | * FUNCTION: acpi_ex_store_direct_to_node | ||
515 | * | ||
516 | * PARAMETERS: source_desc - Value to be stored | ||
517 | * node - Named object to receive the value | ||
518 | * walk_state - Current walk state | ||
519 | * | ||
520 | * RETURN: Status | ||
521 | * | ||
522 | * DESCRIPTION: "Store" an object directly to a node. This involves a copy | ||
523 | * and an attach. | ||
524 | * | ||
525 | ******************************************************************************/ | ||
526 | |||
527 | static acpi_status | ||
528 | acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc, | ||
529 | struct acpi_namespace_node *node, | ||
530 | struct acpi_walk_state *walk_state) | ||
531 | { | ||
532 | acpi_status status; | ||
533 | union acpi_operand_object *new_desc; | ||
534 | |||
535 | ACPI_FUNCTION_TRACE(ex_store_direct_to_node); | ||
536 | |||
537 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
538 | "Storing [%s] (%p) directly into node [%s] (%p)" | ||
539 | " with no implicit conversion\n", | ||
540 | acpi_ut_get_object_type_name(source_desc), | ||
541 | source_desc, acpi_ut_get_type_name(node->type), | ||
542 | node)); | ||
543 | |||
544 | /* Copy the source object to a new object */ | ||
545 | |||
546 | status = | ||
547 | acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state); | ||
548 | if (ACPI_FAILURE(status)) { | ||
549 | return_ACPI_STATUS(status); | ||
550 | } | ||
551 | |||
552 | /* Attach the new object to the node */ | ||
553 | |||
554 | status = acpi_ns_attach_object(node, new_desc, new_desc->common.type); | ||
555 | acpi_ut_remove_reference(new_desc); | ||
556 | return_ACPI_STATUS(status); | ||
557 | } | ||