diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/dswload.c | 40 | ||||
-rw-r--r-- | drivers/acpi/acpica/dswload2.c | 10 |
2 files changed, 47 insertions, 3 deletions
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 1dd5a9880dab..eaa859a89702 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -434,6 +434,10 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) acpi_object_type object_type; acpi_status status = AE_OK; +#ifdef ACPI_ASL_COMPILER + u8 param_count; +#endif + ACPI_FUNCTION_TRACE(ds_load1_end_op); op = walk_state->op; @@ -514,6 +518,38 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) } } } +#ifdef ACPI_ASL_COMPILER + /* + * For external opcode, get the object type from the argument and + * get the parameter count from the argument's next. + */ + if (acpi_gbl_disasm_flag && + op->common.node && op->common.aml_opcode == AML_EXTERNAL_OP) { + /* + * Note, if this external is not a method + * Op->Common.Value.Arg->Common.Next->Common.Value.Integer == 0 + * Therefore, param_count will be 0. + */ + param_count = + (u8)op->common.value.arg->common.next->common.value.integer; + object_type = (u8)op->common.value.arg->common.value.integer; + op->common.node->flags |= ANOBJ_IS_EXTERNAL; + op->common.node->type = (u8)object_type; + + acpi_dm_create_subobject_for_external((u8)object_type, + &op->common.node, + param_count); + + /* + * Add the external to the external list because we may be + * emitting code based off of the items within the external list. + */ + acpi_dm_add_op_to_external_list(op, op->named.path, + (u8)object_type, param_count, + ACPI_EXT_ORIGIN_FROM_OPCODE | + ACPI_EXT_RESOLVED_REFERENCE); + } +#endif /* * If we are executing a method, do not create any namespace objects @@ -563,7 +599,9 @@ acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state) /* Pop the scope stack (only if loading a table) */ - if (!walk_state->method_node && acpi_ns_opens_scope(object_type)) { + if (!walk_state->method_node && + op->common.aml_opcode != AML_EXTERNAL_OP && + 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)); diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c index ab5d318975f4..aad83ef5a4ec 100644 --- a/drivers/acpi/acpica/dswload2.c +++ b/drivers/acpi/acpica/dswload2.c @@ -313,8 +313,14 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, #ifdef ACPI_ASL_COMPILER /* - * Do not open a scope. This could be an external method - * and open a scope. + * Do not open a scope for AML_EXTERNAL_OP + * acpi_ns_lookup can open a new scope based on the object type + * of this op. AML_EXTERNAL_OP is a declaration rather than a + * definition. In the case that this external is a method object, + * acpi_ns_lookup will open a new scope. However, an AML_EXTERNAL_OP + * associated with the ACPI_TYPE_METHOD is a declaration, rather than + * a definition. Flags is set to avoid opening a scope for any + * AML_EXTERNAL_OP. */ if (walk_state->opcode == AML_EXTERNAL_OP) { flags |= ACPI_NS_DONT_OPEN_SCOPE; |