]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/executer/exresolv.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / acpi / executer / exresolv.c
index 97eecbd3242dc9e067b5aa3ac89191ea9e35fbc1..89571b92a52279258812e7cc6f93ad5024acc28b 100644 (file)
@@ -6,7 +6,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2008, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,6 @@
 #include <acpi/acdispat.h>
 #include <acpi/acinterp.h>
 #include <acpi/acnamesp.h>
-#include <acpi/acparser.h>
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exresolv")
@@ -78,10 +77,10 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
 {
        acpi_status status;
 
-       ACPI_FUNCTION_TRACE_PTR("ex_resolve_to_value", stack_ptr);
+       ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
 
        if (!stack_ptr || !*stack_ptr) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Internal - null pointer\n"));
+               ACPI_ERROR((AE_INFO, "Internal - null pointer"));
                return_ACPI_STATUS(AE_AML_NO_OPERAND);
        }
 
@@ -97,8 +96,7 @@ acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
                }
 
                if (!*stack_ptr) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                         "Internal - null pointer\n"));
+                       ACPI_ERROR((AE_INFO, "Internal - null pointer"));
                        return_ACPI_STATUS(AE_AML_NO_OPERAND);
                }
        }
@@ -141,11 +139,10 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 {
        acpi_status status = AE_OK;
        union acpi_operand_object *stack_desc;
-       void *temp_node;
-       union acpi_operand_object *obj_desc;
-       u16 opcode;
+       union acpi_operand_object *obj_desc = NULL;
+       u8 ref_type;
 
-       ACPI_FUNCTION_TRACE("ex_resolve_object_to_value");
+       ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
 
        stack_desc = *stack_ptr;
 
@@ -154,36 +151,19 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
        switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
        case ACPI_TYPE_LOCAL_REFERENCE:
 
-               opcode = stack_desc->reference.opcode;
+               ref_type = stack_desc->reference.class;
 
-               switch (opcode) {
-               case AML_NAME_OP:
-
-                       /*
-                        * Convert name reference to a namespace node
-                        * Then, acpi_ex_resolve_node_to_value can be used to get the value
-                        */
-                       temp_node = stack_desc->reference.object;
-
-                       /* Delete the Reference Object */
-
-                       acpi_ut_remove_reference(stack_desc);
-
-                       /* Return the namespace node */
-
-                       (*stack_ptr) = temp_node;
-                       break;
-
-               case AML_LOCAL_OP:
-               case AML_ARG_OP:
+               switch (ref_type) {
+               case ACPI_REFCLASS_LOCAL:
+               case ACPI_REFCLASS_ARG:
 
                        /*
                         * Get the local from the method's state info
                         * Note: this increments the local's object reference count
                         */
-                       status = acpi_ds_method_data_get_value(opcode,
+                       status = acpi_ds_method_data_get_value(ref_type,
                                                               stack_desc->
-                                                              reference.offset,
+                                                              reference.value,
                                                               walk_state,
                                                               &obj_desc);
                        if (ACPI_FAILURE(status)) {
@@ -191,8 +171,8 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                        }
 
                        ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                         "[Arg/Local %X] value_obj is %p\n",
-                                         stack_desc->reference.offset,
+                                         "[Arg/Local %X] ValueObj is %p\n",
+                                         stack_desc->reference.value,
                                          obj_desc));
 
                        /*
@@ -203,20 +183,30 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                        *stack_ptr = obj_desc;
                        break;
 
-               case AML_INDEX_OP:
+               case ACPI_REFCLASS_INDEX:
 
                        switch (stack_desc->reference.target_type) {
                        case ACPI_TYPE_BUFFER_FIELD:
 
-                               /* Just return - leave the Reference on the stack */
+                               /* Just return - do not dereference */
                                break;
 
                        case ACPI_TYPE_PACKAGE:
 
+                               /* If method call or copy_object - do not dereference */
+
+                               if ((walk_state->opcode ==
+                                    AML_INT_METHODCALL_OP)
+                                   || (walk_state->opcode == AML_COPY_OP)) {
+                                       break;
+                               }
+
+                               /* Otherwise, dereference the package_index to a package element */
+
                                obj_desc = *stack_desc->reference.where;
                                if (obj_desc) {
                                        /*
-                                        * Valid obj descriptor, copy pointer to return value
+                                        * Valid object descriptor, copy pointer to return value
                                         * (i.e., dereference the package index)
                                         * Delete the ref object, increment the returned object
                                         */
@@ -225,12 +215,12 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                                        *stack_ptr = obj_desc;
                                } else {
                                        /*
-                                        * A NULL object descriptor means an unitialized element of
+                                        * A NULL object descriptor means an uninitialized element of
                                         * the package, can't dereference it
                                         */
-                                       ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                                         "Attempt to deref an Index to NULL pkg element Idx=%p\n",
-                                                         stack_desc));
+                                       ACPI_ERROR((AE_INFO,
+                                                   "Attempt to dereference an Index to NULL package element Idx=%p",
+                                                   stack_desc));
                                        status = AE_AML_UNINITIALIZED_ELEMENT;
                                }
                                break;
