aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2013-09-06 02:27:15 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-06 09:39:59 -0400
commit4be4be8fee2ee99a52f94f90d03d2f287ee1db86 (patch)
tree7a9508fc800999401dc88af5be4610b85b0a73af /drivers/acpi
parenta9238741987386bb549d61572973c7e62b2a4145 (diff)
ACPICA: Fix for a Store->ArgX when ArgX contains a reference to a field.
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>
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 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
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
@@ -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
527static acpi_status
528acpi_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}