aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/namespace/nsxfeval.c
diff options
context:
space:
mode:
authorLin Ming <ming.m.lin@intel.com>2008-08-04 01:22:10 -0400
committerLen Brown <len.brown@intel.com>2008-10-22 23:14:37 -0400
commitbbc241340681557a16982f4d1840f00963bc05b4 (patch)
tree660daf64165e970aa064c729f8876595fdad8e3f /drivers/acpi/namespace/nsxfeval.c
parentb417d40b9a850f12f69aa9d785d2af39c9463bb8 (diff)
ACPICA: Add function to dereference returned reference objects
Examines the return object from a call to acpi_evaluate_object. Any Index or RefOf references are automatically dereferenced in an attempt to return something useful (these reference types cannot be converted into an external ACPI_OBJECT.) Lin Ming, Bob Moore. http://bugzilla.kernel.org/show_bug.cgi?id=11105 Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/namespace/nsxfeval.c')
-rw-r--r--drivers/acpi/namespace/nsxfeval.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index 38be5865d95..f3cc3762453 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -45,9 +45,14 @@
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include <acpi/acnamesp.h> 46#include <acpi/acnamesp.h>
47#include <acpi/acinterp.h> 47#include <acpi/acinterp.h>
48#include <acpi/amlcode.h>
48 49
49#define _COMPONENT ACPI_NAMESPACE 50#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsxfeval") 51ACPI_MODULE_NAME("nsxfeval")
52
53/* Local prototypes */
54static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
55
51#ifdef ACPI_FUTURE_USAGE 56#ifdef ACPI_FUTURE_USAGE
52/******************************************************************************* 57/*******************************************************************************
53 * 58 *
@@ -69,6 +74,7 @@ ACPI_MODULE_NAME("nsxfeval")
69 * be valid (non-null) 74 * be valid (non-null)
70 * 75 *
71 ******************************************************************************/ 76 ******************************************************************************/
77
72acpi_status 78acpi_status
73acpi_evaluate_object_typed(acpi_handle handle, 79acpi_evaluate_object_typed(acpi_handle handle,
74 acpi_string pathname, 80 acpi_string pathname,
@@ -283,6 +289,10 @@ acpi_evaluate_object(acpi_handle handle,
283 289
284 if (ACPI_SUCCESS(status)) { 290 if (ACPI_SUCCESS(status)) {
285 291
292 /* Dereference Index and ref_of references */
293
294 acpi_ns_resolve_references(info);
295
286 /* Get the size of the returned object */ 296 /* Get the size of the returned object */
287 297
288 status = 298 status =
@@ -352,6 +362,74 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
352 362
353/******************************************************************************* 363/*******************************************************************************
354 * 364 *
365 * FUNCTION: acpi_ns_resolve_references
366 *
367 * PARAMETERS: Info - Evaluation info block
368 *
369 * RETURN: Info->return_object is replaced with the dereferenced object
370 *
371 * DESCRIPTION: Dereference certain reference objects. Called before an
372 * internal return object is converted to an external union acpi_object.
373 *
374 * Performs an automatic dereference of Index and ref_of reference objects.
375 * These reference objects are not supported by the union acpi_object, so this is a
376 * last resort effort to return something useful. Also, provides compatibility
377 * with other ACPI implementations.
378 *
379 * NOTE: does not handle references within returned package objects or nested
380 * references, but this support could be added later if found to be necessary.
381 *
382 ******************************************************************************/
383static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
384{
385 union acpi_operand_object *obj_desc = NULL;
386 struct acpi_namespace_node *node;
387
388 /* We are interested in reference objects only */
389
390 if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
391 ACPI_TYPE_LOCAL_REFERENCE) {
392 return;
393 }
394
395 /*
396 * Two types of references are supported - those created by Index and
397 * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
398 * to an union acpi_object, so it is not dereferenced here. A ddb_handle
399 * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
400 * an union acpi_object.
401 */
402 switch (info->return_object->reference.opcode) {
403 case AML_INDEX_OP:
404
405 obj_desc = *(info->return_object->reference.where);
406 break;
407
408 case AML_REF_OF_OP:
409
410 node = info->return_object->reference.object;
411 if (node) {
412 obj_desc = node->object;
413 }
414 break;
415
416 default:
417 return;
418 }
419
420 /* Replace the existing reference object */
421
422 if (obj_desc) {
423 acpi_ut_add_reference(obj_desc);
424 acpi_ut_remove_reference(info->return_object);
425 info->return_object = obj_desc;
426 }
427
428 return;
429}
430
431/*******************************************************************************
432 *
355 * FUNCTION: acpi_walk_namespace 433 * FUNCTION: acpi_walk_namespace
356 * 434 *
357 * PARAMETERS: Type - acpi_object_type to search for 435 * PARAMETERS: Type - acpi_object_type to search for
@@ -379,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
379 * function, etc. 457 * function, etc.
380 * 458 *
381 ******************************************************************************/ 459 ******************************************************************************/
460
382acpi_status 461acpi_status
383acpi_walk_namespace(acpi_object_type type, 462acpi_walk_namespace(acpi_object_type type,
384 acpi_handle start_object, 463 acpi_handle start_object,