@@ -239,32 +229,51 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
 
                                /* Invalid reference object */
 
-                               ACPI_REPORT_ERROR(("During resolve, Unknown target_type %X in Index/Reference obj %p\n", stack_desc->reference.target_type, stack_desc));
+                               ACPI_ERROR((AE_INFO,
+                                           "Unknown TargetType %X in Index/Reference object %p",
+                                           stack_desc->reference.target_type,
+                                           stack_desc));
                                status = AE_AML_INTERNAL;
                                break;
                        }
                        break;
 
-               case AML_REF_OF_OP:
-               case AML_DEBUG_OP:
-               case AML_LOAD_OP:
+               case ACPI_REFCLASS_REFOF:
+               case ACPI_REFCLASS_DEBUG:
+               case ACPI_REFCLASS_TABLE:
 
-                       /* Just leave the object as-is */
+                       /* Just leave the object as-is, do not dereference */
 
                        break;
 
-               case AML_INT_NAMEPATH_OP:       /* Reference to a named object */
+               case ACPI_REFCLASS_NAME:        /* Reference to a named object */
 
-                       /* Get the object pointed to by the namespace node */
+                       /* Dereference the name */
+
+                       if ((stack_desc->reference.node->type ==
+                            ACPI_TYPE_DEVICE)
+                           || (stack_desc->reference.node->type ==
+                               ACPI_TYPE_THERMAL)) {
+
+                               /* These node types do not have 'real' subobjects */
+
+                               *stack_ptr = (void *)stack_desc->reference.node;
+                       } else {
+                               /* Get the object pointed to by the namespace node */
+
+                               *stack_ptr =
+                                   (stack_desc->reference.node)->object;
+                               acpi_ut_add_reference(*stack_ptr);
+                       }
 
-                       *stack_ptr = (stack_desc->reference.node)->object;
-                       acpi_ut_add_reference(*stack_ptr);
                        acpi_ut_remove_reference(stack_desc);
                        break;
 
                default:
 
-                       ACPI_REPORT_ERROR(("During resolve, Unknown Reference opcode %X (%s) in %p\n", opcode, acpi_ps_get_opcode_name(opcode), stack_desc));
+                       ACPI_ERROR((AE_INFO,
+                                   "Unknown Reference type %X in %p", ref_type,
+                                   stack_desc));
                        status = AE_AML_INTERNAL;
                        break;
                }
@@ -280,21 +289,23 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
                status = acpi_ds_get_package_arguments(stack_desc);
                break;
 
-               /* These cases may never happen here, but just in case.. */
-
        case ACPI_TYPE_BUFFER_FIELD:
        case ACPI_TYPE_LOCAL_REGION_FIELD:
        case ACPI_TYPE_LOCAL_BANK_FIELD:
        case ACPI_TYPE_LOCAL_INDEX_FIELD:
 
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-                                 "field_read source_desc=%p Type=%X\n",
+                                 "FieldRead SourceDesc=%p Type=%X\n",
                                  stack_desc,
                                  ACPI_GET_OBJECT_TYPE(stack_desc)));
 
                status =
                    acpi_ex_read_data_from_field(walk_state, stack_desc,
                                                 &obj_desc);
+
+               /* Remove a reference to the original operand, then override */
+
+               acpi_ut_remove_reference(*stack_ptr);
                *stack_ptr = (void *)obj_desc;
                break;
 
@@ -332,7 +343,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
        acpi_object_type type;
        acpi_status status;
 
-       ACPI_FUNCTION_TRACE("acpi_ex_resolve_multiple");
+       ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
 
        /* Operand can be either a namespace node or an operand descriptor */
 
@@ -369,24 +380,32 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
        }
 
        /*
-        * For reference objects created via the ref_of or Index operators,
-        * we need to get to the base object (as per the ACPI specification
-        * of the object_type and size_of operators). This means traversing
-        * the list of possibly many nested references.
+        * For reference objects created via the ref_of, Index, or Load/load_table
+        * operators, we need to get to the base object (as per the ACPI
+        * specification of the object_type and size_of operators). This means
+        * traversing the list of possibly many nested references.
         */
        while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
