summaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2006-07-10 02:39:41 -0400
committerLen Brown <len.brown@intel.com>2006-07-10 02:39:41 -0400
commit0f12b15ebcedce115a5d8e5ff741e49a7993f67c (patch)
tree3bfea88873b2a43c5528b9687fa010b6eff23458 /drivers/acpi
parent20b499aa06edf59fa2d21f29d42d36586c6c058e (diff)
parentf6dd9221dddb3550e60d32aee688588ec208312c (diff)
downloadlinux-0f12b15ebcedce115a5d8e5ff741e49a7993f67c.tar.gz
linux-0f12b15ebcedce115a5d8e5ff741e49a7993f67c.tar.bz2
linux-0f12b15ebcedce115a5d8e5ff741e49a7993f67c.zip
Pull acpica-20060707 into test branch
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/dispatcher/dsinit.c10
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c23
-rw-r--r--drivers/acpi/dispatcher/dswexec.c4
-rw-r--r--drivers/acpi/events/evregion.c44
-rw-r--r--drivers/acpi/events/evxface.c44
-rw-r--r--drivers/acpi/events/evxfregn.c13
-rw-r--r--drivers/acpi/executer/exconfig.c1
-rw-r--r--drivers/acpi/executer/exconvrt.c3
-rw-r--r--drivers/acpi/executer/exsystem.c8
-rw-r--r--drivers/acpi/namespace/nsalloc.c13
-rw-r--r--drivers/acpi/tables/tbget.c12
-rw-r--r--drivers/acpi/tables/tbinstal.c21
-rw-r--r--drivers/acpi/tables/tbrsdt.c27
-rw-r--r--drivers/acpi/tables/tbxface.c32
-rw-r--r--drivers/acpi/utilities/utdelete.c13
-rw-r--r--drivers/acpi/utilities/utmisc.c25
-rw-r--r--drivers/acpi/utilities/utstate.c7
17 files changed, 194 insertions, 106 deletions
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
index daf51b5b5875..1888c055d10f 100644
--- a/drivers/acpi/dispatcher/dsinit.c
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -116,16 +116,6 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
case ACPI_TYPE_METHOD:
- /*
- * Set the execution data width (32 or 64) based upon the
- * revision number of the parent ACPI table.
- * TBD: This is really for possible future support of integer width
- * on a per-table basis. Currently, we just use a global for the width.
- */
- if (info->table_desc->pointer->revision == 1) {
- node->flags |= ANOBJ_DATA_WIDTH_32;
- }
-
info->method_count++;
break;
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index a39a33f4847a..cf888add3191 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -134,7 +134,7 @@ acpi_ds_create_method_mutex(union acpi_operand_object *method_desc)
union acpi_operand_object *mutex_desc;
acpi_status status;
- ACPI_FUNCTION_NAME(ds_create_method_mutex);
+ ACPI_FUNCTION_TRACE(ds_create_method_mutex);
/* Create the new mutex object */
@@ -493,7 +493,7 @@ acpi_ds_restart_control_method(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
"****Restart [%4.4s] Op %p ReturnValueFromCallee %p\n",
- (char *)&walk_state->method_node->name,
+ acpi_ut_get_node_name(walk_state->method_node),
walk_state->method_call_op, return_desc));
ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
@@ -610,6 +610,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
acpi_os_release_mutex(method_desc->method.mutex->mutex.
os_mutex);
+ method_desc->method.mutex->mutex.owner_thread = NULL;
}
}
@@ -620,27 +621,11 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
*/
method_node = walk_state->method_node;
- /* Lock namespace for possible update */
-
- status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
- if (ACPI_FAILURE(status)) {
- return_VOID;
- }
-
- /*
- * Delete any namespace entries created immediately underneath
- * the method
- */
- if (method_node && method_node->child) {
- acpi_ns_delete_namespace_subtree(method_node);
- }
-
/*
- * Delete any namespace entries created anywhere else within
+ * Delete any namespace objects created anywhere within
* the namespace by the execution of this method
*/
acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id);
- status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
}
/* Decrement the thread count on the method */
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
index b1ded62d0df1..d7a616c3104e 100644
--- a/drivers/acpi/dispatcher/dswexec.c
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -313,10 +313,10 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
case AML_CLASS_EXECUTE:
case AML_CLASS_CREATE:
/*
- * Most operators with arguments.
+ * Most operators with arguments (except create_xxx_field operators)
* Start a new result/operand state
*/
- if (walk_state->opcode != AML_CREATE_FIELD_OP) {
+ if (walk_state->op_info->object_type != ACPI_TYPE_BUFFER_FIELD) {
status = acpi_ds_result_stack_push(walk_state);
}
break;
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index 094a17e4c86d..21caae04fe85 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -528,34 +528,40 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj,
}
}
- /* Call the setup handler with the deactivate notification */
+ /*
+ * If the region has been activated, call the setup handler
+ * with the deactivate notification
+ */
+ if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
+ region_setup = handler_obj->address_space.setup;
+ status =
+ region_setup(region_obj,
+ ACPI_REGION_DEACTIVATE,
+ handler_obj->address_space.
+ context, region_context);
- region_setup = handler_obj->address_space.setup;
- status =
- region_setup(region_obj, ACPI_REGION_DEACTIVATE,
- handler_obj->address_space.context,
- region_context);
+ /* Init routine may fail, Just ignore errors */
- /* Init routine may fail, Just ignore errors */
+ if (ACPI_FAILURE(status)) {
+ ACPI_EXCEPTION((AE_INFO, status,
+ "from region handler - deactivate, [%s]",
+ acpi_ut_get_region_name
+ (region_obj->region.
+ space_id)));
+ }
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status,
- "from region init, [%s]",
- acpi_ut_get_region_name
- (region_obj->region.space_id)));
+ region_obj->region.flags &=
+ ~(AOPOBJ_SETUP_COMPLETE);
}
- region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
-
/*
* Remove handler reference in the region
*
- * NOTE: this doesn't mean that the region goes away
- * The region is just inaccessible as indicated to
- * the _REG method
+ * NOTE: this doesn't mean that the region goes away, the region
+ * is just inaccessible as indicated to the _REG method
*
- * If the region is on the handler's list
- * this better be the region's handler
+ * If the region is on the handler's list, this must be the
+ * region's handler
*/
region_obj->region.handler = NULL;
acpi_ut_remove_reference(handler_obj);
diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c
index 4f948df17ab9..923fd2b46955 100644
--- a/drivers/acpi/events/evxface.c
+++ b/drivers/acpi/events/evxface.c
@@ -428,7 +428,7 @@ acpi_remove_notify_handler(acpi_handle device,
node = acpi_ns_map_handle_to_node(device);
if (!node) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Root Object */
@@ -442,7 +442,7 @@ acpi_remove_notify_handler(acpi_handle device,
((handler_type & ACPI_DEVICE_NOTIFY) &&
!acpi_gbl_device_notify.handler)) {
status = AE_NOT_EXIST;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -474,7 +474,7 @@ acpi_remove_notify_handler(acpi_handle device,
if (!acpi_ev_is_notify_object(node)) {
status = AE_TYPE;
- goto unlock;
+ goto unlock_and_exit;
}
/* Check for an existing internal object */
@@ -482,17 +482,21 @@ acpi_remove_notify_handler(acpi_handle device,
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
status = AE_NOT_EXIST;
- goto unlock;
+ goto unlock_and_exit;
}
/* Object exists - make sure there's an existing handler */
if (handler_type & ACPI_SYSTEM_NOTIFY) {
notify_obj = obj_desc->common_notify.system_notify;
- if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ if (!notify_obj) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ if (notify_obj->notify.handler != handler) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -510,10 +514,14 @@ acpi_remove_notify_handler(acpi_handle device,
if (handler_type & ACPI_DEVICE_NOTIFY) {
notify_obj = obj_desc->common_notify.device_notify;
- if ((!notify_obj) ||
- (notify_obj->notify.handler != handler)) {
+ if (!notify_obj) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ if (notify_obj->notify.handler != handler) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure all deferred tasks are completed */
@@ -530,9 +538,9 @@ acpi_remove_notify_handler(acpi_handle device,
}
}
-unlock:
+ unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
-exit:
+ exit:
if (ACPI_FAILURE(status))
ACPI_EXCEPTION((AE_INFO, status, "Removing notify handler"));
return_ACPI_STATUS(status);
@@ -586,7 +594,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
- goto unlock;
+ goto unlock_and_exit;
}
/* Make sure that there isn't a handler there already */
@@ -594,7 +602,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
status = AE_ALREADY_EXISTS;
- goto unlock;
+ goto unlock_and_exit;
}
/* Allocate and init handler object */
@@ -602,7 +610,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info));
if (!handler) {
status = AE_NO_MEMORY;
- goto unlock;
+ goto unlock_and_exit;
}
handler->address = address;
@@ -613,7 +621,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
status = acpi_ev_disable_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
- goto unlock;
+ goto unlock_and_exit;
}
/* Install the handler */
@@ -628,9 +636,9 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
-unlock:
+ unlock_and_exit:
(void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
-exit:
+ exit:
if (ACPI_FAILURE(status))
ACPI_EXCEPTION((AE_INFO, status,
"Installing notify handler failed"));
diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c
index e8b86a0baad0..83b12a9afa32 100644
--- a/drivers/acpi/events/evxfregn.c
+++ b/drivers/acpi/events/evxfregn.c
@@ -155,7 +155,11 @@ acpi_remove_address_space_handler(acpi_handle device,
/* Convert and validate the device handle */
node = acpi_ns_map_handle_to_node(device);
- if (!node) {
+ if (!node ||
+ ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_PROCESSOR) &&
+ (node->type != ACPI_TYPE_THERMAL) &&
+ (node != acpi_gbl_root_node))) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
@@ -178,6 +182,13 @@ acpi_remove_address_space_handler(acpi_handle device,
if (handler_obj->address_space.space_id == space_id) {
+ /* Handler must be the same as the installed handler */
+
+ if (handler_obj->address_space.handler != handler) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+
/* Matched space_id, first dereference this in the Regions */
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 83fed079a276..c8341fa5fe01 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -502,7 +502,6 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
* (Offset contains the table_id)
*/
acpi_ns_delete_namespace_by_owner(table_info->owner_id);
- acpi_ut_release_owner_id(&table_info->owner_id);
/* Delete the table itself */
diff --git a/drivers/acpi/executer/exconvrt.c b/drivers/acpi/executer/exconvrt.c
index b732e399b1ef..544e81a6a438 100644
--- a/drivers/acpi/executer/exconvrt.c
+++ b/drivers/acpi/executer/exconvrt.c
@@ -170,6 +170,9 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
return_ACPI_STATUS(AE_NO_MEMORY);
}
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(result)));
+
/* Save the Result */
return_desc->integer.value = result;
diff --git a/drivers/acpi/executer/exsystem.c b/drivers/acpi/executer/exsystem.c
index 6b5d1e6ce94b..28aef3e69ecc 100644
--- a/drivers/acpi/executer/exsystem.c
+++ b/drivers/acpi/executer/exsystem.c
@@ -60,7 +60,7 @@ ACPI_MODULE_NAME("exsystem")
*
* DESCRIPTION: Implements a semaphore wait with a check to see if the
* semaphore is available immediately. If it is not, the
- * interpreter is released.
+ * interpreter is released before waiting.
*
******************************************************************************/
acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
@@ -110,9 +110,9 @@ acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
*
* RETURN: Status
*
- * DESCRIPTION: Implements a semaphore wait with a check to see if the
- * semaphore is available immediately. If it is not, the
- * interpreter is released.
+ * DESCRIPTION: Implements a mutex wait with a check to see if the
+ * mutex is available immediately. If it is not, the
+ * interpreter is released before waiting.
*
******************************************************************************/
diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c
index dc3f0739a46b..55b407aae266 100644
--- a/drivers/acpi/namespace/nsalloc.c
+++ b/drivers/acpi/namespace/nsalloc.c
@@ -386,14 +386,17 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
* specific ID. Used to delete entire ACPI tables. All
* reference counts are updated.
*
+ * MUTEX: Locks namespace during deletion walk.
+ *
******************************************************************************/
void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
{
struct acpi_namespace_node *child_node;
struct acpi_namespace_node *deletion_node;
- u32 level;
struct acpi_namespace_node *parent_node;
+ u32 level;
+ acpi_status status;
ACPI_FUNCTION_TRACE_U32(ns_delete_namespace_by_owner, owner_id);
@@ -401,6 +404,13 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
return_VOID;
}
+ /* Lock namespace for possible update */
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_VOID;
+ }
+
deletion_node = NULL;
parent_node = acpi_gbl_root_node;
child_node = NULL;
@@ -469,5 +479,6 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
}
}
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
return_VOID;
}
diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c
index 99eacceff563..7856db759af0 100644
--- a/drivers/acpi/tables/tbget.c
+++ b/drivers/acpi/tables/tbget.c
@@ -320,6 +320,16 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
ACPI_FUNCTION_TRACE(tb_get_this_table);
+ /* Validate minimum length */
+
+ if (header->length < sizeof(struct acpi_table_header)) {
+ ACPI_ERROR((AE_INFO,
+ "Table length (%X) is smaller than minimum (%X)",
+ header->length, sizeof(struct acpi_table_header)));
+
+ return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+ }
+
/*
* Flags contains the current processor mode (Virtual or Physical
* addressing) The pointer_type is either Logical or Physical
@@ -356,7 +366,7 @@ acpi_tb_get_this_table(struct acpi_pointer *address,
*/
status = acpi_os_map_memory(address->pointer.physical,
(acpi_size) header->length,
- (void *)&full_table);
+ ACPI_CAST_PTR(void, &full_table));
if (ACPI_FAILURE(status)) {
ACPI_ERROR((AE_INFO,
"Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X",
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index 7ca2df75bb11..1668a232fb67 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -256,7 +256,7 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
status = acpi_ut_allocate_owner_id(&table_desc->owner_id);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_exit1;
}
/* Install the table into the global data structure */
@@ -274,8 +274,8 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
* at this location, so return an error.
*/
if (list_head->next) {
- ACPI_FREE(table_desc);
- return_ACPI_STATUS(AE_ALREADY_EXISTS);
+ status = AE_ALREADY_EXISTS;
+ goto error_exit2;
}
table_desc->next = list_head->next;
@@ -335,6 +335,17 @@ acpi_tb_init_table_descriptor(acpi_table_type table_type,
table_info->owner_id = table_desc->owner_id;
table_info->installed_desc = table_desc;
return_ACPI_STATUS(AE_OK);
+
+ /* Error exit with cleanup */
+
+ error_exit2:
+
+ acpi_ut_release_owner_id(&table_desc->owner_id);
+
+ error_exit1:
+
+ ACPI_FREE(table_desc);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -525,6 +536,10 @@ struct acpi_table_desc *acpi_tb_uninstall_table(struct acpi_table_desc
acpi_tb_delete_single_table(table_desc);
+ /* Free the owner ID associated with this table */
+
+ acpi_ut_release_owner_id(&table_desc->owner_id);
+
/* Free the table descriptor */
next_desc = table_desc->next;
diff --git a/drivers/acpi/tables/tbrsdt.c b/drivers/acpi/tables/tbrsdt.c
index abcb08c2592a..0ad3dbb9ebca 100644
--- a/drivers/acpi/tables/tbrsdt.c
+++ b/drivers/acpi/tables/tbrsdt.c
@@ -183,6 +183,17 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
ACPI_FUNCTION_ENTRY();
+ /* Validate minimum length */
+
+ if (table_ptr->length < sizeof(struct acpi_table_header)) {
+ ACPI_ERROR((AE_INFO,
+ "RSDT/XSDT length (%X) is smaller than minimum (%X)",
+ table_ptr->length,
+ sizeof(struct acpi_table_header)));
+
+ return (AE_INVALID_TABLE_LENGTH);
+ }
+
/* Search for appropriate signature, RSDT or XSDT */
if (acpi_gbl_root_table_type == ACPI_TABLE_TYPE_RSDT) {
@@ -210,7 +221,7 @@ acpi_status acpi_tb_validate_rsdt(struct acpi_table_header *table_ptr)
ACPI_ERROR((AE_INFO, "Looking for XSDT"));
}
- ACPI_DUMP_BUFFER((char *)table_ptr, 48);
+ ACPI_DUMP_BUFFER(ACPI_CAST_PTR(char, table_ptr), 48);
return (AE_BAD_SIGNATURE);
}
@@ -258,7 +269,7 @@ acpi_status acpi_tb_get_table_rsdt(void)
status = acpi_tb_validate_rsdt(table_info.pointer);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
/* Get the number of tables defined in the RSDT or XSDT */
@@ -270,14 +281,14 @@ acpi_status acpi_tb_get_table_rsdt(void)
status = acpi_tb_convert_to_xsdt(&table_info);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
/* Save the table pointers and allocation info */
status = acpi_tb_init_table_descriptor(ACPI_TABLE_ID_XSDT, &table_info);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto error_cleanup;
}
acpi_gbl_XSDT =
@@ -285,4 +296,12 @@ acpi_status acpi_tb_get_table_rsdt(void)
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "XSDT located at %p\n", acpi_gbl_XSDT));
return_ACPI_STATUS(status);
+
+ error_cleanup:
+
+ /* Free table allocated by acpi_tb_get_table */
+
+ acpi_tb_delete_single_table(&table_info);
+
+ return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 4e91f2984815..7767987be15a 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -134,8 +134,8 @@ ACPI_EXPORT_SYMBOL(acpi_load_tables)
* RETURN: Status
*
* DESCRIPTION: This function is called to load a table from the caller's
- * buffer. The buffer must contain an entire ACPI Table including
- * a valid header. The header fields will be verified, and if it
+ * buffer. The buffer must contain an entire ACPI Table including
+ * a valid header. The header fields will be verified, and if it
* is determined that the table is invalid, the call will fail.
*
******************************************************************************/
@@ -245,15 +245,18 @@ acpi_status acpi_unload_table(acpi_table_type table_type)
/* Find all tables of the requested type */
table_desc = acpi_gbl_table_lists[table_type].next;
+ if (!table_desc) {
+ return_ACPI_STATUS(AE_NOT_EXIST);
+ }
+
while (table_desc) {
/*
- * Delete all namespace entries owned by this table. Note that these
- * entries can appear anywhere in the namespace by virtue of the AML
- * "Scope" operator. Thus, we need to track ownership by an ID, not
+ * Delete all namespace objects owned by this table. Note that these
+ * objects can appear anywhere in the namespace by virtue of the AML
+ * "Scope" operator. Thus, we need to track ownership by an ID, not
* simply a position within the hierarchy
*/
acpi_ns_delete_namespace_by_owner(table_desc->owner_id);
- acpi_ut_release_owner_id(&table_desc->owner_id);
table_desc = table_desc->next;
}
@@ -275,12 +278,12 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table)
* see acpi_gbl_acpi_table_flag
* out_table_header - pointer to the struct acpi_table_header if successful
*
- * DESCRIPTION: This function is called to get an ACPI table header. The caller
+ * DESCRIPTION: This function is called to get an ACPI table header. The caller
* supplies an pointer to a data area sufficient to contain an ACPI
* struct acpi_table_header structure.
*
* The header contains a length field that can be used to determine
- * the size of the buffer needed to contain the entire table. This
+ * the size of the buffer needed to contain the entire table. This
* function is not valid for the RSD PTR table since it does not
* have a standard header and is fixed length.
*
@@ -322,7 +325,8 @@ acpi_get_table_header(acpi_table_type table_type,
/* Copy the header to the caller's buffer */
- ACPI_MEMCPY((void *)out_table_header, (void *)tbl_ptr,
+ ACPI_MEMCPY(ACPI_CAST_PTR(void, out_table_header),
+ ACPI_CAST_PTR(void, tbl_ptr),
sizeof(struct acpi_table_header));
return_ACPI_STATUS(status);
@@ -344,10 +348,10 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_header)
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to get an ACPI table. The caller
+ * DESCRIPTION: This function is called to get an ACPI table. The caller
* supplies an out_buffer large enough to contain the entire ACPI
- * table. The caller should call the acpi_get_table_header function
- * first to determine the buffer size needed. Upon completion
+ * table. The caller should call the acpi_get_table_header function
+ * first to determine the buffer size needed. Upon completion
* the out_buffer->Length field will indicate the number of bytes
* copied into the out_buffer->buf_ptr buffer. This table will be
* a complete table including the header.
@@ -417,7 +421,9 @@ acpi_get_table(acpi_table_type table_type,
/* Copy the table to the buffer */
- ACPI_MEMCPY((void *)ret_buffer->pointer, (void *)tbl_ptr, table_length);
+ ACPI_MEMCPY(ACPI_CAST_PTR(void, ret_buffer->pointer),
+ ACPI_CAST_PTR(void, tbl_ptr), table_length);
+
return_ACPI_STATUS(AE_OK);
}
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index 38ebe1c54330..9d3f1149ba21 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -447,11 +447,16 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
*/
switch (ACPI_GET_OBJECT_TYPE(object)) {
case ACPI_TYPE_DEVICE:
+ case ACPI_TYPE_PROCESSOR:
+ case ACPI_TYPE_POWER:
+ case ACPI_TYPE_THERMAL:
- acpi_ut_update_ref_count(object->device.system_notify,
- action);
- acpi_ut_update_ref_count(object->device.device_notify,
- action);
+ /* Update the notify objects for these types (if present) */
+
+ acpi_ut_update_ref_count(object->common_notify.
+ system_notify, action);
+ acpi_ut_update_ref_count(object->common_notify.
+ device_notify, action);
break;
case ACPI_TYPE_PACKAGE:
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 33268310c738..6d8a8211be90 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -65,7 +65,7 @@ ACPI_MODULE_NAME("utmisc")
u8 acpi_ut_is_aml_table(struct acpi_table_header *table)
{
- /* Ignore tables that contain AML */
+ /* These are the only tables that contain executable AML */
if (ACPI_COMPARE_NAME(table->signature, DSDT_SIG) ||
ACPI_COMPARE_NAME(table->signature, PSDT_SIG) ||
@@ -419,10 +419,15 @@ void acpi_ut_set_integer_width(u8 revision)
{
if (revision <= 1) {
+
+ /* 32-bit case */
+
acpi_gbl_integer_bit_width = 32;
acpi_gbl_integer_nybble_width = 8;
acpi_gbl_integer_byte_width = 4;
} else {
+ /* 64-bit case (ACPI 2.0+) */
+
acpi_gbl_integer_bit_width = 64;
acpi_gbl_integer_nybble_width = 16;
acpi_gbl_integer_byte_width = 8;
@@ -502,6 +507,7 @@ acpi_ut_display_init_pathname(u8 type,
* FUNCTION: acpi_ut_valid_acpi_char
*
* PARAMETERS: Char - The character to be examined
+ * Position - Byte position (0-3)
*
* RETURN: TRUE if the character is valid, FALSE otherwise
*
@@ -609,7 +615,9 @@ acpi_name acpi_ut_repair_name(acpi_name name)
*
* RETURN: Status and Converted value
*
- * DESCRIPTION: Convert a string into an unsigned value.
+ * DESCRIPTION: Convert a string into an unsigned value. Performs either a
+ * 32-bit or 64-bit conversion, depending on the current mode
+ * of the interpreter.
* NOTE: Does not support Octal strings, not needed.
*
******************************************************************************/
@@ -627,7 +635,7 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
u8 sign_of0x = 0;
u8 term = 0;
- ACPI_FUNCTION_TRACE(ut_stroul64);
+ ACPI_FUNCTION_TRACE_STR(ut_stroul64, string);
switch (base) {
case ACPI_ANY_BASE:
@@ -675,11 +683,13 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
}
}
+ /*
+ * Perform a 32-bit or 64-bit conversion, depending upon the current
+ * execution mode of the interpreter
+ */
dividend = (mode32) ? ACPI_UINT32_MAX : ACPI_UINT64_MAX;
- /* At least one character in the string here */
-
- /* Main loop: convert the string to a 64-bit integer */
+ /* Main loop: convert the string to a 32- or 64-bit integer */
while (*string) {
if (ACPI_IS_DIGIT(*string)) {
@@ -754,6 +764,9 @@ acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer)
all_done:
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Converted value: %8.8X%8.8X\n",
+ ACPI_FORMAT_UINT64(return_value)));
+
*ret_integer = return_value;
return_ACPI_STATUS(AE_OK);
diff --git a/drivers/acpi/utilities/utstate.c b/drivers/acpi/utilities/utstate.c
index 0f5c5bb5deff..eaa13d05c859 100644
--- a/drivers/acpi/utilities/utstate.c
+++ b/drivers/acpi/utilities/utstate.c
@@ -199,6 +199,13 @@ struct acpi_thread_state *acpi_ut_create_thread_state(void)
state->common.descriptor_type = ACPI_DESC_TYPE_STATE_THREAD;
state->thread.thread_id = acpi_os_get_thread_id();
+ /* Check for invalid thread ID - zero is very bad, it will break things */
+
+ if (!state->thread.thread_id) {
+ ACPI_ERROR((AE_INFO, "Invalid zero ID from AcpiOsGetThreadId"));
+ state->thread.thread_id = (acpi_thread_id) 1;
+ }
+
return_PTR((struct acpi_thread_state *)state);
}