forked from luck/tmp_suning_uos_patched
ACPICA: Fixes for Unload and DDBHandles
Implemented support for the use of DDBHandles as an Indexed Reference, as per the ACPI spec. http://www.acpica.org/bugzilla/show_bug.cgi?id=486. Implemented support for UserTerm (Method invocation) for the Unload operator as per the ACPI spec. http://www.acpica.org/bugzilla/show_bug.cgi?id=580 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
parent
a6f4a4511e
commit
bc7a36ab74
@ -895,14 +895,25 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc)
|
|||||||
} else if (obj_desc->reference.object) {
|
} else if (obj_desc->reference.object) {
|
||||||
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
|
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
|
||||||
ACPI_DESC_TYPE_OPERAND) {
|
ACPI_DESC_TYPE_OPERAND) {
|
||||||
acpi_os_printf(" Target: %p [%s]\n",
|
acpi_os_printf(" Target: %p",
|
||||||
obj_desc->reference.object,
|
obj_desc->reference.object);
|
||||||
acpi_ut_get_type_name(((union
|
if (obj_desc->reference.opcode == AML_LOAD_OP) {
|
||||||
acpi_operand_object
|
/*
|
||||||
*)obj_desc->
|
* For DDBHandle reference,
|
||||||
reference.
|
* obj_desc->Reference.Object is the table index
|
||||||
object)->common.
|
*/
|
||||||
type));
|
acpi_os_printf(" [DDBHandle]\n");
|
||||||
|
} else {
|
||||||
|
acpi_os_printf(" [%s]\n",
|
||||||
|
acpi_ut_get_type_name(((union
|
||||||
|
acpi_operand_object
|
||||||
|
*)
|
||||||
|
obj_desc->
|
||||||
|
reference.
|
||||||
|
object)->
|
||||||
|
common.
|
||||||
|
type));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
acpi_os_printf(" Target: %p\n",
|
acpi_os_printf(" Target: %p\n",
|
||||||
obj_desc->reference.object);
|
obj_desc->reference.object);
|
||||||
|
@ -382,10 +382,10 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For reference objects created via the ref_of or Index operators,
|
* For reference objects created via the ref_of, Index, or Load/load_table
|
||||||
* we need to get to the base object (as per the ACPI specification
|
* operators, we need to get to the base object (as per the ACPI
|
||||||
* of the object_type and size_of operators). This means traversing
|
* specification of the object_type and size_of operators). This means
|
||||||
* the list of possibly many nested references.
|
* traversing the list of possibly many nested references.
|
||||||
*/
|
*/
|
||||||
while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
|
while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
|
||||||
switch (obj_desc->reference.opcode) {
|
switch (obj_desc->reference.opcode) {
|
||||||
@ -455,6 +455,11 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AML_LOAD_OP:
|
||||||
|
|
||||||
|
type = ACPI_TYPE_DDB_HANDLE;
|
||||||
|
goto exit;
|
||||||
|
|
||||||
case AML_LOCAL_OP:
|
case AML_LOCAL_OP:
|
||||||
case AML_ARG_OP:
|
case AML_ARG_OP:
|
||||||
|
|
||||||
|
@ -434,11 +434,24 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
|
|||||||
*/
|
*/
|
||||||
obj_desc = *(index_desc->reference.where);
|
obj_desc = *(index_desc->reference.where);
|
||||||
|
|
||||||
status =
|
if (ACPI_GET_OBJECT_TYPE(source_desc) ==
|
||||||
acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc,
|
ACPI_TYPE_LOCAL_REFERENCE
|
||||||
walk_state);
|
&& source_desc->reference.opcode == AML_LOAD_OP) {
|
||||||
if (ACPI_FAILURE(status)) {
|
|
||||||
return_ACPI_STATUS(status);
|
/* This is a DDBHandle, just add a reference to it */
|
||||||
|
|
||||||
|
acpi_ut_add_reference(source_desc);
|
||||||
|
new_desc = source_desc;
|
||||||
|
} else {
|
||||||
|
/* Normal object, copy it */
|
||||||
|
|
||||||
|
status =
|
||||||
|
acpi_ut_copy_iobject_to_iobject(source_desc,
|
||||||
|
&new_desc,
|
||||||
|
walk_state);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
return_ACPI_STATUS(status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj_desc) {
|
if (obj_desc) {
|
||||||
|
@ -235,6 +235,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
|
|||||||
union acpi_parse_object *name_op;
|
union acpi_parse_object *name_op;
|
||||||
union acpi_operand_object *method_desc;
|
union acpi_operand_object *method_desc;
|
||||||
struct acpi_namespace_node *node;
|
struct acpi_namespace_node *node;
|
||||||
|
u8 *start = parser_state->aml;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ps_get_next_namepath);
|
ACPI_FUNCTION_TRACE(ps_get_next_namepath);
|
||||||
|
|
||||||
@ -267,6 +268,16 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state,
|
|||||||
*/
|
*/
|
||||||
if (ACPI_SUCCESS(status) &&
|
if (ACPI_SUCCESS(status) &&
|
||||||
possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
|
possible_method_call && (node->type == ACPI_TYPE_METHOD)) {
|
||||||
|
if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
|
||||||
|
/*
|
||||||
|
* acpi_ps_get_next_namestring has increased the AML pointer,
|
||||||
|
* so we need to restore the saved AML pointer for method call.
|
||||||
|
*/
|
||||||
|
walk_state->parser_state.aml = start;
|
||||||
|
walk_state->arg_count = 1;
|
||||||
|
acpi_ps_init_op(arg, AML_INT_METHODCALL_OP);
|
||||||
|
return_ACPI_STATUS(AE_OK);
|
||||||
|
}
|
||||||
|
|
||||||
/* This name is actually a control method invocation */
|
/* This name is actually a control method invocation */
|
||||||
|
|
||||||
@ -678,9 +689,29 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
|
|||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
status =
|
/* To support super_name arg of Unload */
|
||||||
acpi_ps_get_next_namepath(walk_state, parser_state,
|
|
||||||
arg, 0);
|
if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) {
|
||||||
|
status =
|
||||||
|
acpi_ps_get_next_namepath(walk_state,
|
||||||
|
parser_state, arg,
|
||||||
|
1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the super_name arg of Unload is a method call,
|
||||||
|
* we have restored the AML pointer, just free this Arg
|
||||||
|
*/
|
||||||
|
if (arg->common.aml_opcode ==
|
||||||
|
AML_INT_METHODCALL_OP) {
|
||||||
|
acpi_ps_free_op(arg);
|
||||||
|
arg = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status =
|
||||||
|
acpi_ps_get_next_namepath(walk_state,
|
||||||
|
parser_state, arg,
|
||||||
|
0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Single complex argument, nothing returned */
|
/* Single complex argument, nothing returned */
|
||||||
|
|
||||||
|
@ -709,7 +709,15 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
|
|||||||
/*
|
/*
|
||||||
* We copied the reference object, so we now must add a reference
|
* We copied the reference object, so we now must add a reference
|
||||||
* to the object pointed to by the reference
|
* to the object pointed to by the reference
|
||||||
|
*
|
||||||
|
* DDBHandle reference (from Load/load_table is a special reference,
|
||||||
|
* it's Reference.Object is the table index, so does not need to
|
||||||
|
* increase the reference count
|
||||||
*/
|
*/
|
||||||
|
if (source_desc->reference.opcode == AML_LOAD_OP) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
acpi_ut_add_reference(source_desc->reference.object);
|
acpi_ut_add_reference(source_desc->reference.object);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user