]> err.no Git - linux-2.6/commitdiff
ACPI: ACPICA 20060707
authorBob Moore <robert.moore@intel.com>
Sat, 8 Jul 2006 00:44:38 +0000 (20:44 -0400)
committerLen Brown <len.brown@intel.com>
Sun, 9 Jul 2006 19:15:40 +0000 (15:15 -0400)
Added the ACPI_PACKED_POINTERS_NOT_SUPPORTED macro to
support C compilers that do not allow the initialization
of address pointers within packed structures - even though
the hardware itself may support misaligned transfers. Some
of the debug data structures are packed by default to
minimize size.

Added an error message for the case where
acpi_os_get_thread_id() returns zero. A non-zero value is
required by the core ACPICA code to ensure the proper
operation of AML mutexes and recursive control methods.

The DSDT is now the only ACPI table that determines whether
the AML interpreter is in 32-bit or 64-bit mode. Not really
a functional change, but the hooks for per-table 32/64
switching have been removed from the code. A clarification
to the ACPI specification is forthcoming in ACPI 3.0B.

Fixed a possible leak of an Owner ID in the error
path of tbinstal.c acpi_tb_init_table_descriptor() and
migrated all table OwnerID deletion to a single place in
acpi_tb_uninstall_table() to correct possible leaks when using
the acpi_tb_delete_tables_by_type() interface (with assistance
from Lance Ortiz.)

Fixed a problem with Serialized control methods where the
semaphore associated with the method could be over-signaled
after multiple method invocations.

Fixed two issues with the locking of the internal
namespace data structure. Both the Unload() operator and
acpi_unload_table() interface now lock the namespace during
the namespace deletion associated with the table unload
(with assistance from Linn Crosetto.)

Fixed problem reports (Valery Podrezov) integrated: -
Eliminate unnecessary memory allocation for CreateXxxxField
http://bugzilla.kernel.org/show_bug.cgi?id=5426

Fixed problem reports (Fiodor Suietov) integrated: -
Incomplete cleanup branches in AcpiTbGetTableRsdt (BZ 369)
- On Address Space handler deletion, needless deactivation
call (BZ 374) - AcpiRemoveAddressSpaceHandler: validate
Device handle parameter (BZ 375) - Possible memory leak,
Notify sub-objects of Processor, Power, ThermalZone (BZ
376) - AcpiRemoveAddressSpaceHandler: validate Handler
parameter (BZ 378) - Minimum Length of RSDT should be
validated (BZ 379) - AcpiRemoveNotifyHandler: return
AE_NOT_EXIST if Processor Obj has no Handler (BZ (380)
- AcpiUnloadTable: return AE_NOT_EXIST if no table of
specified type loaded (BZ 381)

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
21 files changed:
drivers/acpi/dispatcher/dsinit.c
drivers/acpi/dispatcher/dsmethod.c
drivers/acpi/dispatcher/dswexec.c
drivers/acpi/events/evregion.c
drivers/acpi/events/evxface.c
drivers/acpi/events/evxfregn.c
drivers/acpi/executer/exconfig.c
drivers/acpi/executer/exconvrt.c
drivers/acpi/executer/exsystem.c
drivers/acpi/namespace/nsalloc.c
drivers/acpi/tables/tbget.c
drivers/acpi/tables/tbinstal.c
drivers/acpi/tables/tbrsdt.c
drivers/acpi/tables/tbxface.c
drivers/acpi/utilities/utdelete.c
drivers/acpi/utilities/utmisc.c
drivers/acpi/utilities/utstate.c
include/acpi/acconfig.h
include/acpi/acinterp.h
include/acpi/aclocal.h
include/acpi/acresrc.h

index daf51b5b5875fd4978b8926d80931a19134c9806..1888c055d10f47f73fbbc1cbb175864121eb5970 100644 (file)
@@ -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;
 
index a39a33f4847aac07ff519dc5f89f6e2afebe7994..cf888add31917aa25a68429e46f700ebe0e462fa 100644 (file)
@@ -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 */
index b1ded62d0df1d343ffb1f3da6422fc66d712d8d1..d7a616c3104e9b8fe87394512b46f2c0ed0fac9c 100644 (file)
@@ -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;
index 094a17e4c86deec03416cd71cd39fd075e660751..21caae04fe85f868bcedddfc3e8ebc6a5b2f5c68 100644 (file)
@@ -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);
index 4f948df17ab975f15cc6a5d22c842a10332d55e1..923fd2b46955284a99a2baaa29eeec9c8086e45d 100644 (file)
@@ -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"));
index e8b86a0baad01f710121fe977d1d920d0606dcf9..83b12a9afa325827fe6148588bc5034efa3ce860 100644 (file)
@@ -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,
index 83fed079a276d02051fbb53751da2f98621e9bc2..c8341fa5fe01b87b785432d8ee210392b121e105 100644 (file)
@@ -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 */
 
