ACPICA: Add additional module-level code support
This change will execute module-level code that is not at the root of the namespace (under a Device object, etc.). ACPICA BZ 762. http://www.acpica.org/bugzilla/show_bug.cgi?id=762 Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
dc95a270c6
commit
9a884ab64a
|
@ -366,33 +366,49 @@ static void
|
|||
acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
|
||||
struct acpi_evaluate_info *info)
|
||||
{
|
||||
union acpi_operand_object *root_obj;
|
||||
union acpi_operand_object *parent_obj;
|
||||
struct acpi_namespace_node *parent_node;
|
||||
acpi_object_type type;
|
||||
acpi_status status;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ns_exec_module_code);
|
||||
|
||||
/*
|
||||
* Get the parent node. We cheat by using the next_object field
|
||||
* of the method object descriptor.
|
||||
*/
|
||||
parent_node = ACPI_CAST_PTR(struct acpi_namespace_node,
|
||||
method_obj->method.next_object);
|
||||
type = acpi_ns_get_type(parent_node);
|
||||
|
||||
/* Must clear next_object (acpi_ns_attach_object needs the field) */
|
||||
|
||||
method_obj->method.next_object = NULL;
|
||||
|
||||
/* Initialize the evaluation information block */
|
||||
|
||||
ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
|
||||
info->prefix_node = acpi_gbl_root_node;
|
||||
info->prefix_node = parent_node;
|
||||
|
||||
/*
|
||||
* Get the currently attached root object. Add a reference, because the
|
||||
* Get the currently attached parent object. Add a reference, because the
|
||||
* ref count will be decreased when the method object is installed to
|
||||
* the root node.
|
||||
* the parent node.
|
||||
*/
|
||||
root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node);
|
||||
acpi_ut_add_reference(root_obj);
|
||||
parent_obj = acpi_ns_get_attached_object(parent_node);
|
||||
if (parent_obj) {
|
||||
acpi_ut_add_reference(parent_obj);
|
||||
}
|
||||
|
||||
/* Install the method (module-level code) in the root node */
|
||||
/* Install the method (module-level code) in the parent node */
|
||||
|
||||
status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj,
|
||||
status = acpi_ns_attach_object(parent_node, method_obj,
|
||||
ACPI_TYPE_METHOD);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Execute the root node as a control method */
|
||||
/* Execute the parent node as a control method */
|
||||
|
||||
status = acpi_ns_evaluate(info);
|
||||
|
||||
|
@ -401,15 +417,19 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
|
|||
|
||||
/* Detach the temporary method object */
|
||||
|
||||
acpi_ns_detach_object(acpi_gbl_root_node);
|
||||
acpi_ns_detach_object(parent_node);
|
||||
|
||||
/* Restore the original root object */
|
||||
/* Restore the original parent object */
|
||||
|
||||
status =
|
||||
acpi_ns_attach_object(acpi_gbl_root_node, root_obj,
|
||||
ACPI_TYPE_DEVICE);
|
||||
if (parent_obj) {
|
||||
status = acpi_ns_attach_object(parent_node, parent_obj, type);
|
||||
} else {
|
||||
parent_node->type = (u8)type;
|
||||
}
|
||||
|
||||
exit:
|
||||
acpi_ut_remove_reference(root_obj);
|
||||
if (parent_obj) {
|
||||
acpi_ut_remove_reference(parent_obj);
|
||||
}
|
||||
return_VOID;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,8 @@ acpi_ps_complete_final_op(struct acpi_walk_state *walk_state,
|
|||
union acpi_parse_object *op, acpi_status status);
|
||||
|
||||
static void
|
||||
acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
|
||||
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
|
||||
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id);
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
@ -479,11 +480,14 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
|||
*/
|
||||
if (walk_state->pass_number ==
|
||||
ACPI_IMODE_LOAD_PASS1) {
|
||||
acpi_ps_link_module_code(aml_op_start,
|
||||
walk_state->
|
||||
acpi_ps_link_module_code(op->common.
|
||||
parent,
|
||||
aml_op_start,
|
||||
(u32)
|
||||
(walk_state->
|
||||
parser_state.
|
||||
pkg_end -
|
||||
aml_op_start,
|
||||
aml_op_start),
|
||||
walk_state->
|
||||
owner_id);
|
||||
}
|
||||
|
@ -598,7 +602,8 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
|||
*
|
||||
* FUNCTION: acpi_ps_link_module_code
|
||||
*
|
||||
* PARAMETERS: aml_start - Pointer to the AML
|
||||
* PARAMETERS: parent_op - Parent parser op
|
||||
* aml_start - Pointer to the AML
|
||||
* aml_length - Length of executable AML
|
||||
* owner_id - owner_id of module level code
|
||||
*
|
||||
|
@ -611,11 +616,13 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
|
|||
******************************************************************************/
|
||||
|
||||
static void
|
||||
acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
|
||||
acpi_ps_link_module_code(union acpi_parse_object *parent_op,
|
||||
u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
|
||||
{
|
||||
union acpi_operand_object *prev;
|
||||
union acpi_operand_object *next;
|
||||
union acpi_operand_object *method_obj;
|
||||
struct acpi_namespace_node *parent_node;
|
||||
|
||||
/* Get the tail of the list */
|
||||
|
||||
|
@ -639,11 +646,24 @@ acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id)
|
|||
return;
|
||||
}
|
||||
|
||||
if (parent_op->common.node) {
|
||||
parent_node = parent_op->common.node;
|
||||
} else {
|
||||
parent_node = acpi_gbl_root_node;
|
||||
}
|
||||
|
||||
method_obj->method.aml_start = aml_start;
|
||||
method_obj->method.aml_length = aml_length;
|
||||
method_obj->method.owner_id = owner_id;
|
||||
method_obj->method.flags |= AOPOBJ_MODULE_LEVEL;
|
||||
|
||||
/*
|
||||
* Save the parent node in next_object. This is cheating, but we
|
||||
* don't want to expand the method object.
|
||||
*/
|
||||
method_obj->method.next_object =
|
||||
ACPI_CAST_PTR(union acpi_operand_object, parent_node);
|
||||
|
||||
if (!prev) {
|
||||
acpi_gbl_module_code_list = method_obj;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue