Merge master.kernel.org:/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[pandora-kernel.git] / drivers / acpi / dispatcher / dswload.c
index 4117312..3507439 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2005, R. Byron Moore
+ * Copyright (C) 2000 - 2006, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -127,7 +127,7 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
        char *path;
        u32 flags;
 
-       ACPI_FUNCTION_NAME("ds_load1_begin_op");
+       ACPI_FUNCTION_TRACE(ds_load1_begin_op);
 
        op = walk_state->op;
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
@@ -138,14 +138,14 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
        if (op) {
                if (!(walk_state->op_info->flags & AML_NAMED)) {
                        *out_op = op;
-                       return (AE_OK);
+                       return_ACPI_STATUS(AE_OK);
                }
 
                /* Check if this object has already been installed in the namespace */
 
                if (op->common.node) {
                        *out_op = op;
-                       return (AE_OK);
+                       return_ACPI_STATUS(AE_OK);
                }
        }
 
@@ -178,17 +178,17 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                         * Target of Scope() not found.  Generate an External for it, and
                         * insert the name into the namespace.
                         */
-                       acpi_dm_add_to_external_list(path);
+                       acpi_dm_add_to_external_list(path, ACPI_TYPE_DEVICE, 0);
                        status =
                            acpi_ns_lookup(walk_state->scope_info, path,
                                           object_type, ACPI_IMODE_LOAD_PASS1,
                                           ACPI_NS_SEARCH_PARENT, walk_state,
-                                          &(node));
+                                          &node);
                }
 #endif
                if (ACPI_FAILURE(status)) {
-                       ACPI_REPORT_NSERROR(path, status);
-                       return (status);
+                       ACPI_ERROR_NAMESPACE(path, status);
+                       return_ACPI_STATUS(status);
                }
 
                /*
@@ -233,9 +233,11 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
 
                        /* All other types are an error */
 
-                       ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n", acpi_ut_get_type_name(node->type), path));
+                       ACPI_ERROR((AE_INFO,
+                                   "Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)",
+                                   acpi_ut_get_type_name(node->type), path));
 
-                       return (AE_AML_OPERAND_TYPE);
+                       return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                }
                break;
 
@@ -257,7 +259,9 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                 *       buffer_field, or Package), the name of the object is already
                 *       in the namespace.
                 */
+
                if (walk_state->deferred_node) {
+
                        /* This name is already in the namespace, get the node */
 
                        node = walk_state->deferred_node;
@@ -265,6 +269,16 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                        break;
                }
 
+               /*
+                * If we are executing a method, do not create any namespace objects
+                * during the load phase, only during execution.
+                */
+               if (walk_state->method_node) {
+                       node = NULL;
+                       status = AE_OK;
+                       break;
+               }
+
                flags = ACPI_NS_NO_UPSEARCH;
                if ((walk_state->opcode != AML_SCOPE_OP) &&
                    (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
@@ -287,10 +301,41 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
                status =
                    acpi_ns_lookup(walk_state->scope_info, path, object_type,
                                   ACPI_IMODE_LOAD_PASS1, flags, walk_state,
-                                  &(node));
+                                  &node);
                if (ACPI_FAILURE(status)) {
-                       ACPI_REPORT_NSERROR(path, status);
-                       return (status);
+                       if (status == AE_ALREADY_EXISTS) {
+
+                               /* The name already exists in this scope */
+
+                               if (node->flags & ANOBJ_IS_EXTERNAL) {
+                                       /*
+                                        * Allow one create on an object or segment that was
+                                        * previously declared External
+                                        */
+                                       node->flags &= ~ANOBJ_IS_EXTERNAL;
+                                       node->type = (u8) object_type;
+
+                                       /* Just retyped a node, probably will need to open a scope */
+
+                                       if (acpi_ns_opens_scope(object_type)) {
+                                               status =
+                                                   acpi_ds_scope_stack_push
+                                                   (node, object_type,
+                                                    walk_state);
+                                               if (ACPI_FAILURE(status)) {
+                                                       return_ACPI_STATUS
+                                                           (status);
+                                               }
+                                       }
+                                       status = AE_OK;
+                               }
+                       }
+
+                       if (ACPI_FAILURE(status)) {
+
+                               ACPI_ERROR_NAMESPACE(path, status);
+                               return_ACPI_STATUS(status);
+                       }
                }
                break;
        }
@@ -298,32 +343,34 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
        /* Common exit */
 
        if (!op) {
+
                /* Create a new op */
 
                op = acpi_ps_alloc_op(walk_state->opcode);
                if (!op) {
-                       return (AE_NO_MEMORY);
+                       return_ACPI_STATUS(AE_NO_MEMORY);
                }
        }
 
-       /* Initialize */
-
-       op->named.name = node->name.integer;
+       /* Initialize the op */
 
 #if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