index b732e399b1eff86abb6439ef0657ff9a5fda0272..544e81a6a438a349212a61930faa7dc3f92077d4 100644 (file)
@@ -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;
index 6b5d1e6ce94b1b823d9ff3634608254293d884bb..28aef3e69ecceeff2a2855854d3f59167ea905c5 100644 (file)
@@ -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.
  *
  ******************************************************************************/
 
index dc3f0739a46b3aee1c4208cb7f9e46a57ff82a89..55b407aae26612372d52f61867d50226f129e673 100644 (file)
@@ -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;
 }
index 99eacceff56384c83710e848c8715e3d242953fe..7856db759af0be7579abcd1733e74d1782455dbe 100644 (file)
@@ -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",
index 7ca2df75bb11909522f6388628f8a1fb8febefdc..1668a232fb6754fb3a0d571cf32cb443863cefa0 100644 (file)
@@ -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;
index abcb08c2592ae3f5ca128dfb4d60debd6f76ac9a..0ad3dbb9ebca377563a6a177ab092704f63545f8 100644 (file)
@@ -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);
 }
index 4e91f29848156d56ce70ac69dce507036bb746ed..7767987be15a0d517acf10fa5b6327b203e08f23 100644 (file)
@@ -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);
 }
 
index 38ebe1c543304e9258fb01fca4fc294240666b8e..9d3f1149ba217736e5ff8b376445e522f6f8a79f 100644 (file)
@@ -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:
index 33268310c73804be4249cfc258b80f788985c4db..6d8a8211be90a4f84abf2ad8efb62c8a3c9cabfa 100644 (file)
@@ -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);
 
index 0f5c5bb5deff29dd1e53a23153a8fa03f81055d5..eaa13d05c859cd0ec20ba6543984ada6da747ff3 100644 (file)
@@ -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);
 }
 
index b492857fe7213e51cf3262605f7e0ea11b009f4e..9e6c23c360b2c0076688abc3ffe2c7bfca4d72f0 100644 (file)
@@ -63,7 +63,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20060623
+#define ACPI_CA_VERSION                 0x20060707
 
 /*
  * OS name, used for the _OS object.  The _OS object is essentially obsolete,
index 216339a8f1f662114856c8448c50ebb069490beb..91586d0d5bb57f8d4ea26602bcd31aafbce391e3 100644 (file)
 #define ACPI_EXD_TABLE_SIZE(name)   (sizeof(name) / sizeof (struct acpi_exdump_info))
 
 /*
- * If possible, pack the following structure to byte alignment, since we
- * don't care about performance for debug output
+ * If possible, pack the following structures to byte alignment, since we
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
  */
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
 #pragma pack(1)
 #endif
 
index 56b8024861611ed6d77a8705801b260a07cfeda9..7010fea26b4849f265328d1e0ee7c7a4c0799697 100644 (file)
@@ -204,7 +204,7 @@ struct acpi_namespace_node {
 /* Namespace Node flags */
 
 #define ANOBJ_END_OF_PEER_LIST          0x01   /* End-of-list, Peer field points to parent */
-#define ANOBJ_DATA_WIDTH_32             0x02   /* Parent table uses 32-bit math */
+#define ANOBJ_RESERVED                  0x02   /* Available for future use */
 #define ANOBJ_METHOD_ARG                0x04   /* Node is a method argument */
 #define ANOBJ_METHOD_LOCAL              0x08   /* Node is a method local */
 #define ANOBJ_SUBTREE_HAS_INI           0x10   /* Used to optimize device initialization */
index ad11fc13fbefc933c7184c9a1b970682ee8c8559..80a3b33571b4c44df62457225e64d56f65a84fea 100644 (file)
 
 /*
  * If possible, pack the following structures to byte alignment, since we
- * don't care about performance for debug output
+ * don't care about performance for debug output. Two cases where we cannot
+ * pack the structures:
+ *
+ * 1) Hardware does not support misaligned memory transfers
+ * 2) Compiler does not support pointers within packed structures
  */
-#ifndef ACPI_MISALIGNMENT_NOT_SUPPORTED
+#if (!defined(ACPI_MISALIGNMENT_NOT_SUPPORTED) && !defined(ACPI_PACKED_POINTERS_NOT_SUPPORTED))
 #pragma pack(1)
 #endif