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