From f0e0da8a6cca44396c7a711e308d58084e881617 Mon Sep 17 00:00:00 2001 From: Dennis Noordsij Date: Fri, 15 Aug 2008 09:37:58 +0800 Subject: ACPICA: Copy dynamically loaded tables to local buffer Previously, dynamically loaded tables were simply mapped, but on some machines this memory is corrupted after suspend. Now copy the table to a local buffer. For OpRegion case, added checksum verify. Use the table length from the table header, not the region length. For Buffer case, use the table length also. http://bugzilla.kernel.org/show_bug.cgi?id=10734 Signed-off-by: Dennis Noordsij Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/executer/exconfig.c | 113 ++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 31 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 8892b9824fa..331a114f42c 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -280,6 +280,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) { union acpi_operand_object *ddb_handle; + struct acpi_table_header *table; struct acpi_table_desc table_desc; u32 table_index; acpi_status status; @@ -294,9 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_REGION: - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", - obj_desc, - acpi_ut_get_object_type_name(obj_desc))); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Load table from Region %p\n", obj_desc)); /* Region must be system_memory (from ACPI spec) */ @@ -316,61 +316,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, } /* - * We will simply map the memory region for the table. However, the - * memory region is technically not guaranteed to remain stable and - * we may eventually have to copy the table to a local buffer. + * Map the table header and get the actual table length. The region + * length is not guaranteed to be the same as the table length. + */ + table = acpi_os_map_memory(obj_desc->region.address, + sizeof(struct acpi_table_header)); + if (!table) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + + /* Must have at least an ACPI table header */ + + if (length < sizeof(struct acpi_table_header)) { + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); + } + + /* + * The memory region is not guaranteed to remain stable and we must + * copy the table to a local buffer. For example, the memory region + * is corrupted after suspend on some machines. Dynamically loaded + * tables are usually small, so this overhead is minimal. */ + + /* Allocate a buffer for the table */ + + table_desc.pointer = ACPI_ALLOCATE(length); + if (!table_desc.pointer) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* Map the entire table and copy it */ + + table = acpi_os_map_memory(obj_desc->region.address, length); + if (!table) { + ACPI_FREE(table_desc.pointer); + return_ACPI_STATUS(AE_NO_MEMORY); + } + + ACPI_MEMCPY(table_desc.pointer, table, length); + acpi_os_unmap_memory(table, length); + table_desc.address = obj_desc->region.address; - table_desc.length = obj_desc->region.length; - table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED; break; case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "Load from Buffer or Field %p %s\n", obj_desc, - acpi_ut_get_object_type_name(obj_desc))); - - length = obj_desc->buffer.length; + "Load table from Buffer or Field %p\n", + obj_desc)); /* Must have at least an ACPI table header */ - if (length < sizeof(struct acpi_table_header)) { + if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) { return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); } - /* Validate checksum here. It won't get validated in tb_add_table */ + /* Get the actual table length from the table header */ - status = - acpi_tb_verify_checksum(ACPI_CAST_PTR - (struct acpi_table_header, - obj_desc->buffer.pointer), length); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + table = + ACPI_CAST_PTR(struct acpi_table_header, + obj_desc->buffer.pointer); + length = table->length; + + /* Table cannot extend beyond the buffer */ + + if (length > obj_desc->buffer.length) { + return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); + } + if (length < sizeof(struct acpi_table_header)) { + return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); } /* - * We need to copy the buffer since the original buffer could be - * changed or deleted in the future + * Copy the table from the buffer because the buffer could be modified + * or even deleted in the future */ table_desc.pointer = ACPI_ALLOCATE(length); if (!table_desc.pointer) { return_ACPI_STATUS(AE_NO_MEMORY); } - ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer, - length); - table_desc.length = length; - table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; + ACPI_MEMCPY(table_desc.pointer, table, length); + table_desc.address = ACPI_TO_INTEGER(table_desc.pointer); break; default: return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } - /* - * Install the new table into the local data structures - */ + /* Validate table checksum (will not get validated in tb_add_table) */ + + status = acpi_tb_verify_checksum(table_desc.pointer, length); + if (ACPI_FAILURE(status)) { + ACPI_FREE(table_desc.pointer); + return_ACPI_STATUS(status); + } + + /* Complete the table descriptor */ + + table_desc.length = length; + table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; + + /* Install the new table into the local data structures */ + status = acpi_tb_add_table(&table_desc, &table_index); if (ACPI_FAILURE(status)) { goto cleanup; @@ -379,7 +430,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, /* * Add the table to the namespace. * - * Note: We load the table objects relative to the root of the namespace. + * Note: Load the table objects relative to the root of the namespace. * This appears to go against the ACPI specification, but we do it for * compatibility with other ACPI implementations. */ @@ -415,7 +466,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, cleanup: if (ACPI_FAILURE(status)) { - /* Delete allocated buffer or mapping */ + /* Delete allocated table buffer */ acpi_tb_delete_table(&table_desc); } -- cgit v1.2.3 From 237a927682a63f02adb542dbdaafe8a81566451d Mon Sep 17 00:00:00 2001 From: Fiodor Suietov Date: Fri, 4 Jul 2008 10:18:34 +0800 Subject: ACPICA: Add check for invalid handle in acpi_get_object_info Return AE_BAD_PARAMETER if input handle is invalid. http://www.acpica.org/bugzilla/show_bug.cgi?id=474 Signed-off-by: Fiodor Suietov Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/namespace/nsxfname.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index a287ed550f5..3cb910ded44 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -253,6 +253,7 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) node = acpi_ns_map_handle_to_node(handle); if (!node) { (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); + status = AE_BAD_PARAMETER; goto cleanup; } -- cgit v1.2.3 From e56f561736e340a4e923b0db65f65dabf5d94823 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 4 Jul 2008 10:48:43 +0800 Subject: ACPICA: Allow same ACPI table to be loaded/unloaded more than once Without this change, a table cannot be loaded again once it has been loaded/unloaded one time. The current mechanism does not unregister a table upon an unload. During a load, if the same table is found, this no longer returns an exception. http://www.acpica.org/bugzilla/show_bug.cgi?id=722 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/tables/tbinstal.c | 49 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index b22185f55a1..905dc38ab23 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -145,6 +145,8 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) } } + /* Check for a table match on the entire table length */ + length = ACPI_MIN(table_desc->length, acpi_gbl_root_table_list.tables[i].length); if (ACPI_MEMCMP(table_desc->pointer, @@ -153,17 +155,49 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) continue; } - /* Table is already registered */ - + /* + * Note: the current mechanism does not unregister a table if it is + * dynamically unloaded. The related namespace entries are deleted, + * but the table remains in the root table list. + * + * The assumption here is that the number of different tables that + * will be loaded is actually small, and there is minimal overhead + * in just keeping the table in case it is needed again. + * + * If this assumption changes in the future (perhaps on large + * machines with many table load/unload operations), tables will + * need to be unregistered when they are unloaded, and slots in the + * root table list should be reused when empty. + */ + + /* + * Table is already registered. + * We can delete the table that was passed as a parameter. + */ acpi_tb_delete_table(table_desc); *table_index = i; - status = AE_ALREADY_EXISTS; - goto release; + + if (acpi_gbl_root_table_list.tables[i]. + flags & ACPI_TABLE_IS_LOADED) { + + /* Table is still loaded, this is an error */ + + status = AE_ALREADY_EXISTS; + goto release; + } else { + /* Table was unloaded, allow it to be reloaded */ + + table_desc->pointer = + acpi_gbl_root_table_list.tables[i].pointer; + table_desc->address = + acpi_gbl_root_table_list.tables[i].address; + status = AE_OK; + goto print_header; + } } - /* - * Add the table to the global table list - */ + /* Add the table to the global root table list */ + status = acpi_tb_store_table(table_desc->address, table_desc->pointer, table_desc->length, table_desc->flags, table_index); @@ -171,6 +205,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) goto release; } + print_header: acpi_tb_print_table_header(table_desc->address, table_desc->pointer); release: -- cgit v1.2.3 From a6f30539f31a8129288b0e5640d3eb1174848c15 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 4 Jul 2008 10:57:51 +0800 Subject: ACPICA: Fix table compare code, length then data Split the ACPI table compare. First check that the lengths match exactly. Then compare the data. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/tables/tbinstal.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 905dc38ab23..18747ce8dd2 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -110,7 +110,6 @@ acpi_status acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) { u32 i; - u32 length; acpi_status status = AE_OK; ACPI_FUNCTION_TRACE(tb_add_table); @@ -145,13 +144,18 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) } } - /* Check for a table match on the entire table length */ + /* + * Check for a table match on the entire table length, + * not just the header. + */ + if (table_desc->length != + acpi_gbl_root_table_list.tables[i].length) { + continue; + } - length = ACPI_MIN(table_desc->length, - acpi_gbl_root_table_list.tables[i].length); if (ACPI_MEMCMP(table_desc->pointer, acpi_gbl_root_table_list.tables[i].pointer, - length)) { + acpi_gbl_root_table_list.tables[i].length)) { continue; } -- cgit v1.2.3 From b417d40b9a850f12f69aa9d785d2af39c9463bb8 Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Mon, 4 Aug 2008 10:30:09 +0800 Subject: ACPICA: Return status from global init function Return status from acpi_ut_init_globals. This is used by both the kernel subsystem and the utilities such as iASL compiler. The function could possibly fail when the caches are initialized. Yang Yi. Signed-off-by: Yi Yang Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/utilities/utglobal.c | 8 ++++---- drivers/acpi/utilities/utxface.c | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index a6e71b801d2..248eefc369f 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -677,14 +677,14 @@ u8 acpi_ut_valid_object_type(acpi_object_type type) * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * * DESCRIPTION: Init library globals. All globals that require specific * initialization should be initialized here! * ******************************************************************************/ -void acpi_ut_init_globals(void) +acpi_status acpi_ut_init_globals(void) { acpi_status status; u32 i; @@ -695,7 +695,7 @@ void acpi_ut_init_globals(void) status = acpi_ut_create_caches(); if (ACPI_FAILURE(status)) { - return; + return_ACPI_STATUS(status); } /* Mutex locked flags */ @@ -772,7 +772,7 @@ void acpi_ut_init_globals(void) acpi_gbl_display_final_mem_stats = FALSE; #endif - return_VOID; + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_dbg_level) diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index f8bdadf3c32..c198a4d4058 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -81,7 +81,12 @@ acpi_status __init acpi_initialize_subsystem(void) /* Initialize all globals used by the subsystem */ - acpi_ut_init_globals(); + status = acpi_ut_init_globals(); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "During initialization of globals")); + return_ACPI_STATUS(status); + } /* Create the default mutex objects */ -- cgit v1.2.3 From bbc241340681557a16982f4d1840f00963bc05b4 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 4 Aug 2008 13:22:10 +0800 Subject: ACPICA: Add function to dereference returned reference objects Examines the return object from a call to acpi_evaluate_object. Any Index or RefOf references are automatically dereferenced in an attempt to return something useful (these reference types cannot be converted into an external ACPI_OBJECT.) Lin Ming, Bob Moore. http://bugzilla.kernel.org/show_bug.cgi?id=11105 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/namespace/nsxfeval.c | 79 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 38be5865d95..f3cc3762453 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -45,9 +45,14 @@ #include #include #include +#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfeval") + +/* Local prototypes */ +static void acpi_ns_resolve_references(struct acpi_evaluate_info *info); + #ifdef ACPI_FUTURE_USAGE /******************************************************************************* * @@ -69,6 +74,7 @@ ACPI_MODULE_NAME("nsxfeval") * be valid (non-null) * ******************************************************************************/ + acpi_status acpi_evaluate_object_typed(acpi_handle handle, acpi_string pathname, @@ -283,6 +289,10 @@ acpi_evaluate_object(acpi_handle handle, if (ACPI_SUCCESS(status)) { + /* Dereference Index and ref_of references */ + + acpi_ns_resolve_references(info); + /* Get the size of the returned object */ status = @@ -350,6 +360,74 @@ acpi_evaluate_object(acpi_handle handle, ACPI_EXPORT_SYMBOL(acpi_evaluate_object) +/******************************************************************************* + * + * FUNCTION: acpi_ns_resolve_references + * + * PARAMETERS: Info - Evaluation info block + * + * RETURN: Info->return_object is replaced with the dereferenced object + * + * DESCRIPTION: Dereference certain reference objects. Called before an + * internal return object is converted to an external union acpi_object. + * + * Performs an automatic dereference of Index and ref_of reference objects. + * These reference objects are not supported by the union acpi_object, so this is a + * last resort effort to return something useful. Also, provides compatibility + * with other ACPI implementations. + * + * NOTE: does not handle references within returned package objects or nested + * references, but this support could be added later if found to be necessary. + * + ******************************************************************************/ +static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) +{ + union acpi_operand_object *obj_desc = NULL; + struct acpi_namespace_node *node; + + /* We are interested in reference objects only */ + + if (ACPI_GET_OBJECT_TYPE(info->return_object) != + ACPI_TYPE_LOCAL_REFERENCE) { + return; + } + + /* + * Two types of references are supported - those created by Index and + * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted + * to an union acpi_object, so it is not dereferenced here. A ddb_handle + * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to + * an union acpi_object. + */ + switch (info->return_object->reference.opcode) { + case AML_INDEX_OP: + + obj_desc = *(info->return_object->reference.where); + break; + + case AML_REF_OF_OP: + + node = info->return_object->reference.object; + if (node) { + obj_desc = node->object; + } + break; + + default: + return; + } + + /* Replace the existing reference object */ + + if (obj_desc) { + acpi_ut_add_reference(obj_desc); + acpi_ut_remove_reference(info->return_object); + info->return_object = obj_desc; + } + + return; +} + /******************************************************************************* * * FUNCTION: acpi_walk_namespace @@ -379,6 +457,7 @@ ACPI_EXPORT_SYMBOL(acpi_evaluate_object) * function, etc. * ******************************************************************************/ + acpi_status acpi_walk_namespace(acpi_object_type type, acpi_handle start_object, -- cgit v1.2.3 From b7906e324532c1616546f6d4a1306894ba7c0a3d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 15 Aug 2008 04:32:59 +0200 Subject: ACPICA: Fix warning for 64-bit build Fixes warning from exconfig.c on 64-bit build. AK: This actually was fixed earlier in Linux, this just syncs with AK: the version of the fix that went into the ACPCA codebase Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/executer/exconfig.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 331a114f42c..4c512c2990e 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -96,8 +96,7 @@ acpi_ex_add_table(u32 table_index, /* Install the new table into the local data structures */ - obj_desc->reference.object = ACPI_CAST_PTR(void, - (unsigned long)table_index); + obj_desc->reference.object = ACPI_TO_POINTER(table_index); /* Add the table to the namespace */ -- cgit v1.2.3 From 0a1fbf2db0d275f0f8160bb9c3e51c4df5bafdc2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 4 Jul 2008 10:53:58 +0800 Subject: ACPICA: Return method arg count from acpi_get_object_info Also update the debugger so that the correct number of arguments is passed to the method. Prevents a warning message from the debugger. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/namespace/nsxfname.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 3cb910ded44..5efa4e7ddb0 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -265,6 +265,10 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) info->name = node->name.integer; info->valid = 0; + if (node->type == ACPI_TYPE_METHOD) { + info->param_count = node->object->method.param_count; + } + status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; -- cgit v1.2.3 From f02a99ac66748f8b62477c86f6df04d3ec6169fd Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 4 Aug 2008 10:40:09 +0800 Subject: ACPICA: Add function to decode reference obj types to strings Created for improved error messages. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/utilities/utglobal.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 248eefc369f..bcace577183 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -45,6 +45,7 @@ #include #include +#include ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) #define _COMPONENT ACPI_UTILITIES @@ -575,6 +576,41 @@ char *acpi_ut_get_descriptor_name(void *object) } +/******************************************************************************* + * + * FUNCTION: acpi_ut_get_reference_name + * + * PARAMETERS: Object - An ACPI reference object + * + * RETURN: Pointer to a string + * + * DESCRIPTION: Decode a reference object sub-type to a string. + * + ******************************************************************************/ + +/* Printable names of reference object sub-types */ + +const char *acpi_ut_get_reference_name(union acpi_operand_object *object) +{ + + switch (object->reference.opcode) { + case AML_INT_NAMEPATH_OP: + return "Name"; + + case AML_LOAD_OP: + return "DDB-Handle"; + + case AML_REF_OF_OP: + return "RefOf"; + + case AML_INDEX_OP: + return "Index"; + + default: + return "Unknown"; + } +} + #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) /* * Strings and procedures used for debug only -- cgit v1.2.3 From c2de3a49454cdc9ca42bbd5d742913421d049f59 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 4 Aug 2008 10:41:29 +0800 Subject: ACPICA: Improve object conversion error messages Better error messages during object conversion from internal to the external ACPI_OBJECT. Used for external calls to acpi_evaluate_object. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- drivers/acpi/utilities/utobject.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 916eff399eb..924d05af94d 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -503,7 +503,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, * required eventually. */ ACPI_ERROR((AE_INFO, - "Unsupported Reference opcode=%X in object %p", + "Cannot convert to external object - " + "unsupported Reference type [%s] %X in object %p", + acpi_ut_get_reference_name(internal_object), internal_object->reference.opcode, internal_object)); status = AE_TYPE; @@ -513,7 +515,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, default: - ACPI_ERROR((AE_INFO, "Unsupported type=%X in object %p", + ACPI_ERROR((AE_INFO, "Cannot convert to external object - " + "unsupported type [%s] %X in object %p", + acpi_ut_get_object_type_name(internal_object), ACPI_GET_OBJECT_TYPE(internal_object), internal_object)); status = AE_TYPE; -- cgit v1.2.3 From 8bd108d14604d9c95000751e6c6ecbd11ea6ed40 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 25 Sep 2008 21:40:30 +0400 Subject: ACPICA: add preemption point after each opcode parse Reference: http://marc.info/?l=linux-acpi&m=122236382701062&w=2 Signed-off-by: Alexey Starikovskiy Tested-by: Sitsofe Wheeler Signed-off-by: Len Brown --- drivers/acpi/parser/psloop.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c index c06238e55d9..4647039a0d8 100644 --- a/drivers/acpi/parser/psloop.c +++ b/drivers/acpi/parser/psloop.c @@ -719,6 +719,8 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state, *op = NULL; } + ACPI_PREEMPTION_POINT(); + return_ACPI_STATUS(AE_OK); } -- cgit v1.2.3 From 55ac9a018f83e4f42f3c6ce98a8dbda73b985935 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sun, 28 Sep 2008 14:51:56 +0800 Subject: ACPI: replace ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ...) with printk ACPI_DB_ERROR and ACPI_DB_WARN were removed from ACPICA core. So replace ACPI_DEBUG_PRINT((ACPI_DB_ERROR, ...) with printk(KERN_ERR PREFIX ...) and ACPI_DEBUG_PRINT((ACPI_DB_WARN, ...) with printk(KERN_WARNING PREFIX ...) We do not use ACPI_ERROR/ACPI_WARNING since they're not exported, see ------------------------------------------------------------- commit 6468463abd7051fcc29f3ee7c931f9bbbb26f5a4 Author: Len Brown Date: Mon Jun 26 23:41:38 2006 -0400 ACPI: un-export ACPI_ERROR() -- use printk(KERN_ERR...) Signed-off-by: Len Brown ------------------------------------------------------------- Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpi_memhotplug.c | 4 ++-- drivers/acpi/cm_sbs.c | 8 ++++---- drivers/acpi/fan.c | 4 ++-- drivers/acpi/osl.c | 4 ++-- drivers/acpi/processor_perflib.c | 10 +++++----- drivers/acpi/processor_throttling.c | 10 +++++----- drivers/acpi/scan.c | 10 +++++----- drivers/acpi/system.c | 4 ++-- drivers/acpi/thermal.c | 4 ++-- drivers/acpi/video.c | 12 ++++++------ 10 files changed, 35 insertions(+), 35 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 5f1127ad5a9..bbad9b6c2c8 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -454,8 +454,8 @@ static int acpi_memory_device_start (struct acpi_device *device) /* call add_memory func */ result = acpi_memory_enable_device(mem_device); if (result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error in acpi_memory_enable_device\n")); + printk(KERN_ERR PREFIX + "Error in acpi_memory_enable_device\n"); } return result; } diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c index f9db4f444bd..4441e84b28a 100644 --- a/drivers/acpi/cm_sbs.c +++ b/drivers/acpi/cm_sbs.c @@ -52,8 +52,8 @@ struct proc_dir_entry *acpi_lock_ac_dir(void) if (acpi_ac_dir) { lock_ac_dir_cnt++; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Cannot create %s\n", ACPI_AC_CLASS)); + printk(KERN_ERR PREFIX + "Cannot create %s\n", ACPI_AC_CLASS); } mutex_unlock(&cm_sbs_mutex); return acpi_ac_dir; @@ -83,8 +83,8 @@ struct proc_dir_entry *acpi_lock_battery_dir(void) if (acpi_battery_dir) { lock_battery_dir_cnt++; } else { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Cannot create %s\n", ACPI_BATTERY_CLASS)); + printk(KERN_ERR PREFIX + "Cannot create %s\n", ACPI_BATTERY_CLASS); } mutex_unlock(&cm_sbs_mutex); return acpi_battery_dir; diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 2655bc1b4ee..dfc0486ffaf 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -327,8 +327,8 @@ static int acpi_fan_resume(struct acpi_device *device) result = acpi_bus_get_power(device->handle, &power_state); if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading fan power state\n")); + printk(KERN_ERR PREFIX + "Error reading fan power state\n"); return result; } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 235a1386888..1420a9f69e5 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -729,8 +729,8 @@ acpi_status acpi_os_execute(acpi_execute_type type, INIT_WORK(&dpc->work, acpi_os_execute_deferred); queue = (type == OSL_NOTIFY_HANDLER) ? kacpi_notify_wq : kacpid_wq; if (!queue_work(queue, &dpc->work)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Call to queue_work() failed.\n")); + printk(KERN_ERR PREFIX + "Call to queue_work() failed.\n"); status = AE_ERROR; kfree(dpc); } diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 80c251ec6d2..e5c457b45f2 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -524,13 +524,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) psd = buffer.pointer; if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); + printk(KERN_ERR PREFIX "Invalid _PSD data\n"); result = -EFAULT; goto end; } if (psd->package.count != 1) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); + printk(KERN_ERR PREFIX "Invalid _PSD data\n"); result = -EFAULT; goto end; } @@ -543,19 +543,19 @@ static int acpi_processor_get_psd(struct acpi_processor *pr) status = acpi_extract_package(&(psd->package.elements[0]), &format, &state); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _PSD data\n")); + printk(KERN_ERR PREFIX "Invalid _PSD data\n"); result = -EFAULT; goto end; } if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:num_entries\n")); + printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n"); result = -EFAULT; goto end; } if (pdomain->revision != ACPI_PSD_REV0_REVISION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _PSD:revision\n")); + printk(KERN_ERR PREFIX "Unknown _PSD:revision\n"); result = -EFAULT; goto end; } diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index a56fc6c4394..e89a25824f2 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -528,13 +528,13 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) tsd = buffer.pointer; if (!tsd || (tsd->type != ACPI_TYPE_PACKAGE)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); + printk(KERN_ERR PREFIX "Invalid _TSD data\n"); result = -EFAULT; goto end; } if (tsd->package.count != 1) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); + printk(KERN_ERR PREFIX "Invalid _TSD data\n"); result = -EFAULT; goto end; } @@ -547,19 +547,19 @@ static int acpi_processor_get_tsd(struct acpi_processor *pr) status = acpi_extract_package(&(tsd->package.elements[0]), &format, &state); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid _TSD data\n")); + printk(KERN_ERR PREFIX "Invalid _TSD data\n"); result = -EFAULT; goto end; } if (pdomain->num_entries != ACPI_TSD_REV0_ENTRIES) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:num_entries\n")); + printk(KERN_ERR PREFIX "Unknown _TSD:num_entries\n"); result = -EFAULT; goto end; } if (pdomain->revision != ACPI_TSD_REV0_REVISION) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unknown _TSD:revision\n")); + printk(KERN_ERR PREFIX "Unknown _TSD:revision\n"); result = -EFAULT; goto end; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f6f52c1a2ab..81d6095468f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context) if (acpi_bus_trim(device, 1)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Removing device failed\n")); + printk(KERN_ERR PREFIX + "Removing device failed\n"); return -1; } /* power off device */ status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Power-off device failed\n")); + printk(KERN_WARNING PREFIX + "Power-off device failed\n"); if (device->flags.lockable) { arg_list.count = 1; @@ -477,7 +477,7 @@ static int acpi_device_register(struct acpi_device *device, result = acpi_device_setup_files(device); if(result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id)); + printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); device->removal_type = ACPI_BUS_REMOVAL_NORMAL; return 0; diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index 91dec448b3e..3eefd6d029f 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -387,8 +387,8 @@ static ssize_t counter_set(struct kobject *kobj, goto end; if (!(all_counters[index].flags & ACPI_EVENT_VALID)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Can not change Invalid GPE/Fixed Event status\n")); + printk(KERN_WARNING PREFIX + "Can not change Invalid GPE/Fixed Event status\n"); return -EINVAL; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 912703691d3..263ec08a901 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1213,8 +1213,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) acpi_bus_private_data_handler, tz->thermal_zone); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error attaching device data\n")); + printk(KERN_ERR PREFIX + "Error attaching device data\n"); return -ENODEV; } diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index e8a51a1700f..4ae39ee8cde 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1530,8 +1530,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, acpi_video_device_notify, data); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); + printk(KERN_ERR PREFIX + "Error installing notify handler\n"); if(data->brightness) kfree(data->brightness->levels); kfree(data->brightness); @@ -1745,8 +1745,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, status = acpi_video_bus_get_one_device(dev, video); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, - "Cant attach device")); + printk(KERN_WARNING PREFIX + "Cant attach device"); continue; } } @@ -2003,8 +2003,8 @@ static int acpi_video_bus_add(struct acpi_device *device) ACPI_DEVICE_NOTIFY, acpi_video_bus_notify, video); if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error installing notify handler\n")); + printk(KERN_ERR PREFIX + "Error installing notify handler\n"); error = -ENODEV; goto err_stop_video; } -- cgit v1.2.3 From 23d3e055beb12db2a3b91dfeee474c4d5ecc13b9 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sun, 28 Sep 2008 15:00:47 +0800 Subject: ACPICA: Remove obsolete debug levels (WARN and ERROR) Removed ACPI_DB_WARN and ACPI_DB_ERROR. These debug levels were made obsolete by the ACPI_WARNING and ACPI_ERROR/ACPI_EXCEPTION interfaces. Also added ACPI_DB_EVENTS to correspond with the existing ACPI_LV_EVENTS. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/debug.c | 2 -- drivers/acpi/executer/exstore.c | 2 +- drivers/acpi/namespace/nssearch.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c index 6df564f4ca6..abf36b4b1d1 100644 --- a/drivers/acpi/debug.c +++ b/drivers/acpi/debug.c @@ -47,8 +47,6 @@ static const struct acpi_dlayer acpi_debug_layers[] = { }; static const struct acpi_dlevel acpi_debug_levels[] = { - ACPI_DEBUG_INIT(ACPI_LV_ERROR), - ACPI_DEBUG_INIT(ACPI_LV_WARN), ACPI_DEBUG_INIT(ACPI_LV_INIT), ACPI_DEBUG_INIT(ACPI_LV_DEBUG_OBJECT), ACPI_DEBUG_INIT(ACPI_LV_INFO), diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 38b55e35249..09e96846d15 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -403,7 +403,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", ref_desc->reference.opcode)); - ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_ERROR); + ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO); status = AE_AML_INTERNAL; break; diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 8399276cba1..a9a80bf811b 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -331,7 +331,7 @@ acpi_ns_search_and_enter(u32 target_name, "Found bad character(s) in name, repaired: [%4.4s]\n", ACPI_CAST_PTR(char, &target_name))); } else { - ACPI_DEBUG_PRINT((ACPI_DB_WARN, + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found bad character(s) in name, repaired: [%4.4s]\n", ACPI_CAST_PTR(char, &target_name))); } -- cgit v1.2.3 From b68bacf225e5e9758472e99505d76125ced3ea88 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 10:29:31 +0800 Subject: ACPICA: Disallow evaluation of named object types with no value Return AE_TYPE for objects that have no value and therefore evaluation is undefined: Device, Event, Mutex, Region, Thermal, and Scope. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/namespace/nseval.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index d369164e00b..0a1ae670a84 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -195,7 +195,28 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) } else { /* * 2) Object is not a method, return its current value + * + * Disallow certain object types. For these, "evaluation" is undefined. */ + switch (info->resolved_node->type) { + case ACPI_TYPE_DEVICE: + case ACPI_TYPE_EVENT: + case ACPI_TYPE_MUTEX: + case ACPI_TYPE_REGION: + case ACPI_TYPE_THERMAL: + case ACPI_TYPE_LOCAL_SCOPE: + + ACPI_ERROR((AE_INFO, + "[%4.4s] Evaluation of object type [%s] is not supported", + info->resolved_node->name.ascii, + acpi_ut_get_type_name(info->resolved_node-> + type))); + + return_ACPI_STATUS(AE_TYPE); + + default: + break; + } /* * Objects require additional resolution steps (e.g., the Node may be -- cgit v1.2.3 From 93851b4d13de48753eaae76ed190eef7355e2c19 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 10:38:07 +0800 Subject: ACPICA: Reduce error to warning for incorrect method arg count Previously aborted with error if too few arguments were passed to a control method via the external ACPICA interface. Now issue a warning instead and continue. Handles the case where the method inadvertently declares too many arguments, but does not actually use the extra ones. Applies mainly to the predefined methods. http://bugzilla.kernel.org/show_bug.cgi?id=11032 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/namespace/nseval.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 0a1ae670a84..42dae12f2ef 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -148,21 +148,22 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) info->param_count++; } - /* Error if too few arguments were passed in */ + /* + * Warning if too few or too many arguments have been passed by the + * caller. We don't want to abort here with an error because an + * incorrect number of arguments may not cause the method to fail. + * However, the method will fail if there are too few arguments passed + * and the method attempts to use one of the missing ones. + */ if (info->param_count < info->obj_desc->method.param_count) { - ACPI_ERROR((AE_INFO, + ACPI_WARNING((AE_INFO, "Insufficient arguments - " "method [%4.4s] needs %d, found %d", acpi_ut_get_node_name(info->resolved_node), info->obj_desc->method.param_count, info->param_count)); - return_ACPI_STATUS(AE_MISSING_ARGUMENTS); - } - - /* Just a warning if too many arguments */ - - else if (info->param_count > + } else if (info->param_count > info->obj_desc->method.param_count) { ACPI_WARNING((AE_INFO, "Excess arguments - " -- cgit v1.2.3 From 57e664cfd968ec8e4b0bfd80a5e8f903307e598b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 10:40:39 +0800 Subject: ACPICA: Update for Reference ACPI_OPERAND_OBJECT 1) Add new field for use by DdbHandle (Value) 2) Use ACPI_CAST_INDIRECT_PTR to eliminate strict type warnings 3) Cleanup debug output Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsobject.c | 16 ++++++++++------ drivers/acpi/executer/exconfig.c | 6 +++--- drivers/acpi/executer/exdump.c | 29 ++++++++++++++--------------- drivers/acpi/executer/exstore.c | 4 ++-- 4 files changed, 29 insertions(+), 26 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 0f280589921..09af39fff1a 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -741,10 +741,12 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, obj_desc-> reference.offset, walk_state, + ACPI_CAST_INDIRECT_PTR (struct - acpi_namespace_node - **)&obj_desc-> - reference.object); + acpi_namespace_node, + &obj_desc-> + reference. + object)); #endif break; @@ -760,10 +762,12 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, obj_desc-> reference.offset, walk_state, + ACPI_CAST_INDIRECT_PTR (struct - acpi_namespace_node - **)&obj_desc-> - reference.object); + acpi_namespace_node, + &obj_desc-> + reference. + object)); #endif break; diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 4c512c2990e..5f2b1ebf70a 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -96,7 +96,7 @@ acpi_ex_add_table(u32 table_index, /* Install the new table into the local data structures */ - obj_desc->reference.object = ACPI_TO_POINTER(table_index); + obj_desc->reference.value = table_index; /* Add the table to the namespace */ @@ -505,9 +505,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */ + /* Get the table index from the ddb_handle */ - table_index = (u32) (acpi_size) table_desc->reference.object; + table_index = table_desc->reference.value; /* Invoke table handler if present */ diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 2be2e2bf95b..7d4123256cf 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -214,10 +214,11 @@ static struct acpi_exdump_info acpi_ex_dump_index_field[5] = { {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(index_field.data_obj), "Data Object"} }; -static struct acpi_exdump_info acpi_ex_dump_reference[7] = { +static struct acpi_exdump_info acpi_ex_dump_reference[8] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"}, + {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.where), "Where"}, @@ -497,24 +498,24 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) switch (obj_desc->reference.opcode) { case AML_DEBUG_OP: - acpi_os_printf("Reference: Debug\n"); + acpi_os_printf("Reference: [Debug]\n"); break; case AML_INDEX_OP: - acpi_os_printf("Reference: Index %p\n", + acpi_os_printf("Reference: [Index] %p\n", obj_desc->reference.object); break; case AML_LOAD_OP: - acpi_os_printf("Reference: [DdbHandle] TableIndex %p\n", - obj_desc->reference.object); + acpi_os_printf("Reference: [DdbHandle] TableIndex %X\n", + obj_desc->reference.value); break; case AML_REF_OF_OP: - acpi_os_printf("Reference: (RefOf) %p [%s]\n", + acpi_os_printf("Reference: [RefOf] %p [%s]\n", obj_desc->reference.object, acpi_ut_get_type_name(((union acpi_operand_object @@ -526,7 +527,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case AML_ARG_OP: - acpi_os_printf("Reference: Arg%d", + acpi_os_printf("Reference: [Arg%d]", obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { @@ -544,7 +545,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case AML_LOCAL_OP: - acpi_os_printf("Reference: Local%d", + acpi_os_printf("Reference: [Local%d]", obj_desc->reference.offset); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { @@ -562,7 +563,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) case AML_INT_NAMEPATH_OP: - acpi_os_printf("Reference: Namepath %X [%4.4s]\n", + acpi_os_printf("Reference: [Namepath] %X [%4.4s]\n", obj_desc->reference.node->name.integer, obj_desc->reference.node->name.ascii); break; @@ -883,13 +884,11 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) acpi_os_printf(" Target: %p", obj_desc->reference.object); if (obj_desc->reference.opcode == AML_LOAD_OP) { - /* - * For DDBHandle reference, - * obj_desc->Reference.Object is the table index - */ - acpi_os_printf(" [DDBHandle]\n"); + acpi_os_printf(" [DDBHandle] Table Index: %X\n", + obj_desc->reference.value); } else { - acpi_os_printf(" [%s]\n", + acpi_os_printf(" Target: %p [%s]\n", + obj_desc->reference.object, acpi_ut_get_type_name(((union acpi_operand_object *) diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 09e96846d15..20b4893e06e 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -193,8 +193,8 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, - " Table OwnerId %p\n", - source_desc->reference.object)); + " Table Index %X\n", + source_desc->reference.value)); break; } -- cgit v1.2.3 From 2425a0967f29b196fad5d4f726c9502679284656 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 10:42:02 +0800 Subject: ACPICA: Update comments - no functional changes Some formatting and spelling fixes. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/executer/exconvrt.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 261d97516d9..890378e789a 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -57,7 +57,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, * * FUNCTION: acpi_ex_convert_to_integer * - * PARAMETERS: obj_desc - Object to be converted. Must be an + * PARAMETERS: obj_desc - Object to be converted. Must be an * Integer, Buffer, or String * result_desc - Where the new Integer object is returned * Flags - Used for string conversion @@ -103,7 +103,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, } /* - * Convert the buffer/string to an integer. Note that both buffers and + * Convert the buffer/string to an integer. Note that both buffers and * strings are treated as raw data - we don't convert ascii to hex for * strings. * @@ -120,7 +120,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, /* * Convert string to an integer - for most cases, the string must be - * hexadecimal as per the ACPI specification. The only exception (as + * hexadecimal as per the ACPI specification. The only exception (as * of ACPI 3.0) is that the to_integer() operator allows both decimal * and hexadecimal strings (hex prefixed with "0x"). */ @@ -159,6 +159,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, break; default: + /* No other types can get here */ break; } @@ -185,7 +186,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc, * * FUNCTION: acpi_ex_convert_to_buffer * - * PARAMETERS: obj_desc - Object to be converted. Must be an + * PARAMETERS: obj_desc - Object to be converted. Must be an * Integer, Buffer, or String * result_desc - Where the new buffer object is returned * @@ -365,7 +366,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, } /* - * Since leading zeros are supressed, we must check for the case where + * Since leading zeros are suppressed, we must check for the case where * the integer equals 0 * * Finally, null terminate the string and return the length @@ -383,7 +384,7 @@ acpi_ex_convert_to_ascii(acpi_integer integer, * * FUNCTION: acpi_ex_convert_to_string * - * PARAMETERS: obj_desc - Object to be converted. Must be an + * PARAMETERS: obj_desc - Object to be converted. Must be an * Integer, Buffer, or String * result_desc - Where the string object is returned * Type - String flags (base and conversion type) @@ -472,7 +473,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, base = 10; /* - * Calculate the final string length. Individual string values + * Calculate the final string length. Individual string values * are variable length (include separator for each) */ for (i = 0; i < obj_desc->buffer.length; i++) { @@ -617,7 +618,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, case ACPI_TYPE_LOCAL_BANK_FIELD: case ACPI_TYPE_LOCAL_INDEX_FIELD: /* - * These types require an Integer operand. We can convert + * These types require an Integer operand. We can convert * a Buffer or a String to an Integer if necessary. */ status = @@ -627,7 +628,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, case ACPI_TYPE_STRING: /* - * The operand must be a String. We can convert an + * The operand must be a String. We can convert an * Integer or Buffer if necessary */ status = @@ -637,7 +638,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type, case ACPI_TYPE_BUFFER: /* - * The operand must be a Buffer. We can convert an + * The operand must be a Buffer. We can convert an * Integer or String if necessary */ status = -- cgit v1.2.3 From 1044f1f65b7df2aae979e397904c4985eeb99ba2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 11:08:41 +0800 Subject: ACPICA: Cleanup for internal Reference Object Fix some sloppiness in the Reference object. No longer use AML opcodes to differentiate the types, introduce new reference Class. Cleanup the debug output code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsmthdat.c | 83 ++++++++++++++++++++------------------ drivers/acpi/dispatcher/dsobject.c | 56 +++++++++++++++---------- drivers/acpi/dispatcher/dsopcode.c | 2 +- drivers/acpi/dispatcher/dswexec.c | 8 ++-- drivers/acpi/executer/exconfig.c | 3 +- drivers/acpi/executer/exdump.c | 74 ++++++++++++++++----------------- drivers/acpi/executer/exmisc.c | 14 +++---- drivers/acpi/executer/exoparg1.c | 26 ++++++------ drivers/acpi/executer/exoparg2.c | 4 +- drivers/acpi/executer/exresnte.c | 16 +++----- drivers/acpi/executer/exresolv.c | 60 +++++++++++++-------------- drivers/acpi/executer/exresop.c | 50 ++++++++++------------- drivers/acpi/executer/exstore.c | 57 +++++++++++++------------- drivers/acpi/executer/exstoren.c | 3 +- drivers/acpi/namespace/nsdump.c | 5 +-- drivers/acpi/namespace/nsxfeval.c | 7 ++-- drivers/acpi/resources/rscalc.c | 5 +-- drivers/acpi/resources/rscreate.c | 10 ++--- drivers/acpi/utilities/utcopy.c | 29 +++++++------ drivers/acpi/utilities/utdelete.c | 5 +-- drivers/acpi/utilities/utglobal.c | 35 +++++++++------- drivers/acpi/utilities/utobject.c | 9 ++--- 22 files changed, 280 insertions(+), 281 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index 13c43eac35d..d03f81bd1bc 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c @@ -43,7 +43,6 @@ #include #include -#include #include #include @@ -52,11 +51,11 @@ ACPI_MODULE_NAME("dsmthdat") /* Local prototypes */ static void -acpi_ds_method_data_delete_value(u16 opcode, +acpi_ds_method_data_delete_value(u8 type, u32 index, struct acpi_walk_state *walk_state); static acpi_status -acpi_ds_method_data_set_value(u16 opcode, +acpi_ds_method_data_set_value(u8 type, u32 index, union acpi_operand_object *object, struct acpi_walk_state *walk_state); @@ -216,7 +215,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, * Store the argument in the method/walk descriptor. * Do not copy the arg in order to implement call by reference */ - status = acpi_ds_method_data_set_value(AML_ARG_OP, index, + status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index, params[index], walk_state); if (ACPI_FAILURE(status)) { @@ -234,7 +233,8 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, * * FUNCTION: acpi_ds_method_data_get_node * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP + * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or + * ACPI_REFCLASS_ARG * Index - Which Local or Arg whose type to get * walk_state - Current walk state object * Node - Where the node is returned. @@ -246,7 +246,7 @@ acpi_ds_method_data_init_args(union acpi_operand_object **params, ******************************************************************************/ acpi_status -acpi_ds_method_data_get_node(u16 opcode, +acpi_ds_method_data_get_node(u8 type, u32 index, struct acpi_walk_state *walk_state, struct acpi_namespace_node **node) @@ -256,8 +256,8 @@ acpi_ds_method_data_get_node(u16 opcode, /* * Method Locals and Arguments are supported */ - switch (opcode) { - case AML_LOCAL_OP: + switch (type) { + case ACPI_REFCLASS_LOCAL: if (index > ACPI_METHOD_MAX_LOCAL) { ACPI_ERROR((AE_INFO, @@ -271,7 +271,7 @@ acpi_ds_method_data_get_node(u16 opcode, *node = &walk_state->local_variables[index]; break; - case AML_ARG_OP: + case ACPI_REFCLASS_ARG: if (index > ACPI_METHOD_MAX_ARG) { ACPI_ERROR((AE_INFO, @@ -286,8 +286,8 @@ acpi_ds_method_data_get_node(u16 opcode, break; default: - ACPI_ERROR((AE_INFO, "Opcode %d is invalid", opcode)); - return_ACPI_STATUS(AE_AML_BAD_OPCODE); + ACPI_ERROR((AE_INFO, "Type %d is invalid", type)); + return_ACPI_STATUS(AE_TYPE); } return_ACPI_STATUS(AE_OK); @@ -297,7 +297,8 @@ acpi_ds_method_data_get_node(u16 opcode, * * FUNCTION: acpi_ds_method_data_set_value * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP + * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or + * ACPI_REFCLASS_ARG * Index - Which Local or Arg to get * Object - Object to be inserted into the stack entry * walk_state - Current walk state object @@ -310,7 +311,7 @@ acpi_ds_method_data_get_node(u16 opcode, ******************************************************************************/ static acpi_status -acpi_ds_method_data_set_value(u16 opcode, +acpi_ds_method_data_set_value(u8 type, u32 index, union acpi_operand_object *object, struct acpi_walk_state *walk_state) @@ -321,13 +322,13 @@ acpi_ds_method_data_set_value(u16 opcode, ACPI_FUNCTION_TRACE(ds_method_data_set_value); ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "NewObj %p Opcode %X, Refs=%d [%s]\n", object, - opcode, object->common.reference_count, + "NewObj %p Type %2.2X, Refs=%d [%s]\n", object, + type, object->common.reference_count, acpi_ut_get_type_name(object->common.type))); /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); + status = acpi_ds_method_data_get_node(type, index, walk_state, &node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -350,7 +351,8 @@ acpi_ds_method_data_set_value(u16 opcode, * * FUNCTION: acpi_ds_method_data_get_value * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP + * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or + * ACPI_REFCLASS_ARG * Index - Which local_var or argument to get * walk_state - Current walk state object * dest_desc - Where Arg or Local value is returned @@ -363,7 +365,7 @@ acpi_ds_method_data_set_value(u16 opcode, ******************************************************************************/ acpi_status -acpi_ds_method_data_get_value(u16 opcode, +acpi_ds_method_data_get_value(u8 type, u32 index, struct acpi_walk_state *walk_state, union acpi_operand_object **dest_desc) @@ -383,7 +385,7 @@ acpi_ds_method_data_get_value(u16 opcode, /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); + status = acpi_ds_method_data_get_node(type, index, walk_state, &node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -419,8 +421,8 @@ acpi_ds_method_data_get_value(u16 opcode, /* Otherwise, return the error */ else - switch (opcode) { - case AML_ARG_OP: + switch (type) { + case ACPI_REFCLASS_ARG: ACPI_ERROR((AE_INFO, "Uninitialized Arg[%d] at node %p", @@ -428,7 +430,7 @@ acpi_ds_method_data_get_value(u16 opcode, return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG); - case AML_LOCAL_OP: + case ACPI_REFCLASS_LOCAL: ACPI_ERROR((AE_INFO, "Uninitialized Local[%d] at node %p", @@ -437,9 +439,10 @@ acpi_ds_method_data_get_value(u16 opcode, return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); default: + ACPI_ERROR((AE_INFO, "Not a Arg/Local opcode: %X", - opcode)); + type)); return_ACPI_STATUS(AE_AML_INTERNAL); } } @@ -458,7 +461,8 @@ acpi_ds_method_data_get_value(u16 opcode, * * FUNCTION: acpi_ds_method_data_delete_value * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP + * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or + * ACPI_REFCLASS_ARG * Index - Which local_var or argument to delete * walk_state - Current walk state object * @@ -470,7 +474,7 @@ acpi_ds_method_data_get_value(u16 opcode, ******************************************************************************/ static void -acpi_ds_method_data_delete_value(u16 opcode, +acpi_ds_method_data_delete_value(u8 type, u32 index, struct acpi_walk_state *walk_state) { acpi_status status; @@ -481,7 +485,7 @@ acpi_ds_method_data_delete_value(u16 opcode, /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); + status = acpi_ds_method_data_get_node(type, index, walk_state, &node); if (ACPI_FAILURE(status)) { return_VOID; } @@ -514,7 +518,8 @@ acpi_ds_method_data_delete_value(u16 opcode, * * FUNCTION: acpi_ds_store_object_to_local * - * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP + * PARAMETERS: Type - Either ACPI_REFCLASS_LOCAL or + * ACPI_REFCLASS_ARG * Index - Which Local or Arg to set * obj_desc - Value to be stored * walk_state - Current walk state @@ -528,7 +533,7 @@ acpi_ds_method_data_delete_value(u16 opcode, ******************************************************************************/ acpi_status -acpi_ds_store_object_to_local(u16 opcode, +acpi_ds_store_object_to_local(u8 type, u32 index, union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state) @@ -539,8 +544,8 @@ acpi_ds_store_object_to_local(u16 opcode, union acpi_operand_object *new_obj_desc; ACPI_FUNCTION_TRACE(ds_store_object_to_local); - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n", - opcode, index, obj_desc)); + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%d Obj=%p\n", + type, index, obj_desc)); /* Parameter validation */ @@ -550,7 +555,7 @@ acpi_ds_store_object_to_local(u16 opcode, /* Get the namespace node for the arg/local */ - status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node); + status = acpi_ds_method_data_get_node(type, index, walk_state, &node); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -602,7 +607,7 @@ acpi_ds_store_object_to_local(u16 opcode, * * Weird, but true. */ - if (opcode == AML_ARG_OP) { + if (type == ACPI_REFCLASS_ARG) { /* * If we have a valid reference object that came from ref_of(), * do the indirect store @@ -611,8 +616,8 @@ acpi_ds_store_object_to_local(u16 opcode, ACPI_DESC_TYPE_OPERAND) && (current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) - && (current_obj_desc->reference.opcode == - AML_REF_OF_OP)) { + && (current_obj_desc->reference.class == + ACPI_REFCLASS_REFOF)) { ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Arg (%p) is an ObjRef(Node), storing in node %p\n", new_obj_desc, @@ -640,11 +645,9 @@ acpi_ds_store_object_to_local(u16 opcode, } } - /* - * Delete the existing object - * before storing the new one - */ - acpi_ds_method_data_delete_value(opcode, index, walk_state); + /* Delete the existing object before storing the new one */ + + acpi_ds_method_data_delete_value(type, index, walk_state); } /* @@ -653,7 +656,7 @@ acpi_ds_store_object_to_local(u16 opcode, * (increments the object reference count by one) */ status = - acpi_ds_method_data_set_value(opcode, index, new_obj_desc, + acpi_ds_method_data_set_value(type, index, new_obj_desc, walk_state); /* Remove local reference if we copied the object above */ diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 09af39fff1a..4f08e599d07 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -731,36 +731,35 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, switch (op_info->type) { case AML_TYPE_LOCAL_VARIABLE: - /* Split the opcode into a base opcode + offset */ + /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ - obj_desc->reference.opcode = AML_LOCAL_OP; - obj_desc->reference.offset = opcode - AML_LOCAL_OP; + obj_desc->reference.value = opcode - AML_LOCAL_OP; + obj_desc->reference.class = ACPI_REFCLASS_LOCAL; #ifndef ACPI_NO_METHOD_EXECUTION - status = acpi_ds_method_data_get_node(AML_LOCAL_OP, - obj_desc-> - reference.offset, - walk_state, - ACPI_CAST_INDIRECT_PTR - (struct - acpi_namespace_node, - &obj_desc-> - reference. - object)); + status = + acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL, + obj_desc->reference. + value, walk_state, + ACPI_CAST_INDIRECT_PTR + (struct + acpi_namespace_node, + &obj_desc->reference. + object)); #endif break; case AML_TYPE_METHOD_ARGUMENT: - /* Split the opcode into a base opcode + offset */ + /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ - obj_desc->reference.opcode = AML_ARG_OP; - obj_desc->reference.offset = opcode - AML_ARG_OP; + obj_desc->reference.value = opcode - AML_ARG_OP; + obj_desc->reference.class = ACPI_REFCLASS_ARG; #ifndef ACPI_NO_METHOD_EXECUTION - status = acpi_ds_method_data_get_node(AML_ARG_OP, + status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG, obj_desc-> - reference.offset, + reference.value, walk_state, ACPI_CAST_INDIRECT_PTR (struct @@ -771,18 +770,31 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state, #endif break; - default: /* Other literals, etc.. */ + default: /* Object name or Debug object */ - if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { + switch (op->common.aml_opcode) { + case AML_INT_NAMEPATH_OP: /* Node was saved in Op */ obj_desc->reference.node = op->common.node; obj_desc->reference.object = op->common.node->object; - } + obj_desc->reference.class = ACPI_REFCLASS_NAME; + break; + + case AML_DEBUG_OP: - obj_desc->reference.opcode = opcode; + obj_desc->reference.class = ACPI_REFCLASS_DEBUG; + break; + + default: + + ACPI_ERROR((AE_INFO, + "Unimplemented reference type for AML opcode: %4.4X", + opcode)); + return_ACPI_STATUS(AE_AML_OPERAND_TYPE); + } break; } break; diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 6a81c4400ed..69fae5905bb 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -1330,7 +1330,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, (walk_state->results->results.obj_desc[0]) == ACPI_TYPE_LOCAL_REFERENCE) && ((walk_state->results->results.obj_desc[0])-> - reference.opcode != AML_INDEX_OP)) { + reference.class != ACPI_REFCLASS_INDEX)) { status = acpi_ex_resolve_to_value(&walk_state-> results->results. diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index b5072fa9c92..5b2419197b9 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -429,10 +429,10 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) ACPI_TYPE_LOCAL_REFERENCE) && (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) - && (walk_state->operands[0]->reference.opcode == - walk_state->operands[1]->reference.opcode) - && (walk_state->operands[0]->reference.offset == - walk_state->operands[1]->reference.offset)) { + && (walk_state->operands[0]->reference.class == + walk_state->operands[1]->reference.class) + && (walk_state->operands[0]->reference.value == + walk_state->operands[1]->reference.value)) { status = AE_OK; } else { ACPI_EXCEPTION((AE_INFO, status, diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index 5f2b1ebf70a..74da6fa52ef 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -43,7 +43,6 @@ #include #include -#include #include #include #include @@ -91,7 +90,7 @@ acpi_ex_add_table(u32 table_index, /* Init the table handle */ - obj_desc->reference.opcode = AML_LOAD_OP; + obj_desc->reference.class = ACPI_REFCLASS_TABLE; *ddb_handle = obj_desc; /* Install the new table into the local data structures */ diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 7d4123256cf..d087a7d28aa 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -45,7 +45,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exdump") @@ -216,8 +215,8 @@ static struct acpi_exdump_info acpi_ex_dump_index_field[5] = { static struct acpi_exdump_info acpi_ex_dump_reference[8] = { {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_reference), NULL}, + {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.class), "Class"}, {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(reference.target_type), "Target Type"}, - {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.offset), "Offset"}, {ACPI_EXD_UINT32, ACPI_EXD_OFFSET(reference.value), "Value"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.object), "Object Desc"}, {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(reference.node), "Node"}, @@ -414,10 +413,10 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, case ACPI_EXD_REFERENCE: - acpi_ex_out_string("Opcode", - (acpi_ps_get_opcode_info - (obj_desc->reference.opcode))-> - name); + acpi_ex_out_string("Class Name", + (char *) + acpi_ut_get_reference_name + (obj_desc)); acpi_ex_dump_reference_obj(obj_desc); break; @@ -495,40 +494,41 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_LOCAL_REFERENCE: - switch (obj_desc->reference.opcode) { - case AML_DEBUG_OP: + acpi_os_printf("Reference: [%s] ", + acpi_ut_get_reference_name(obj_desc)); + + switch (obj_desc->reference.class) { + case ACPI_REFCLASS_DEBUG: - acpi_os_printf("Reference: [Debug]\n"); + acpi_os_printf("\n"); break; - case AML_INDEX_OP: + case ACPI_REFCLASS_INDEX: - acpi_os_printf("Reference: [Index] %p\n", - obj_desc->reference.object); + acpi_os_printf("%p\n", obj_desc->reference.object); break; - case AML_LOAD_OP: + case ACPI_REFCLASS_TABLE: - acpi_os_printf("Reference: [DdbHandle] TableIndex %X\n", + acpi_os_printf("Table Index %X\n", obj_desc->reference.value); break; - case AML_REF_OF_OP: + case ACPI_REFCLASS_REFOF: - acpi_os_printf("Reference: [RefOf] %p [%s]\n", - obj_desc->reference.object, + acpi_os_printf("%p [%s]\n", obj_desc->reference.object, acpi_ut_get_type_name(((union acpi_operand_object - *)obj_desc-> + *) + obj_desc-> reference. object)->common. type)); break; - case AML_ARG_OP: + case ACPI_REFCLASS_ARG: - acpi_os_printf("Reference: [Arg%d]", - obj_desc->reference.offset); + acpi_os_printf("%X", obj_desc->reference.value); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { @@ -543,10 +543,9 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) acpi_os_printf("\n"); break; - case AML_LOCAL_OP: + case ACPI_REFCLASS_LOCAL: - acpi_os_printf("Reference: [Local%d]", - obj_desc->reference.offset); + acpi_os_printf("%X", obj_desc->reference.value); if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) { @@ -561,21 +560,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth) acpi_os_printf("\n"); break; - case AML_INT_NAMEPATH_OP: + case ACPI_REFCLASS_NAME: - acpi_os_printf("Reference: [Namepath] %X [%4.4s]\n", - obj_desc->reference.node->name.integer, + acpi_os_printf("- [%4.4s]\n", obj_desc->reference.node->name.ascii); break; - default: - - /* Unknown opcode */ + default: /* Unknown reference class */ - acpi_os_printf("Unknown Reference opcode=%X\n", - obj_desc->reference.opcode); + acpi_os_printf("%2.2X\n", obj_desc->reference.class); break; - } break; @@ -866,8 +860,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) ret_buf.length = ACPI_ALLOCATE_LOCAL_BUFFER; - if (obj_desc->reference.opcode == AML_INT_NAMEPATH_OP) { - acpi_os_printf(" Named Object %p ", obj_desc->reference.node); + if (obj_desc->reference.class == ACPI_REFCLASS_NAME) { + acpi_os_printf(" %p ", obj_desc->reference.node); status = acpi_ns_handle_to_pathname(obj_desc->reference.node, @@ -883,8 +877,8 @@ static void acpi_ex_dump_reference_obj(union acpi_operand_object *obj_desc) ACPI_DESC_TYPE_OPERAND) { acpi_os_printf(" Target: %p", obj_desc->reference.object); - if (obj_desc->reference.opcode == AML_LOAD_OP) { - acpi_os_printf(" [DDBHandle] Table Index: %X\n", + if (obj_desc->reference.class == ACPI_REFCLASS_TABLE) { + acpi_os_printf(" Table Index: %X\n", obj_desc->reference.value); } else { acpi_os_printf(" Target: %p [%s]\n", @@ -987,9 +981,9 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc, case ACPI_TYPE_LOCAL_REFERENCE: - acpi_os_printf("[Object Reference] %s", - (acpi_ps_get_opcode_info - (obj_desc->reference.opcode))->name); + acpi_os_printf("[Object Reference] Type [%s] %2.2X", + acpi_ut_get_reference_name(obj_desc), + obj_desc->reference.class); acpi_ex_dump_reference_obj(obj_desc); break; diff --git a/drivers/acpi/executer/exmisc.c b/drivers/acpi/executer/exmisc.c index 731414a581a..efb19134005 100644 --- a/drivers/acpi/executer/exmisc.c +++ b/drivers/acpi/executer/exmisc.c @@ -86,10 +86,10 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, /* * Must be a reference to a Local or Arg */ - switch (obj_desc->reference.opcode) { - case AML_LOCAL_OP: - case AML_ARG_OP: - case AML_DEBUG_OP: + switch (obj_desc->reference.class) { + case ACPI_REFCLASS_LOCAL: + case ACPI_REFCLASS_ARG: + case ACPI_REFCLASS_DEBUG: /* The referenced object is the pseudo-node for the local/arg */ @@ -98,8 +98,8 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, default: - ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", - obj_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X", + obj_desc->reference.class)); return_ACPI_STATUS(AE_AML_INTERNAL); } break; @@ -127,7 +127,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, return_ACPI_STATUS(AE_NO_MEMORY); } - reference_obj->reference.opcode = AML_REF_OF_OP; + reference_obj->reference.class = ACPI_REFCLASS_REFOF; reference_obj->reference.object = referenced_obj; *return_desc = reference_obj; diff --git a/drivers/acpi/executer/exoparg1.c b/drivers/acpi/executer/exoparg1.c index 7c3bea575e0..f622f9eac8a 100644 --- a/drivers/acpi/executer/exoparg1.c +++ b/drivers/acpi/executer/exoparg1.c @@ -825,16 +825,16 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) * * Must resolve/dereference the local/arg reference first */ - switch (operand[0]->reference.opcode) { - case AML_LOCAL_OP: - case AML_ARG_OP: + switch (operand[0]->reference.class) { + case ACPI_REFCLASS_LOCAL: + case ACPI_REFCLASS_ARG: /* Set Operand[0] to the value of the local/arg */ status = acpi_ds_method_data_get_value - (operand[0]->reference.opcode, - operand[0]->reference.offset, + (operand[0]->reference.class, + operand[0]->reference.value, walk_state, &temp_desc); if (ACPI_FAILURE(status)) { goto cleanup; @@ -848,7 +848,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) operand[0] = temp_desc; break; - case AML_REF_OF_OP: + case ACPI_REFCLASS_REFOF: /* Get the object to which the reference refers */ @@ -928,8 +928,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) * This must be a reference object produced by either the * Index() or ref_of() operator */ - switch (operand[0]->reference.opcode) { - case AML_INDEX_OP: + switch (operand[0]->reference.class) { + case ACPI_REFCLASS_INDEX: /* * The target type for the Index operator must be @@ -965,7 +965,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) return_desc->integer.value = temp_desc->buffer. pointer[operand[0]->reference. - offset]; + value]; break; case ACPI_TYPE_PACKAGE: @@ -985,7 +985,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: ACPI_ERROR((AE_INFO, - "Unknown Index TargetType %X in obj %p", + "Unknown Index TargetType %X in reference object %p", operand[0]->reference. target_type, operand[0])); status = AE_AML_OPERAND_TYPE; @@ -993,7 +993,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) } break; - case AML_REF_OF_OP: + case ACPI_REFCLASS_REFOF: return_desc = operand[0]->reference.object; @@ -1013,9 +1013,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) default: ACPI_ERROR((AE_INFO, - "Unknown opcode in reference(%p) - %X", + "Unknown class in reference(%p) - %2.2X", operand[0], - operand[0]->reference.opcode)); + operand[0]->reference.class)); status = AE_TYPE; goto cleanup; diff --git a/drivers/acpi/executer/exoparg2.c b/drivers/acpi/executer/exoparg2.c index 8e8bbb6cceb..368def5dffc 100644 --- a/drivers/acpi/executer/exoparg2.c +++ b/drivers/acpi/executer/exoparg2.c @@ -391,8 +391,8 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state) /* Initialize the Index reference object */ index = operand[1]->integer.value; - return_desc->reference.offset = (u32) index; - return_desc->reference.opcode = AML_INDEX_OP; + return_desc->reference.value = (u32) index; + return_desc->reference.class = ACPI_REFCLASS_INDEX; /* * At this point, the Source operand is a String, Buffer, or Package. diff --git a/drivers/acpi/executer/exresnte.c b/drivers/acpi/executer/exresnte.c index 5596f42c967..423ad3635f3 100644 --- a/drivers/acpi/executer/exresnte.c +++ b/drivers/acpi/executer/exresnte.c @@ -46,8 +46,6 @@ #include #include #include -#include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresnte") @@ -238,10 +236,10 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, case ACPI_TYPE_LOCAL_REFERENCE: - switch (source_desc->reference.opcode) { - case AML_LOAD_OP: /* This is a ddb_handle */ - case AML_REF_OF_OP: - case AML_INDEX_OP: + switch (source_desc->reference.class) { + case ACPI_REFCLASS_TABLE: /* This is a ddb_handle */ + case ACPI_REFCLASS_REFOF: + case ACPI_REFCLASS_INDEX: /* Return an additional reference to the object */ @@ -253,10 +251,8 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, /* No named references are allowed here */ ACPI_ERROR((AE_INFO, - "Unsupported Reference opcode %X (%s)", - source_desc->reference.opcode, - acpi_ps_get_opcode_name(source_desc-> - reference.opcode))); + "Unsupported Reference type %X", + source_desc->reference.class)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } diff --git a/drivers/acpi/executer/exresolv.c b/drivers/acpi/executer/exresolv.c index b35f7c817ac..89571b92a52 100644 --- a/drivers/acpi/executer/exresolv.c +++ b/drivers/acpi/executer/exresolv.c @@ -47,7 +47,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exresolv") @@ -141,7 +140,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, acpi_status status = AE_OK; union acpi_operand_object *stack_desc; union acpi_operand_object *obj_desc = NULL; - u16 opcode; + u8 ref_type; ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); @@ -152,19 +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_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)) { @@ -173,7 +172,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n", - stack_desc->reference.offset, + stack_desc->reference.value, obj_desc)); /* @@ -184,7 +183,7 @@ 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: @@ -239,15 +238,15 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, } 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, do not dereference */ break; - case AML_INT_NAMEPATH_OP: /* Reference to a named object */ + case ACPI_REFCLASS_NAME: /* Reference to a named object */ /* Dereference the name */ @@ -273,8 +272,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, default: ACPI_ERROR((AE_INFO, - "Unknown Reference opcode %X (%s) in %p", - opcode, acpi_ps_get_opcode_name(opcode), + "Unknown Reference type %X in %p", ref_type, stack_desc)); status = AE_AML_INTERNAL; break; @@ -388,13 +386,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, * 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: - case AML_INT_NAMEPATH_OP: + switch (obj_desc->reference.class) { + case ACPI_REFCLASS_REFOF: + case ACPI_REFCLASS_NAME: /* Dereference the reference pointer */ - if (obj_desc->reference.opcode == AML_REF_OF_OP) { + if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) { node = obj_desc->reference.object; } else { /* AML_INT_NAMEPATH_OP */ @@ -429,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) */ @@ -455,22 +453,22 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, } break; - case AML_LOAD_OP: + case ACPI_REFCLASS_TABLE: 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)) { @@ -481,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)) { @@ -499,7 +497,7 @@ 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 "DebugObject" */ @@ -509,8 +507,8 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, default: ACPI_ERROR((AE_INFO, - "Unknown Reference subtype %X", - obj_desc->reference.opcode)); + "Unknown Reference Class %2.2X", + obj_desc->reference.class)); return_ACPI_STATUS(AE_AML_INTERNAL); } } diff --git a/drivers/acpi/executer/exresop.c b/drivers/acpi/executer/exresop.c index 54085f16ec2..0bb82593da7 100644 --- a/drivers/acpi/executer/exresop.c +++ b/drivers/acpi/executer/exresop.c @@ -225,41 +225,36 @@ acpi_ex_resolve_operands(u16 opcode, if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) { - /* Decode the Reference */ + /* Validate the Reference */ - op_info = acpi_ps_get_opcode_info(opcode); - if (op_info->class == AML_CLASS_UNKNOWN) { - return_ACPI_STATUS(AE_AML_BAD_OPCODE); - } + switch (obj_desc->reference.class) { + case ACPI_REFCLASS_DEBUG: - switch (obj_desc->reference.opcode) { - case AML_DEBUG_OP: target_op = AML_DEBUG_OP; /*lint -fallthrough */ - case AML_INDEX_OP: - case AML_REF_OF_OP: - case AML_ARG_OP: - case AML_LOCAL_OP: - case AML_LOAD_OP: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ - case AML_INT_NAMEPATH_OP: /* Reference to a named object */ - - ACPI_DEBUG_ONLY_MEMBERS(ACPI_DEBUG_PRINT - ((ACPI_DB_EXEC, - "Operand is a Reference, RefOpcode [%s]\n", - (acpi_ps_get_opcode_info - (obj_desc-> - reference. - opcode))-> - name))); + case ACPI_REFCLASS_ARG: + case ACPI_REFCLASS_LOCAL: + case ACPI_REFCLASS_INDEX: + case ACPI_REFCLASS_REFOF: + case ACPI_REFCLASS_TABLE: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */ + case ACPI_REFCLASS_NAME: /* Reference to a named object */ + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Operand is a Reference, Class [%s] %2.2X\n", + acpi_ut_get_reference_name + (obj_desc), + obj_desc->reference. + class)); break; default: + ACPI_ERROR((AE_INFO, - "Operand is a Reference, Unknown Reference Opcode: %X", - obj_desc->reference. - opcode)); + "Unknown Reference Class %2.2X in %p", + obj_desc->reference.class, + obj_desc)); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } @@ -270,8 +265,7 @@ acpi_ex_resolve_operands(u16 opcode, /* Invalid descriptor */ - ACPI_ERROR((AE_INFO, - "Invalid descriptor %p [%s]", + ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]", obj_desc, acpi_ut_get_descriptor_name(obj_desc))); @@ -343,7 +337,7 @@ acpi_ex_resolve_operands(u16 opcode, if ((opcode == AML_STORE_OP) && (ACPI_GET_OBJECT_TYPE(*stack_ptr) == ACPI_TYPE_LOCAL_REFERENCE) - && ((*stack_ptr)->reference.opcode == AML_INDEX_OP)) { + && ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) { goto next_operand; } break; diff --git a/drivers/acpi/executer/exstore.c b/drivers/acpi/executer/exstore.c index 20b4893e06e..3318df4cbd9 100644 --- a/drivers/acpi/executer/exstore.c +++ b/drivers/acpi/executer/exstore.c @@ -47,7 +47,6 @@ #include #include #include -#include #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exstore") @@ -179,23 +178,27 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, case ACPI_TYPE_LOCAL_REFERENCE: - if (source_desc->reference.opcode == AML_INDEX_OP) { - ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, - "[%s, 0x%X]\n", - acpi_ps_get_opcode_name - (source_desc->reference.opcode), - source_desc->reference.offset)); - } else { - ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s]", - acpi_ps_get_opcode_name - (source_desc->reference.opcode))); - } + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "[%s] ", + acpi_ut_get_reference_name(source_desc))); + + /* Decode the reference */ + + switch (source_desc->reference.class) { + case ACPI_REFCLASS_INDEX: + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, "0x%X\n", + source_desc->reference.value)); + break; + + case ACPI_REFCLASS_TABLE: - if (source_desc->reference.opcode == AML_LOAD_OP) { /* Load and load_table */ ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, - " Table Index %X\n", + "Table Index 0x%X\n", source_desc->reference.value)); break; + + default: + break; } ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, " ")); @@ -347,15 +350,15 @@ acpi_ex_store(union acpi_operand_object *source_desc, } /* - * Examine the Reference opcode. These cases are handled: + * Examine the Reference class. These cases are handled: * * 1) Store to Name (Change the object associated with a name) * 2) Store to an indexed area of a Buffer or Package * 3) Store to a Method Local or Arg * 4) Store to the debug object */ - switch (ref_desc->reference.opcode) { - case AML_REF_OF_OP: + switch (ref_desc->reference.class) { + case ACPI_REFCLASS_REFOF: /* Storing an object into a Name "container" */ @@ -365,7 +368,7 @@ acpi_ex_store(union acpi_operand_object *source_desc, ACPI_IMPLICIT_CONVERSION); break; - case AML_INDEX_OP: + case ACPI_REFCLASS_INDEX: /* Storing to an Index (pointer into a packager or buffer) */ @@ -374,18 +377,18 @@ acpi_ex_store(union acpi_operand_object *source_desc, walk_state); break; - case AML_LOCAL_OP: - case AML_ARG_OP: + case ACPI_REFCLASS_LOCAL: + case ACPI_REFCLASS_ARG: /* Store to a method local/arg */ status = - acpi_ds_store_object_to_local(ref_desc->reference.opcode, - ref_desc->reference.offset, + acpi_ds_store_object_to_local(ref_desc->reference.class, + ref_desc->reference.value, source_desc, walk_state); break; - case AML_DEBUG_OP: + case ACPI_REFCLASS_DEBUG: /* * Storing to the Debug object causes the value stored to be @@ -401,8 +404,8 @@ acpi_ex_store(union acpi_operand_object *source_desc, default: - ACPI_ERROR((AE_INFO, "Unknown Reference opcode %X", - ref_desc->reference.opcode)); + ACPI_ERROR((AE_INFO, "Unknown Reference Class %2.2X", + ref_desc->reference.class)); ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO); status = AE_AML_INTERNAL; @@ -458,7 +461,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_LOCAL_REFERENCE - && source_desc->reference.opcode == AML_LOAD_OP) { + && source_desc->reference.class == ACPI_REFCLASS_TABLE) { /* This is a DDBHandle, just add a reference to it */ @@ -553,7 +556,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc, /* Store the source value into the target buffer byte */ - obj_desc->buffer.pointer[index_desc->reference.offset] = value; + obj_desc->buffer.pointer[index_desc->reference.value] = value; break; default: diff --git a/drivers/acpi/executer/exstoren.c b/drivers/acpi/executer/exstoren.c index a6d2168b81f..eef61a00803 100644 --- a/drivers/acpi/executer/exstoren.c +++ b/drivers/acpi/executer/exstoren.c @@ -121,7 +121,8 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr, (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) && !((ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_LOCAL_REFERENCE) - && (source_desc->reference.opcode == AML_LOAD_OP))) { + && (source_desc->reference.class == + ACPI_REFCLASS_TABLE))) { /* Conversion successful but still not a valid type */ diff --git a/drivers/acpi/namespace/nsdump.c b/drivers/acpi/namespace/nsdump.c index 0ab22004728..cc0ae39440e 100644 --- a/drivers/acpi/namespace/nsdump.c +++ b/drivers/acpi/namespace/nsdump.c @@ -43,7 +43,6 @@ #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsdump") @@ -334,9 +333,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle, case ACPI_TYPE_LOCAL_REFERENCE: acpi_os_printf("[%s]\n", - acpi_ps_get_opcode_name(obj_desc-> - reference. - opcode)); + acpi_ut_get_reference_name(obj_desc)); break; case ACPI_TYPE_BUFFER_FIELD: diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index f3cc3762453..a085cc39c05 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -45,7 +45,6 @@ #include #include #include -#include #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfeval") @@ -399,13 +398,13 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to * an union acpi_object. */ - switch (info->return_object->reference.opcode) { - case AML_INDEX_OP: + switch (info->return_object->reference.class) { + case ACPI_REFCLASS_INDEX: obj_desc = *(info->return_object->reference.where); break; - case AML_REF_OF_OP: + case ACPI_REFCLASS_REFOF: node = info->return_object->reference.object; if (node) { diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index d9063ea414e..8eaaecf9200 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -43,7 +43,6 @@ #include #include -#include #include #define _COMPONENT ACPI_RESOURCES @@ -560,8 +559,8 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, ACPI_GET_OBJECT_TYPE(*sub_object_list)) || ((ACPI_TYPE_LOCAL_REFERENCE == ACPI_GET_OBJECT_TYPE(*sub_object_list)) && - ((*sub_object_list)->reference.opcode == - AML_INT_NAMEPATH_OP)))) { + ((*sub_object_list)->reference.class == + ACPI_REFCLASS_NAME)))) { name_found = TRUE; } else { /* Look at the next element */ diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index 7804a8c40e7..c0bbfa2c419 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -43,7 +43,6 @@ #include #include -#include #include #define _COMPONENT ACPI_RESOURCES @@ -310,13 +309,12 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { case ACPI_TYPE_LOCAL_REFERENCE: - if (obj_desc->reference.opcode != - AML_INT_NAMEPATH_OP) { + if (obj_desc->reference.class != + ACPI_REFCLASS_NAME) { ACPI_ERROR((AE_INFO, - "(PRT[%X].Source) Need name, found reference op %X", + "(PRT[%X].Source) Need name, found Reference Class %X", index, - obj_desc->reference. - opcode)); + obj_desc->reference.class)); return_ACPI_STATUS(AE_BAD_DATA); } diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 53499ac9098..5b2f7c27b70 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -42,7 +42,6 @@ */ #include -#include #include @@ -176,20 +175,24 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object, /* This is an object reference. */ - switch (internal_object->reference.opcode) { - case AML_INT_NAMEPATH_OP: - - /* For namepath, return the object handle ("reference") */ - - default: - - /* We are referring to the namespace node */ + switch (internal_object->reference.class) { + case ACPI_REFCLASS_NAME: + /* + * For namepath, return the object handle ("reference") + * We are referring to the namespace node + */ external_object->reference.handle = internal_object->reference.node; external_object->reference.actual_type = acpi_ns_get_type(internal_object->reference.node); break; + + default: + + /* All other reference types are unsupported */ + + return_ACPI_STATUS(AE_TYPE); } break; @@ -533,7 +536,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object, /* TBD: should validate incoming handle */ - internal_object->reference.opcode = AML_INT_NAMEPATH_OP; + internal_object->reference.class = ACPI_REFCLASS_NAME; internal_object->reference.node = external_object->reference.handle; break; @@ -743,11 +746,11 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc, * We copied the reference object, so we now must add a 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 + * DDBHandle reference (from Load/load_table) is a special reference, + * it does not have a Reference.Object, so does not need to * increase the reference count */ - if (source_desc->reference.opcode == AML_LOAD_OP) { + if (source_desc->reference.class == ACPI_REFCLASS_TABLE) { break; } diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 42609d3a8aa..5c219758c22 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -45,7 +45,6 @@ #include #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utdelete") @@ -548,8 +547,8 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) * reference must track changes to the ref count of the index or * target object. */ - if ((object->reference.opcode == AML_INDEX_OP) || - (object->reference.opcode == AML_INT_NAMEPATH_OP)) { + if ((object->reference.class == ACPI_REFCLASS_INDEX) || + (object->reference.class == ACPI_REFCLASS_NAME)) { next_object = object->reference.object; } break; diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index bcace577183..0b1e493a837 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -45,7 +45,6 @@ #include #include -#include ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) #define _COMPONENT ACPI_UTILITIES @@ -590,25 +589,31 @@ char *acpi_ut_get_descriptor_name(void *object) /* Printable names of reference object sub-types */ +static const char *acpi_gbl_ref_class_names[] = { + /* 00 */ "Local", + /* 01 */ "Argument", + /* 02 */ "RefOf", + /* 03 */ "Index", + /* 04 */ "DdbHandle", + /* 05 */ "Named Object", + /* 06 */ "Debug" +}; + const char *acpi_ut_get_reference_name(union acpi_operand_object *object) { + if (!object) + return "NULL Object"; - switch (object->reference.opcode) { - case AML_INT_NAMEPATH_OP: - return "Name"; + if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) + return "Not an Operand object"; - case AML_LOAD_OP: - return "DDB-Handle"; + if (object->common.type != ACPI_TYPE_LOCAL_REFERENCE) + return "Not a Reference object"; - case AML_REF_OF_OP: - return "RefOf"; + if (object->reference.class > ACPI_REFCLASS_MAX) + return "Unknown Reference class"; - case AML_INDEX_OP: - return "Index"; - - default: - return "Unknown"; - } + return acpi_gbl_ref_class_names[object->reference.class]; } #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) @@ -812,4 +817,4 @@ acpi_status acpi_ut_init_globals(void) } ACPI_EXPORT_SYMBOL(acpi_dbg_level) - ACPI_EXPORT_SYMBOL(acpi_dbg_layer) +ACPI_EXPORT_SYMBOL(acpi_dbg_layer) diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index 924d05af94d..c354e7a42bc 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -43,7 +43,6 @@ #include #include -#include #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utobject") @@ -478,8 +477,8 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, case ACPI_TYPE_LOCAL_REFERENCE: - switch (internal_object->reference.opcode) { - case AML_INT_NAMEPATH_OP: + switch (internal_object->reference.class) { + case ACPI_REFCLASS_NAME: /* * Get the actual length of the full pathname to this object. @@ -504,9 +503,9 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object, */ ACPI_ERROR((AE_INFO, "Cannot convert to external object - " - "unsupported Reference type [%s] %X in object %p", + "unsupported Reference Class [%s] %X in object %p", acpi_ut_get_reference_name(internal_object), - internal_object->reference.opcode, + internal_object->reference.class, internal_object)); status = AE_TYPE; break; -- cgit v1.2.3 From 393a75d6b7bae59221b2122634eb4cb905e84208 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 11:12:36 +0800 Subject: ACPICA: Fix possible memory leak in acpi_ns_get_external_pathname Fixes a memory leak in the error exit path. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/namespace/nsnames.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index bd577387800..9c587bdfe3f 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -142,7 +142,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) size = acpi_ns_get_pathname_length(node); if (!size) { - return (NULL); + return_PTR(NULL); } /* Allocate a buffer to be returned to caller */ @@ -157,7 +157,8 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) status = acpi_ns_build_external_path(node, size, name_buffer); if (ACPI_FAILURE(status)) { - return (NULL); + ACPI_FREE(name_buffer); + return_PTR(NULL); } return_PTR(name_buffer); -- cgit v1.2.3 From bbbbeb8e31af97f11b84294b2e7e5607125829d2 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 11:26:59 +0800 Subject: ACPICA: Remove unused ACPI register bit definition Removed the ACPI_BITREG_WAKE_ENABLE definition and entry in the global register table. This bit does not exist and is unused. http://www.acpica.org/bugzilla/show_bug.cgi?id=442 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/utilities/utglobal.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 0b1e493a837..670551b95e5 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -281,7 +281,6 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = { /* ACPI_BITREG_RT_CLOCK_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_RT_CLOCK_ENABLE, ACPI_BITMASK_RT_CLOCK_ENABLE}, - /* ACPI_BITREG_WAKE_ENABLE */ {ACPI_REGISTER_PM1_ENABLE, 0, 0}, /* ACPI_BITREG_PCIEXP_WAKE_DISABLE */ {ACPI_REGISTER_PM1_ENABLE, ACPI_BITPOSITION_PCIEXP_WAKE_DISABLE, ACPI_BITMASK_PCIEXP_WAKE_DISABLE}, -- cgit v1.2.3 From c35def2118d3d7cceb0f69d6707f613a7473df15 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 11:28:46 +0800 Subject: ACPICA: Fix fault after mem allocation failure in AML parser Fixes a crash if a memory allocation fails during the Op completion routine acpi_ps_complete_this_op(). http://www.acpica.org/bugzilla/show_bug.cgi?id=492 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/parser/psparse.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 15e1702e48d..52caaf6582e 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, union acpi_parse_object *next; const struct acpi_opcode_info *parent_info; union acpi_parse_object *replacement_op = NULL; + acpi_status status = AE_OK; ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); @@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, replacement_op = acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); if (!replacement_op) { - goto allocate_error; + status = AE_NO_MEMORY; } break; @@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, replacement_op = acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); if (!replacement_op) { - goto allocate_error; + status = AE_NO_MEMORY; } } else if ((op->common.parent->common.aml_opcode == @@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, acpi_ps_alloc_op(op->common. aml_opcode); if (!replacement_op) { - goto allocate_error; + status = AE_NO_MEMORY; + } else { + replacement_op->named.data = + op->named.data; + replacement_op->named.length = + op->named.length; } - - replacement_op->named.data = - op->named.data; - replacement_op->named.length = - op->named.length; } } break; @@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, replacement_op = acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); if (!replacement_op) { - goto allocate_error; + status = AE_NO_MEMORY; } } @@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, /* Now we can actually delete the subtree rooted at Op */ acpi_ps_delete_parse_tree(op); - return_ACPI_STATUS(AE_OK); - - allocate_error: - - /* Always delete the subtree, even on error */ - - acpi_ps_delete_parse_tree(op); - return_ACPI_STATUS(AE_NO_MEMORY); + return_ACPI_STATUS(status); } /******************************************************************************* -- cgit v1.2.3 From cf058bd1c84df9921ecc517d8a8a413f4d6b5b45 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 11:29:57 +0800 Subject: ACPICA: Fix possible memory leak, error exit path Fixed two possible memory leaks in the error exit paths of acpi_ut_update_objerct_reference() and acpi_ut_walk_package_tree() These functions are similar in that they use a stack of state objects in order to eliminate recursion. The stack must be fully deallocated if an error occurs. http://www.acpica.org/bugzilla/show_bug.cgi?id=383 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/utilities/utdelete.c | 7 +++++++ drivers/acpi/utilities/utmisc.c | 9 +++++++++ 2 files changed, 16 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 5c219758c22..d197c6b29e1 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -585,6 +585,13 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action) ACPI_EXCEPTION((AE_INFO, status, "Could not update object reference count")); + /* Free any stacked Update State objects */ + + while (state_list) { + state = acpi_ut_pop_generic_state(&state_list); + acpi_ut_delete_generic_state(state); + } + return_ACPI_STATUS(status); } diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index f34be677355..9089a158a87 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -995,6 +995,15 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object, state->pkg. this_target_obj, 0); if (!state) { + + /* Free any stacked Update State objects */ + + while (state_list) { + state = + acpi_ut_pop_generic_state + (&state_list); + acpi_ut_delete_generic_state(state); + } return_ACPI_STATUS(AE_NO_MEMORY); } } -- cgit v1.2.3 From 68e125c40597802b9789bc696775bf0246e7667d Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 11:34:48 +0800 Subject: ACPICA: Optimize buffer allocation procedure Eliminate duplicate code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/utilities/utalloc.c | 53 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/utilities/utalloc.c b/drivers/acpi/utilities/utalloc.c index 7dcb67e0b21..241c535c175 100644 --- a/drivers/acpi/utilities/utalloc.c +++ b/drivers/acpi/utilities/utalloc.c @@ -232,7 +232,7 @@ acpi_status acpi_ut_validate_buffer(struct acpi_buffer * buffer) * RETURN: Status * * DESCRIPTION: Validate that the buffer is of the required length or - * allocate a new buffer. Returned buffer is always zeroed. + * allocate a new buffer. Returned buffer is always zeroed. * ******************************************************************************/ @@ -240,7 +240,7 @@ acpi_status acpi_ut_initialize_buffer(struct acpi_buffer * buffer, acpi_size required_length) { - acpi_status status = AE_OK; + acpi_size input_buffer_length; /* Parameter validation */ @@ -248,55 +248,58 @@ acpi_ut_initialize_buffer(struct acpi_buffer * buffer, return (AE_BAD_PARAMETER); } - switch (buffer->length) { + /* + * Buffer->Length is used as both an input and output parameter. Get the + * input actual length and set the output required buffer length. + */ + input_buffer_length = buffer->length; + buffer->length = required_length; + + /* + * The input buffer length contains the actual buffer length, or the type + * of buffer to be allocated by this routine. + */ + switch (input_buffer_length) { case ACPI_NO_BUFFER: - /* Set the exception and returned the required length */ + /* Return the exception (and the required buffer length) */ - status = AE_BUFFER_OVERFLOW; - break; + return (AE_BUFFER_OVERFLOW); case ACPI_ALLOCATE_BUFFER: /* Allocate a new buffer */ buffer->pointer = acpi_os_allocate(required_length); - if (!buffer->pointer) { - return (AE_NO_MEMORY); - } - - /* Clear the buffer */ - - ACPI_MEMSET(buffer->pointer, 0, required_length); break; case ACPI_ALLOCATE_LOCAL_BUFFER: /* Allocate a new buffer with local interface to allow tracking */ - buffer->pointer = ACPI_ALLOCATE_ZEROED(required_length); - if (!buffer->pointer) { - return (AE_NO_MEMORY); - } + buffer->pointer = ACPI_ALLOCATE(required_length); break; default: /* Existing buffer: Validate the size of the buffer */ - if (buffer->length < required_length) { - status = AE_BUFFER_OVERFLOW; - break; + if (input_buffer_length < required_length) { + return (AE_BUFFER_OVERFLOW); } + break; + } - /* Clear the buffer */ + /* Validate allocation from above or input buffer pointer */ - ACPI_MEMSET(buffer->pointer, 0, required_length); - break; + if (!buffer->pointer) { + return (AE_NO_MEMORY); } - buffer->length = required_length; - return (status); + /* Have a valid buffer, clear it */ + + ACPI_MEMSET(buffer->pointer, 0, required_length); + return (AE_OK); } #ifdef NOT_USED_BY_LINUX -- cgit v1.2.3 From d8a0ec914afa1a994d2f6184ac4c6668b5f8068f Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 11:50:24 +0800 Subject: ACPICA: Fixed a couple memory leaks associated with "implicit return" Fixed a couple memory leaks associated with "implicit return" objects when the AML Interpreter slack mode is enabled. http://www.acpica.org/bugzilla/show_bug.cgi?id=349 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dsmethod.c | 3 +++ drivers/acpi/parser/psparse.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 4613b9ca579..279a5a60a0d 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -103,6 +103,9 @@ acpi_ds_method_error(acpi_status status, struct acpi_walk_state *walk_state) NULL); acpi_ex_enter_interpreter(); } + + acpi_ds_clear_implicit_return(walk_state); + #ifdef ACPI_DISASSEMBLER if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 52caaf6582e..68e932f215e 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -635,10 +635,12 @@ acpi_status acpi_ps_parse_aml(struct acpi_walk_state *walk_state) ACPI_WALK_METHOD_RESTART; } } else { - /* On error, delete any return object */ + /* On error, delete any return object or implicit return */ acpi_ut_remove_reference(previous_walk_state-> return_desc); + acpi_ds_clear_implicit_return + (previous_walk_state); } } -- cgit v1.2.3 From b9d1312ad4246e467f333dfe2ac4dc7a79608d59 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Sat, 27 Sep 2008 12:01:12 +0800 Subject: ACPICA: Fix for implicit return compatibility Predicate can be used for an implicit return value. This change improves the implicit return mechanism to be more compatible with the MS interpreter. http://www.acpica.org/bugzilla/show_bug.cgi?id=349 Below AML code from http://bugzilla.kernel.org/show_bug.cgi?id=10686 Store(0x07D6, OSYS) Method (_CRT, 0, Serialized) { If (LLess (OSYS, 0x07D6)) { If (LEqual (\_SB.TJ85, Zero)) { Return (Add (0x0AAC, Multiply (TPC, 0x0A))) } Else { Return (Add (0x0AAC, Multiply (TP85, 0x0A))) } } } Previously _CRT returns 0x07D6, now it returns 0 (predicate value of LLess) Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/dispatcher/dswexec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/acpi') diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 5b2419197b9..396fe12078c 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -166,6 +166,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, status = AE_CTRL_FALSE; } + /* Predicate can be used for an implicit return value */ + + (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); + cleanup: ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n", -- cgit v1.2.3 From e8707b340fb5b6313cde784b944a568dfd770ddd Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sun, 28 Sep 2008 15:26:17 +0800 Subject: ACPICA: New: Validation for predefined ACPI methods/objects Validates predefined ACPI objects that appear in the namespace, at the time they are evaluated. The argument count and the type of the returned object are validated. The purpose of this validation is to detect problems with the BIOS-exposed predefined ACPI objects before the results are returned to the ACPI-related drivers. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/namespace/Makefile | 2 +- drivers/acpi/namespace/nseval.c | 35 +- drivers/acpi/namespace/nsnames.c | 2 - drivers/acpi/namespace/nspredef.c | 900 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 933 insertions(+), 6 deletions(-) create mode 100644 drivers/acpi/namespace/nspredef.c (limited to 'drivers/acpi') diff --git a/drivers/acpi/namespace/Makefile b/drivers/acpi/namespace/Makefile index 3f63d364069..371a2daf837 100644 --- a/drivers/acpi/namespace/Makefile +++ b/drivers/acpi/namespace/Makefile @@ -5,7 +5,7 @@ obj-y := nsaccess.o nsload.o nssearch.o nsxfeval.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ - nsparse.o + nsparse.o nspredef.o obj-$(ACPI_FUTURE_USAGE) += nsdumpdv.o diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 42dae12f2ef..4cdf03ac2b4 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -78,6 +78,7 @@ ACPI_MODULE_NAME("nseval") acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) { acpi_status status; + struct acpi_namespace_node *node; ACPI_FUNCTION_TRACE(ns_evaluate); @@ -117,6 +118,8 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) info->resolved_node, acpi_ns_get_attached_object(info->resolved_node))); + node = info->resolved_node; + /* * Two major cases here: * @@ -261,9 +264,35 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) } } - /* - * Check if there is a return value that must be dealt with - */ + /* Validation of return values for ACPI-predefined methods and objects */ + + if ((status == AE_OK) || (status == AE_CTRL_RETURN_VALUE)) { + /* + * If this is the first evaluation, check the return value. This + * ensures that any warnings will only be emitted during the very + * first evaluation of the object. + */ + if (!(node->flags & ANOBJ_EVALUATED)) { + /* + * Check for a predefined ACPI name. If found, validate the + * returned object. + * + * Note: Ignore return status for now, emit warnings if there are + * problems with the returned object. May change later to abort + * the method on invalid return object. + */ + (void)acpi_ns_check_predefined_names(node, + info-> + return_object); + } + + /* Mark the node as having been evaluated */ + + node->flags |= ANOBJ_EVALUATED; + } + + /* Check if there is a return value that must be dealt with */ + if (status == AE_CTRL_RETURN_VALUE) { /* If caller does not want the return value, delete it */ diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index 9c587bdfe3f..42a39a7c96e 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -115,7 +115,6 @@ acpi_ns_build_external_path(struct acpi_namespace_node *node, return (AE_OK); } -#ifdef ACPI_DEBUG_OUTPUT /******************************************************************************* * * FUNCTION: acpi_ns_get_external_pathname @@ -163,7 +162,6 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node) return_PTR(name_buffer); } -#endif /******************************************************************************* * diff --git a/drivers/acpi/namespace/nspredef.c b/drivers/acpi/namespace/nspredef.c new file mode 100644 index 00000000000..0f17cf0898c --- /dev/null +++ b/drivers/acpi/namespace/nspredef.c @@ -0,0 +1,900 @@ +/****************************************************************************** + * + * Module Name: nspredef - Validation of ACPI predefined methods and objects + * $Revision: 1.1 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2008, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include + +#define _COMPONENT ACPI_NAMESPACE +ACPI_MODULE_NAME("nspredef") + +/******************************************************************************* + * + * This module validates predefined ACPI objects that appear in the namespace, + * at the time they are evaluated (via acpi_evaluate_object). The purpose of this + * validation is to detect problems with BIOS-exposed predefined ACPI objects + * before the results are returned to the ACPI-related drivers. + * + * There are several areas that are validated: + * + * 1) The number of input arguments as defined by the method/object in the + * ASL is validated against the ACPI specification. + * 2) The type of the return object (if any) is validated against the ACPI + * specification. + * 3) For returned package objects, the count of package elements is + * validated, as well as the type of each package element. Nested + * packages are supported. + * + * For any problems found, a warning message is issued. + * + ******************************************************************************/ +/* Local prototypes */ +static acpi_status +acpi_ns_check_package(char *pathname, + union acpi_operand_object *return_object, + const union acpi_predefined_info *predefined); + +static acpi_status +acpi_ns_check_package_elements(char *pathname, + union acpi_operand_object **elements, + u8 type1, u32 count1, u8 type2, u32 count2); + +static acpi_status +acpi_ns_check_object_type(char *pathname, + union acpi_operand_object *return_object, + u32 expected_btypes, u32 package_index); + +static acpi_status +acpi_ns_check_reference(char *pathname, + union acpi_operand_object *return_object); + +/* + * Names for the types that can be returned by the predefined objects. + * Used for warning messages. Must be in the same order as the ACPI_RTYPEs + */ +static const char *acpi_rtype_names[] = { + "/Integer", + "/String", + "/Buffer", + "/Package", + "/Reference", +}; + +#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_predefined_names + * + * PARAMETERS: Node - Namespace node for the method/object + * return_object - Object returned from the evaluation of this + * method/object + * + * RETURN: Status + * + * DESCRIPTION: Check an ACPI name for a match in the predefined name list. + * + ******************************************************************************/ + +acpi_status +acpi_ns_check_predefined_names(struct acpi_namespace_node *node, + union acpi_operand_object *return_object) +{ + acpi_status status = AE_OK; + const union acpi_predefined_info *predefined; + char *pathname; + + /* Match the name for this method/object against the predefined list */ + + predefined = acpi_ns_check_for_predefined_name(node); + if (!predefined) { + + /* Name was not one of the predefined names */ + + return (AE_OK); + } + + /* Get the full pathname to the object, for use in error messages */ + + pathname = acpi_ns_get_external_pathname(node); + if (!pathname) { + pathname = ACPI_CAST_PTR(char, predefined->info.name); + } + + /* + * Check that the parameter count for this method is in accordance + * with the ACPI specification. + */ + acpi_ns_check_parameter_count(pathname, node, predefined); + + /* + * If there is no return value, check if we require a return value for + * this predefined name. Either one return value is expected, or none, + * for both methods and other objects. + * + * Exit now if there is no return object. Warning if one was expected. + */ + if (!return_object) { + if ((predefined->info.expected_btypes) && + (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { + ACPI_ERROR((AE_INFO, + "%s: Missing expected return value", + pathname)); + + status = AE_AML_NO_RETURN_VALUE; + } + goto exit; + } + + /* + * We have a return value, but if one wasn't expected, just exit, this is + * not a problem + * + * For example, if "Implicit return value" is enabled, methods will + * always return a value + */ + if (!predefined->info.expected_btypes) { + goto exit; + } + + /* + * Check that the type of the return object is what is expected for + * this predefined name + */ + status = acpi_ns_check_object_type(pathname, return_object, + predefined->info.expected_btypes, + ACPI_NOT_PACKAGE); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* For returned Package objects, check the type of all sub-objects */ + + if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) { + status = + acpi_ns_check_package(pathname, return_object, predefined); + } + + exit: + if (pathname) { + ACPI_FREE(pathname); + } + + return (status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_parameter_count + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * Node - Namespace node for the method/object + * Predefined - Pointer to entry in predefined name table + * + * RETURN: None + * + * DESCRIPTION: Check that the declared (in ASL/AML) parameter count for a + * predefined name is what is expected (i.e., what is defined in + * the ACPI specification for this predefined name.) + * + ******************************************************************************/ + +void +acpi_ns_check_parameter_count(char *pathname, + struct acpi_namespace_node *node, + const union acpi_predefined_info *predefined) +{ + u32 param_count; + u32 required_params_current; + u32 required_params_old; + + /* + * Check that the ASL-defined parameter count is what is expected for + * this predefined name. + * + * Methods have 0-7 parameters. All other types have zero. + */ + param_count = 0; + if (node->type == ACPI_TYPE_METHOD) { + param_count = node->object->method.param_count; + } + + /* Validate parameter count - allow two different legal counts (_SCP) */ + + required_params_current = predefined->info.param_count & 0x0F; + required_params_old = predefined->info.param_count >> 4; + + if ((param_count != required_params_current) && + (param_count != required_params_old)) { + ACPI_WARNING((AE_INFO, + "%s: Parameter count mismatch - ASL declared %d, expected %d", + pathname, param_count, required_params_current)); + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_for_predefined_name + * + * PARAMETERS: Node - Namespace node for the method/object + * + * RETURN: Pointer to entry in predefined table. NULL indicates not found. + * + * DESCRIPTION: Check an object name against the predefined object list. + * + ******************************************************************************/ + +const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct + acpi_namespace_node + *node) +{ + const union acpi_predefined_info *this_name; + + /* Quick check for a predefined name, first character must be underscore */ + + if (node->name.ascii[0] != '_') { + return (NULL); + } + + /* Search info table for a predefined method/object name */ + + this_name = predefined_names; + while (this_name->info.name[0]) { + if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { + + /* Return pointer to this table entry */ + + return (this_name); + } + + /* + * Skip next entry in the table if this name returns a Package + * (next entry contains the package info) + */ + if (this_name->info.expected_btypes & ACPI_RTYPE_PACKAGE) { + this_name++; + } + + this_name++; + } + + return (NULL); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_package + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * return_object - Object returned from the evaluation of a + * method or object + * Predefined - Pointer to entry in predefined name table + * + * RETURN: Status + * + * DESCRIPTION: Check a returned package object for the correct count and + * correct type of all sub-objects. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_check_package(char *pathname, + union acpi_operand_object *return_object, + const union acpi_predefined_info *predefined) +{ + const union acpi_predefined_info *package; + union acpi_operand_object *sub_package; + union acpi_operand_object **elements; + union acpi_operand_object **sub_elements; + acpi_status status; + u32 expected_count; + u32 count; + u32 i; + u32 j; + + ACPI_FUNCTION_NAME(ns_check_package); + + /* The package info for this name is in the next table entry */ + + package = predefined + 1; + + ACPI_DEBUG_PRINT((ACPI_DB_NAMES, + "%s Validating return Package of Type %X, Count %X\n", + pathname, package->ret_info.type, + return_object->package.count)); + + /* Extract package count and elements array */ + + elements = return_object->package.elements; + count = return_object->package.count; + + /* The package must have at least one element, else invalid */ + + if (!count) { + ACPI_WARNING((AE_INFO, + "%s: Return Package has no elements (empty)", + pathname)); + + return (AE_AML_OPERAND_VALUE); + } + + /* + * Decode the type of the expected package contents + * + * PTYPE1 packages contain no subpackages + * PTYPE2 packages contain sub-packages + */ + switch (package->ret_info.type) { + case ACPI_PTYPE1_FIXED: + + /* + * The package count is fixed and there are no sub-packages + * + * If package is too small, exit. + * If package is larger than expected, issue warning but continue + */ + expected_count = + package->ret_info.count1 + package->ret_info.count2; + if (count < expected_count) { + goto package_too_small; + } else if (count > expected_count) { + ACPI_WARNING((AE_INFO, + "%s: Return Package is larger than needed - " + "found %u, expected %u", pathname, count, + expected_count)); + } + + /* Validate all elements of the returned package */ + + status = acpi_ns_check_package_elements(pathname, elements, + package->ret_info. + object_type1, + package->ret_info. + count1, + package->ret_info. + object_type2, + package->ret_info. + count2); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_PTYPE1_VAR: + + /* + * The package count is variable, there are no sub-packages, and all + * elements must be of the same type + */ + for (i = 0; i < count; i++) { + status = acpi_ns_check_object_type(pathname, *elements, + package->ret_info. + object_type1, i); + if (ACPI_FAILURE(status)) { + return (status); + } + elements++; + } + break; + + case ACPI_PTYPE1_OPTION: + + /* + * The package count is variable, there are no sub-packages. There are + * a fixed number of required elements, and a variable number of + * optional elements. + * + * Check if package is at least as large as the minimum required + */ + expected_count = package->ret_info3.count; + if (count < expected_count) { + goto package_too_small; + } + + /* Variable number of sub-objects */ + + for (i = 0; i < count; i++) { + if (i < package->ret_info3.count) { + + /* These are the required package elements (0, 1, or 2) */ + + status = + acpi_ns_check_object_type(pathname, + *elements, + package-> + ret_info3. + object_type[i], + i); + if (ACPI_FAILURE(status)) { + return (status); + } + } else { + /* These are the optional package elements */ + + status = + acpi_ns_check_object_type(pathname, + *elements, + package-> + ret_info3. + tail_object_type, + i); + if (ACPI_FAILURE(status)) { + return (status); + } + } + elements++; + } + break; + + case ACPI_PTYPE2_PKG_COUNT: + + /* First element is the (Integer) count of sub-packages to follow */ + + status = acpi_ns_check_object_type(pathname, *elements, + ACPI_RTYPE_INTEGER, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* + * Count cannot be larger than the parent package length, but allow it + * to be smaller. The >= accounts for the Integer above. + */ + expected_count = (u32) (*elements)->integer.value; + if (expected_count >= count) { + goto package_too_small; + } + + count = expected_count; + elements++; + + /* Now we can walk the sub-packages */ + + /*lint -fallthrough */ + + case ACPI_PTYPE2: + case ACPI_PTYPE2_FIXED: + case ACPI_PTYPE2_MIN: + case ACPI_PTYPE2_COUNT: + + /* + * These types all return a single package that consists of a variable + * number of sub-packages + */ + for (i = 0; i < count; i++) { + sub_package = *elements; + sub_elements = sub_package->package.elements; + + /* Each sub-object must be of type Package */ + + status = + acpi_ns_check_object_type(pathname, sub_package, + ACPI_RTYPE_PACKAGE, i); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Examine the different types of sub-packages */ + + switch (package->ret_info.type) { + case ACPI_PTYPE2: + case ACPI_PTYPE2_PKG_COUNT: + + /* Each subpackage has a fixed number of elements */ + + expected_count = + package->ret_info.count1 + + package->ret_info.count2; + if (sub_package->package.count != + expected_count) { + count = sub_package->package.count; + goto package_too_small; + } + + status = + acpi_ns_check_package_elements(pathname, + sub_elements, + package-> + ret_info. + object_type1, + package-> + ret_info. + count1, + package-> + ret_info. + object_type2, + package-> + ret_info. + count2); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_PTYPE2_FIXED: + + /* Each sub-package has a fixed length */ + + expected_count = package->ret_info2.count; + if (sub_package->package.count < expected_count) { + count = sub_package->package.count; + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + for (j = 0; j < expected_count; j++) { + status = + acpi_ns_check_object_type(pathname, + sub_elements + [j], + package-> + ret_info2. + object_type + [j], j); + if (ACPI_FAILURE(status)) { + return (status); + } + } + break; + + case ACPI_PTYPE2_MIN: + + /* Each sub-package has a variable but minimum length */ + + expected_count = package->ret_info.count1; + if (sub_package->package.count < expected_count) { + count = sub_package->package.count; + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + status = + acpi_ns_check_package_elements(pathname, + sub_elements, + package-> + ret_info. + object_type1, + sub_package-> + package. + count, 0, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_PTYPE2_COUNT: + + /* First element is the (Integer) count of elements to follow */ + + status = + acpi_ns_check_object_type(pathname, + *sub_elements, + ACPI_RTYPE_INTEGER, + 0); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Make sure package is large enough for the Count */ + + expected_count = + (u32) (*sub_elements)->integer.value; + if (sub_package->package.count < expected_count) { + count = sub_package->package.count; + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + status = + acpi_ns_check_package_elements(pathname, + (sub_elements + + 1), + package-> + ret_info. + object_type1, + (expected_count + - 1), 0, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + default: + break; + } + + elements++; + } + break; + + default: + + /* Should not get here if predefined info table is correct */ + + ACPI_WARNING((AE_INFO, + "%s: Invalid internal return type in table entry: %X", + pathname, package->ret_info.type)); + + return (AE_AML_INTERNAL); + } + + return (AE_OK); + + package_too_small: + + /* Error exit for the case with an incorrect package count */ + + ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " + "found %u, expected %u", pathname, count, + expected_count)); + + return (AE_AML_OPERAND_VALUE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_package_elements + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * Elements - Pointer to the package elements array + * Type1 - Object type for first group + * Count1 - Count for first group + * Type2 - Object type for second group + * Count2 - Count for second group + * + * RETURN: Status + * + * DESCRIPTION: Check that all elements of a package are of the correct object + * type. Supports up to two groups of different object types. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_check_package_elements(char *pathname, + union acpi_operand_object **elements, + u8 type1, u32 count1, u8 type2, u32 count2) +{ + union acpi_operand_object **this_element = elements; + acpi_status status; + u32 i; + + /* + * Up to two groups of package elements are supported by the data + * structure. All elements in each group must be of the same type. + * The second group can have a count of zero. + */ + for (i = 0; i < count1; i++) { + status = acpi_ns_check_object_type(pathname, *this_element, + type1, i); + if (ACPI_FAILURE(status)) { + return (status); + } + this_element++; + } + + for (i = 0; i < count2; i++) { + status = acpi_ns_check_object_type(pathname, *this_element, + type2, (i + count1)); + if (ACPI_FAILURE(status)) { + return (status); + } + this_element++; + } + + return (AE_OK); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_object_type + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * return_object - Object return from the execution of this + * method/object + * expected_btypes - Bitmap of expected return type(s) + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE otherwise) + * + * RETURN: Status + * + * DESCRIPTION: Check the type of the return object against the expected object + * type(s). Use of Btype allows multiple expected object types. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_check_object_type(char *pathname, + union acpi_operand_object *return_object, + u32 expected_btypes, u32 package_index) +{ + acpi_status status = AE_OK; + u32 return_btype; + char type_buffer[48]; /* Room for 5 types */ + u32 this_rtype; + u32 i; + u32 j; + + /* + * If we get a NULL return_object here, it is a NULL package element, + * and this is always an error. + */ + if (!return_object) { + goto type_error_exit; + } + + /* A Namespace node should not get here, but make sure */ + + if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { + ACPI_WARNING((AE_INFO, + "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", + pathname, return_object->node.name.ascii, + acpi_ut_get_type_name(return_object->node.type))); + return (AE_AML_OPERAND_TYPE); + } + + /* + * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type. + * The bitmapped type allows multiple possible return types. + * + * Note, the cases below must handle all of the possible types returned + * from all of the predefined names (including elements of returned + * packages) + */ + switch (ACPI_GET_OBJECT_TYPE(return_object)) { + case ACPI_TYPE_INTEGER: + return_btype = ACPI_RTYPE_INTEGER; + break; + + case ACPI_TYPE_BUFFER: + return_btype = ACPI_RTYPE_BUFFER; + break; + + case ACPI_TYPE_STRING: + return_btype = ACPI_RTYPE_STRING; + break; + + case ACPI_TYPE_PACKAGE: + return_btype = ACPI_RTYPE_PACKAGE; + break; + + case ACPI_TYPE_LOCAL_REFERENCE: + return_btype = ACPI_RTYPE_REFERENCE; + break; + + default: + /* Not one of the supported objects, must be incorrect */ + + goto type_error_exit; + } + + /* Is the object one of the expected types? */ + + if (!(return_btype & expected_btypes)) { + goto type_error_exit; + } + + /* For reference objects, check that the reference type is correct */ + + if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) { + status = acpi_ns_check_reference(pathname, return_object); + } + + return (status); + + type_error_exit: + + /* Create a string with all expected types for this predefined object */ + + j = 1; + type_buffer[0] = 0; + this_rtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) { + + /* If one of the expected types, concatenate the name of this type */ + + if (expected_btypes & this_rtype) { + ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); + j = 0; /* Use name separator from now on */ + } + this_rtype <<= 1; /* Next Rtype */ + } + + if (package_index == ACPI_NOT_PACKAGE) { + ACPI_WARNING((AE_INFO, + "%s: Return type mismatch - found %s, expected %s", + pathname, + acpi_ut_get_object_type_name(return_object), + type_buffer)); + } else { + ACPI_WARNING((AE_INFO, + "%s: Return Package type mismatch at index %u - " + "found %s, expected %s", pathname, package_index, + acpi_ut_get_object_type_name(return_object), + type_buffer)); + } + + return (AE_AML_OPERAND_TYPE); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_reference + * + * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * return_object - Object returned from the evaluation of a + * method or object + * + * RETURN: Status + * + * DESCRIPTION: Check a returned reference object for the correct reference + * type. The only reference type that can be returned from a + * predefined method is a named reference. All others are invalid. + * + ******************************************************************************/ + +static acpi_status +acpi_ns_check_reference(char *pathname, + union acpi_operand_object *return_object) +{ + + /* + * Check the reference object for the correct reference type (opcode). + * The only type of reference that can be converted to an union acpi_object is + * a reference to a named object (reference class: NAME) + */ + if (return_object->reference.class == ACPI_REFCLASS_NAME) { + return (AE_OK); + } + + ACPI_WARNING((AE_INFO, + "%s: Return type mismatch - unexpected reference object type [%s] %2.2X", + pathname, acpi_ut_get_reference_name(return_object), + return_object->reference.class)); + + return (AE_AML_OPERAND_TYPE); +} -- cgit v1.2.3 From 4ca846e9270f305ad19e61f6654664f31459f332 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Sat, 27 Sep 2008 13:27:51 +0800 Subject: ACPICA: Add support for zero-length buffer-to-string conversions Allow zero length strings during interpreter buffer-to-string conversions. For example, during the ToDecimalString and ToHexString operaters, as well as implicit conversions. Fiodor Suietov. ACPICA BZ 585. http://www.acpica.org/bugzilla/show_bug.cgi?id=585 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/executer/exconvrt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/acpi') diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c index 890378e789a..1d1f35adddd 100644 --- a/drivers/acpi/executer/exconvrt.c +++ b/drivers/acpi/executer/exconvrt.c @@ -512,9 +512,14 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, /* * Create a new string object and string buffer * (-1 because of extra separator included in string_length from above) + * Allow creation of zero-length strings from zero-length buffers. */ + if (string_length) { + string_length--; + } + return_desc = acpi_ut_create_string_object((acpi_size) - (string_length - 1)); + string_length); if (!return_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -537,7 +542,9 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc, * Null terminate the string * (overwrites final comma/space from above) */ - new_buf--; + if (obj_desc->buffer.length) { + new_buf--; + } *new_buf = 0; break; -- cgit v1.2.3