-               switch (obj_desc->reference.opcode) {
-               case AML_REF_OF_OP:
+               switch (obj_desc->reference.class) {
+               case ACPI_REFCLASS_REFOF:
+               case ACPI_REFCLASS_NAME:
 
                        /* Dereference the reference pointer */
 
-                       node = obj_desc->reference.object;
+                       if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
+                               node = obj_desc->reference.object;
+                       } else {        /* AML_INT_NAMEPATH_OP */
+
+                               node = obj_desc->reference.node;
+                       }
 
                        /* All "References" point to a NS node */
 
                        if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
                            ACPI_DESC_TYPE_NAMED) {
-                               ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
+                               ACPI_ERROR((AE_INFO, "Not a NS node %p [%s]",
+                                           node,
+                                           acpi_ut_get_descriptor_name(node)));
                                return_ACPI_STATUS(AE_AML_INTERNAL);
                        }
 
@@ -394,6 +413,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
 
                        obj_desc = acpi_ns_get_attached_object(node);
                        if (!obj_desc) {
+
                                /* No object, use the NS node type */
 
                                type = acpi_ns_get_type(node);
@@ -407,7 +427,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_INDEX_OP:
+               case ACPI_REFCLASS_INDEX:
 
                        /* Get the type of this reference (index into another object) */
 
@@ -425,6 +445,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                         */
                        obj_desc = *(obj_desc->reference.where);
                        if (!obj_desc) {
+
                                /* NULL package elements are allowed */
 
                                type = 0;       /* Uninitialized */
@@ -432,48 +453,22 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_INT_NAMEPATH_OP:
+               case ACPI_REFCLASS_TABLE:
 
-                       /* Dereference the reference pointer */
-
-                       node = obj_desc->reference.node;
-
-                       /* All "References" point to a NS node */
-
-                       if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
-                           ACPI_DESC_TYPE_NAMED) {
-                               ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Not a NS node %p [%s]\n", node, acpi_ut_get_descriptor_name(node)));
-                               return_ACPI_STATUS(AE_AML_INTERNAL);
-                       }
-
-                       /* Get the attached object */
-
-                       obj_desc = acpi_ns_get_attached_object(node);
-                       if (!obj_desc) {
-                               /* No object, use the NS node type */
-
-                               type = acpi_ns_get_type(node);
-                               goto exit;
-                       }
-
-                       /* Check for circular references */
-
-                       if (obj_desc == operand) {
-                               return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
-                       }
-                       break;
+                       type = ACPI_TYPE_DDB_HANDLE;
+                       goto exit;
 
-               case AML_LOCAL_OP:
-               case AML_ARG_OP:
+               case ACPI_REFCLASS_LOCAL:
+               case ACPI_REFCLASS_ARG:
 
                        if (return_desc) {
                                status =
                                    acpi_ds_method_data_get_value(obj_desc->
                                                                  reference.
-                                                                 opcode,
+                                                                 class,
                                                                  obj_desc->
                                                                  reference.
-                                                                 offset,
+                                                                 value,
                                                                  walk_state,
                                                                  &obj_desc);
                                if (ACPI_FAILURE(status)) {
@@ -484,10 +479,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                                status =
                                    acpi_ds_method_data_get_node(obj_desc->
                                                                 reference.
-                                                                opcode,
+                                                                class,
                                                                 obj_desc->
                                                                 reference.
-                                                                offset,
+                                                                value,
                                                                 walk_state,
                                                                 &node);
                                if (ACPI_FAILURE(status)) {
@@ -502,16 +497,18 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
                        }
                        break;
 
-               case AML_DEBUG_OP:
+               case ACPI_REFCLASS_DEBUG:
 
-                       /* The Debug Object is of type "debug_object" */
+                       /* The Debug Object is of type "DebugObject" */
 
                        type = ACPI_TYPE_DEBUG_OBJECT;
                        goto exit;
 
                default:
 
-                       ACPI_REPORT_ERROR(("acpi_ex_resolve_multiple: Unknown Reference subtype %X\n", obj_desc->reference.opcode));
+                       ACPI_ERROR((AE_INFO,
+                                   "Unknown Reference Class %2.2X",
+                                   obj_desc->reference.class));
                        return_ACPI_STATUS(AE_AML_INTERNAL);
                }
        }