|
@@ -45,9 +45,14 @@
|
|
|
#include <acpi/acpi.h>
|
|
|
#include <acpi/acnamesp.h>
|
|
|
#include <acpi/acinterp.h>
|
|
|
+#include <acpi/amlcode.h>
|
|
|
|
|
|
#define _COMPONENT ACPI_NAMESPACE
|
|
|
ACPI_MODULE_NAME("nsxfeval")
|
|
|
+
|
|
|
+/* Local prototypes */
|
|
|
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info);
|
|
|
+
|
|
|
#ifdef ACPI_FUTURE_USAGE
|
|
|
/*******************************************************************************
|
|
|
*
|
|
@@ -69,6 +74,7 @@ ACPI_MODULE_NAME("nsxfeval")
|
|
|
* be valid (non-null)
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
+
|
|
|
acpi_status
|
|
|
acpi_evaluate_object_typed(acpi_handle handle,
|
|
|
acpi_string pathname,
|
|
@@ -283,6 +289,10 @@ acpi_evaluate_object(acpi_handle handle,
|
|
|
|
|
|
if (ACPI_SUCCESS(status)) {
|
|
|
|
|
|
+ /* Dereference Index and ref_of references */
|
|
|
+
|
|
|
+ acpi_ns_resolve_references(info);
|
|
|
+
|
|
|
/* Get the size of the returned object */
|
|
|
|
|
|
status =
|
|
@@ -350,6 +360,74 @@ acpi_evaluate_object(acpi_handle handle,
|
|
|
|
|
|
ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
|
|
|
|
|
|
+/*******************************************************************************
|
|
|
+ *
|
|
|
+ * FUNCTION: acpi_ns_resolve_references
|
|
|
+ *
|
|
|
+ * PARAMETERS: Info - Evaluation info block
|
|
|
+ *
|
|
|
+ * RETURN: Info->return_object is replaced with the dereferenced object
|
|
|
+ *
|
|
|
+ * DESCRIPTION: Dereference certain reference objects. Called before an
|
|
|
+ * internal return object is converted to an external union acpi_object.
|
|
|
+ *
|
|
|
+ * Performs an automatic dereference of Index and ref_of reference objects.
|
|
|
+ * These reference objects are not supported by the union acpi_object, so this is a
|
|
|
+ * last resort effort to return something useful. Also, provides compatibility
|
|
|
+ * with other ACPI implementations.
|
|
|
+ *
|
|
|
+ * NOTE: does not handle references within returned package objects or nested
|
|
|
+ * references, but this support could be added later if found to be necessary.
|
|
|
+ *
|
|
|
+ ******************************************************************************/
|
|
|
+static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
|
|
|
+{
|
|
|
+ union acpi_operand_object *obj_desc = NULL;
|
|
|
+ struct acpi_namespace_node *node;
|
|
|
+
|
|
|
+ /* We are interested in reference objects only */
|
|
|
+
|
|
|
+ if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
|
|
|
+ ACPI_TYPE_LOCAL_REFERENCE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Two types of references are supported - those created by Index and
|
|
|
+ * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted
|
|
|
+ * to an union acpi_object, so it is not dereferenced here. A ddb_handle
|
|
|
+ * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to
|
|
|
+ * an union acpi_object.
|
|
|
+ */
|
|
|
+ switch (info->return_object->reference.opcode) {
|
|
|
+ case AML_INDEX_OP:
|
|
|
+
|
|
|
+ obj_desc = *(info->return_object->reference.where);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case AML_REF_OF_OP:
|
|
|
+
|
|
|
+ node = info->return_object->reference.object;
|
|
|
+ if (node) {
|
|
|
+ obj_desc = node->object;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Replace the existing reference object */
|
|
|
+
|
|
|
+ if (obj_desc) {
|
|
|
+ acpi_ut_add_reference(obj_desc);
|
|
|
+ acpi_ut_remove_reference(info->return_object);
|
|
|
+ info->return_object = obj_desc;
|
|
|
+ }
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* FUNCTION: acpi_walk_namespace
|
|
@@ -379,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object)
|
|
|
* function, etc.
|
|
|
*
|
|
|
******************************************************************************/
|
|
|
+
|
|
|
acpi_status
|
|
|
acpi_walk_namespace(acpi_object_type type,
|
|
|
acpi_handle start_object,
|