-       op->named.path = (u8 *) path;
+       op->named.path = ACPI_CAST_PTR(u8, path);
 #endif
 
-       /*
-        * Put the Node in the "op" object that the parser uses, so we
-        * can get it again quickly when this scope is closed
-        */
-       op->common.node = node;
+       if (node) {
+               /*
+                * Put the Node in the "op" object that the parser uses, so we
+                * can get it again quickly when this scope is closed
+                */
+               op->common.node = node;
+               op->named.name = node->name.integer;
+       }
+
        acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
                           op);
-
        *out_op = op;
-       return (status);
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -339,13 +386,13 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
  *
  ******************************************************************************/
 
-acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
+acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
 {
        union acpi_parse_object *op;
        acpi_object_type object_type;
        acpi_status status = AE_OK;
 
-       ACPI_FUNCTION_NAME("ds_load1_end_op");
+       ACPI_FUNCTION_TRACE(ds_load1_end_op);
 
        op = walk_state->op;
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
@@ -354,7 +401,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
        /* We are only interested in opcodes that have an associated name */
 
        if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
-               return (AE_OK);
+               return_ACPI_STATUS(AE_OK);
        }
 
        /* Get the object type to determine if we should pop the scope */
@@ -363,26 +410,43 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
 
 #ifndef ACPI_NO_METHOD_EXECUTION
        if (walk_state->op_info->flags & AML_FIELD) {
-               if (walk_state->opcode == AML_FIELD_OP ||
-                   walk_state->opcode == AML_BANK_FIELD_OP ||
-                   walk_state->opcode == AML_INDEX_FIELD_OP) {
-                       status = acpi_ds_init_field_objects(op, walk_state);
+               /*
+                * If we are executing a method, do not create any namespace objects
+                * during the load phase, only during execution.
+                */
+               if (!walk_state->method_node) {
+                       if (walk_state->opcode == AML_FIELD_OP ||
+                           walk_state->opcode == AML_BANK_FIELD_OP ||
+                           walk_state->opcode == AML_INDEX_FIELD_OP) {
+                               status =
+                                   acpi_ds_init_field_objects(op, walk_state);
+                       }
                }
-               return (status);
+               return_ACPI_STATUS(status);
        }
 
-       if (op->common.aml_opcode == AML_REGION_OP) {
-               status = acpi_ex_create_region(op->named.data, op->named.length,
-                                              (acpi_adr_space_type)
-                                              ((op->common.value.arg)->common.
-                                               value.integer), walk_state);
-               if (ACPI_FAILURE(status)) {
-                       return (status);
+       /*
+        * If we are executing a method, do not create any namespace objects
+        * during the load phase, only during execution.
+        */
+       if (!walk_state->method_node) {
+               if (op->common.aml_opcode == AML_REGION_OP) {
+                       status =
+                           acpi_ex_create_region(op->named.data,
+                                                 op->named.length,
+                                                 (acpi_adr_space_type)
+                                                 ((op->common.value.arg)->
+                                                  common.value.integer),
+                                                 walk_state);
+                       if (ACPI_FAILURE(status)) {
+                               return_ACPI_STATUS(status);
+                       }
                }
        }
 #endif
 
        if (op->common.aml_opcode == AML_NAME_OP) {
+
                /* For Name opcode, get the object type from the argument */
 
                if (op->common.value.arg) {
@@ -391,47 +455,63 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
                                                               common.
                                                               aml_opcode))->
                            object_type;
-                       op->common.node->type = (u8) object_type;
+
+                       /* Set node type if we have a namespace node */
+
+                       if (op->common.node) {
+                               op->common.node->type = (u8) object_type;
+                       }
                }
        }
 
-       if (op->common.aml_opcode == AML_METHOD_OP) {
-               /*
-                * method_op pkg_length name_string method_flags term_list
-                *
-                * Note: We must create the method node/object pair as soon as we
-                * see the method declaration.  This allows later pass1 parsing
-                * of invocations of the method (need to know the number of
-                * arguments.)
-                */
-               ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                                 "LOADING-Method: State=%p Op=%p named_obj=%p\n",
-                                 walk_state, op, op->named.node));
+       /*
+        * If we are executing a method, do not create any namespace objects
+        * during the load phase, only during execution.
+        */
+       if (!walk_state->method_node) {
+               if (op->common.aml_opcode == AML_METHOD_OP) {
+                       /*
+                        * method_op pkg_length name_string method_flags term_list
+                        *
+                        * Note: We must create the method node/object pair as soon as we
+                        * see the method declaration.  This allows later pass1 parsing
+                        * of invocations of the method (need to know the number of
+                        * arguments.)
+                        */
+                       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+                                         "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
+                                         walk_state, op, op->named.node));
 
-               if (!acpi_ns_get_attached_object(op->named.node)) {
-                       walk_state->operands[0] = (void *)op->named.node;
-                       walk_state->num_operands = 1;
+                       if (!acpi_ns_get_attached_object(op->named.node)) {
+                               walk_state->operands[0] =
+                                   ACPI_CAST_PTR(void, op->named.node);
+                               walk_state->num_operands = 1;
 
-                       status =
-                           acpi_ds_create_operands(walk_state,
-                                                   op->common.value.arg);
-                       if (ACPI_SUCCESS(status)) {
-                               status = acpi_ex_create_method(op->named.data,
-                                                              op->named.length,
-                                                              walk_state);
-                       }
-                       walk_state->operands[0] = NULL;
-                       walk_state->num_operands = 0;
+                               status =
+                                   acpi_ds_create_operands(walk_state,
+                                                           op->common.value.
+                                                           arg);
+                               if (ACPI_SUCCESS(status)) {
+                                       status =
+                                           acpi_ex_create_method(op->named.
+                                                                 data,
+                                                                 op->named.
+                                                                 length,
+                                                                 walk_state);
+                               }
+                               walk_state->operands[0] = NULL;
+                               walk_state->num_operands = 0;
 
-                       if (ACPI_FAILURE(status)) {
-                               return (status);
+                               if (ACPI_FAILURE(status)) {
+                                       return_ACPI_STATUS(status);
+                               }
                        }
                }
        }
 
-       /* Pop the scope stack */
+       /* Pop the scope stack (only if loading a table) */
 
-       if (acpi_ns_opens_scope(object_type)) {
+       if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) {
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
                                  "(%s): Popping scope for Op %p\n",
                                  acpi_ut_get_type_name(object_type), op));
@@ -439,7 +519,7 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
                status = acpi_ds_scope_stack_pop(walk_state);
        }
 
-       return (status);
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
@@ -456,8 +536,8 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state * walk_state)
  ******************************************************************************/
 
 acpi_status
-acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
-                      union acpi_parse_object ** out_op)
+acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
+                      union acpi_parse_object **out_op)
 {
        union acpi_parse_object *op;
        struct acpi_namespace_node *node;
@@ -465,7 +545,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
        acpi_object_type object_type;
        char *buffer_ptr;
 
-       ACPI_FUNCTION_TRACE("ds_load2_begin_op");
+       ACPI_FUNCTION_TRACE(ds_load2_begin_op);
 
        op = walk_state->op;
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
@@ -475,6 +555,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                if ((walk_state->control_state) &&
                    (walk_state->control_state->common.state ==
                     ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
+
                        /* We are executing a while loop outside of a method */
 
                        status = acpi_ds_exec_begin_op(walk_state, out_op);
@@ -508,10 +589,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                /* Get the name we are going to enter or lookup in the namespace */
 
                if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
+
                        /* For Namepath op, get the path string */
 
                        buffer_ptr = op->common.value.string;
                        if (!buffer_ptr) {
+
                                /* No name, just exit */
 
                                return_ACPI_STATUS(AE_OK);
@@ -574,10 +657,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                        if (status == AE_NOT_FOUND) {
                                status = AE_OK;
                        } else {
-                               ACPI_REPORT_NSERROR(buffer_ptr, status);
+                               ACPI_ERROR_NAMESPACE(buffer_ptr, status);
                        }
 #else
-                       ACPI_REPORT_NSERROR(buffer_ptr, status);
+                       ACPI_ERROR_NAMESPACE(buffer_ptr, status);
 #endif
                        return_ACPI_STATUS(status);
                }
@@ -607,7 +690,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                         *  Scope (DEB) { ... }
                         */
 
-                       ACPI_REPORT_WARNING(("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n", buffer_ptr, acpi_ut_get_type_name(node->type)));
+                       ACPI_WARNING((AE_INFO,
+                                     "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)",
+                                     buffer_ptr,
+                                     acpi_ut_get_type_name(node->type)));
 
                        node->type = ACPI_TYPE_ANY;
                        walk_state->scope_info->common.value = ACPI_TYPE_ANY;
@@ -617,7 +703,10 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
 
                        /* All other types are an error */
 
-                       ACPI_REPORT_ERROR(("Invalid type (%s) for target of Scope operator [%4.4s]\n", acpi_ut_get_type_name(node->type), buffer_ptr));
+                       ACPI_ERROR((AE_INFO,
+                                   "Invalid type (%s) for target of Scope operator [%4.4s]",
+                                   acpi_ut_get_type_name(node->type),
+                                   buffer_ptr));
 
                        return (AE_AML_OPERAND_TYPE);
                }
@@ -628,6 +717,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                /* All other opcodes */
 
                if (op && op->common.node) {
+
                        /* This op/node was previously entered into the namespace */
 
                        node = op->common.node;
@@ -653,6 +743,7 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
                 * Note: Name may already exist if we are executing a deferred opcode.
                 */
                if (walk_state->deferred_node) {
+
                        /* This name is already in the namespace, get the node */
 
                        node = walk_state->deferred_node;
@@ -670,11 +761,12 @@ acpi_ds_load2_begin_op(struct acpi_walk_state * walk_state,
        }
 
        if (ACPI_FAILURE(status)) {
-               ACPI_REPORT_NSERROR(buffer_ptr, status);
+               ACPI_ERROR_NAMESPACE(buffer_ptr, status);
                return_ACPI_STATUS(status);
        }
 
        if (!op) {
+
                /* Create a new op */
 
                op = acpi_ps_alloc_op(walk_state->opcode);
@@ -724,7 +816,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
        u32 i;
 #endif
 
-       ACPI_FUNCTION_TRACE("ds_load2_end_op");
+       ACPI_FUNCTION_TRACE(ds_load2_end_op);
 
        op = walk_state->op;
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
@@ -818,7 +910,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
         */
 
        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                         "Create-Load [%s] State=%p Op=%p named_obj=%p\n",
+                         "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
                          acpi_ps_get_opcode_name(op->common.aml_opcode),
                          walk_state, op, node));
 
@@ -840,6 +932,13 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
        case AML_TYPE_NAMED_FIELD:
 
+               /*
+                * If we are executing a method, initialize the field
+                */
+               if (walk_state->method_node) {
+                       status = acpi_ds_init_field_objects(op, walk_state);
+               }
+
                switch (op->common.aml_opcode) {
                case AML_INDEX_FIELD_OP:
 
@@ -929,6 +1028,24 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                switch (op->common.aml_opcode) {
 #ifndef ACPI_NO_METHOD_EXECUTION
                case AML_REGION_OP:
+
+                       /*
+                        * If we are executing a method, initialize the region
+                        */
+                       if (walk_state->method_node) {
+                               status =
+                                   acpi_ex_create_region(op->named.data,
+                                                         op->named.length,
+                                                         (acpi_adr_space_type)
+                                                         ((op->common.value.
+                                                           arg)->common.value.
+                                                          integer),
+                                                         walk_state);
+                               if (ACPI_FAILURE(status)) {
+                                       return (status);
+                               }
+                       }
+
                        /*
                         * The op_region is not fully parsed at this time. Only valid
                         * argument is the space_id. (We must save the address of the
@@ -957,11 +1074,50 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
                        status = acpi_ds_create_node(walk_state, node, op);
                        break;
+
+               case AML_METHOD_OP:
+                       /*
+                        * method_op pkg_length name_string method_flags term_list
+                        *
+                        * Note: We must create the method node/object pair as soon as we
+                        * see the method declaration.  This allows later pass1 parsing
+                        * of invocations of the method (need to know the number of
+                        * arguments.)
+                        */
+                       ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
+                                         "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
+                                         walk_state, op, op->named.node));
+
+                       if (!acpi_ns_get_attached_object(op->named.node)) {
+                               walk_state->operands[0] =
+                                   ACPI_CAST_PTR(void, op->named.node);
+                               walk_state->num_operands = 1;
+
+                               status =
+                                   acpi_ds_create_operands(walk_state,
+                                                           op->common.value.
+                                                           arg);
+                               if (ACPI_SUCCESS(status)) {
+                                       status =
+                                           acpi_ex_create_method(op->named.
+                                                                 data,
+                                                                 op->named.
+                                                                 length,
+                                                                 walk_state);
+                               }
+                               walk_state->operands[0] = NULL;
+                               walk_state->num_operands = 0;
+
+                               if (ACPI_FAILURE(status)) {
+                                       return_ACPI_STATUS(status);
+                               }
+                       }
+                       break;
+
 #endif                         /* ACPI_NO_METHOD_EXECUTION */
 
                default:
                        /* All NAMED_COMPLEX opcodes must be handled above */
-                       /* Note: Method objects were already created in Pass 1 */
                        break;
                }
                break;
@@ -974,7 +1130,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
        case AML_CLASS_METHOD_CALL:
 
                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
-                                 "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n",
+                                 "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
                                  walk_state, op, node));
 
                /*
@@ -988,7 +1144,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                                   ACPI_NS_DONT_OPEN_SCOPE, walk_state,
                                   &(new_node));
                if (ACPI_SUCCESS(status)) {
-
                        /*
                         * Make sure that what we found is indeed a method
                         * We didn't search for a method on purpose, to see if the name
@@ -1004,7 +1159,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
                         */
                        op->common.node = new_node;
                } else {
-                       ACPI_REPORT_NSERROR(arg->common.value.string, status);
+                       ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
                }
                break;