]> err.no Git - linux-2.6/commitdiff
ACPICA: New interfaces for table event handlers
authorLin Ming <ming.m.lin@intel.com>
Thu, 10 Apr 2008 15:06:38 +0000 (19:06 +0400)
committerLen Brown <len.brown@intel.com>
Tue, 22 Apr 2008 18:29:24 +0000 (14:29 -0400)
Designed and implemented new external interfaces to install and
remove handlers for ACPI table-related events. Current events that
are defined are LOAD and UNLOAD. These interfaces allow the host to
track ACPI tables as they are dynamically loaded and unloaded. See
AcpiInstallTableHandler and AcpiRemoveTableHandler.

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/executer/exconfig.c
drivers/acpi/tables/tbxface.c
drivers/acpi/utilities/utglobal.c
include/acpi/acdisasm.h
include/acpi/acglobal.h
include/acpi/acpixf.h
include/acpi/actypes.h

index 25802f302ffe18c00608ff5ae347f79931b57645..009aef5fcbfc6c4ed353518c1f18be3cf68d05fc 100644 (file)
@@ -234,6 +234,13 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
                           table->oem_table_id));
        }
 
+       /* Invoke table handler if present */
+
+       if (acpi_gbl_table_handler) {
+               (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
+                                            acpi_gbl_table_handler_context);
+       }
+
        *return_desc = ddb_handle;
        return_ACPI_STATUS(status);
 }
@@ -352,6 +359,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(status);
        }
 
+       /* Invoke table handler if present */
+
+       if (acpi_gbl_table_handler) {
+               (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD,
+                                            table_desc.pointer,
+                                            acpi_gbl_table_handler_context);
+       }
+
       cleanup:
        if (ACPI_FAILURE(status)) {
                acpi_tb_delete_table(&table_desc);
@@ -376,6 +391,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        acpi_status status = AE_OK;
        union acpi_operand_object *table_desc = ddb_handle;
        acpi_native_uint table_index;
+       struct acpi_table_header *table;
 
        ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -395,6 +411,17 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 
        table_index = (acpi_native_uint) table_desc->reference.object;
 
+       /* Invoke table handler if present */
+
+       if (acpi_gbl_table_handler) {
+               status = acpi_get_table_by_index(table_index, &table);
+               if (ACPI_SUCCESS(status)) {
+                       (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
+                                                    table,
+                                                    acpi_gbl_table_handler_context);
+               }
+       }
+
        /*
         * Delete the entire namespace under this table Node
         * (Offset contains the table_id)
@@ -407,5 +434,5 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        /* Delete the table descriptor (ddb_handle) */
 
        acpi_ut_remove_reference(table_desc);
-       return_ACPI_STATUS(status);
+       return_ACPI_STATUS(AE_OK);
 }
index a9e3331fee5deade7a3e8047a3c9da980e103f25..5f2271542a9664b2d49cc2f793829fbeeca71591 100644 (file)
@@ -635,6 +635,95 @@ acpi_status acpi_load_tables(void)
 ACPI_EXPORT_SYMBOL(acpi_load_tables)
 
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_install_table_handler
+ *
+ * PARAMETERS:  Handler         - Table event handler
+ *              Context         - Value passed to the handler on each event
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install table event handler
+ *
+ ******************************************************************************/
+acpi_status
+acpi_install_table_handler(acpi_tbl_handler handler, void *context)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_install_table_handler);
+
+       if (!handler) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Don't allow more than one handler */
+
+       if (acpi_gbl_table_handler) {
+               status = AE_ALREADY_EXISTS;
+               goto cleanup;
+       }
+
+       /* Install the handler */
+
+       acpi_gbl_table_handler = handler;
+       acpi_gbl_table_handler_context = context;
+
+      cleanup:
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_install_table_handler)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_remove_table_handler
+ *
+ * PARAMETERS:  Handler         - Table event handler that was installed
+ *                                previously.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove table event handler
+ *
+ ******************************************************************************/
+acpi_status acpi_remove_table_handler(acpi_tbl_handler handler)
+{
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_remove_table_handler);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Make sure that the installed handler is the same */
+
+       if (!handler || handler != acpi_gbl_table_handler) {
+               status = AE_BAD_PARAMETER;
+               goto cleanup;
+       }
+
+       /* Remove the handler */
+
+       acpi_gbl_table_handler = NULL;
+
+      cleanup:
+       (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
+       return_ACPI_STATUS(status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_remove_table_handler)
+
+
 static int __init acpi_no_auto_ssdt_setup(char *s) {
 
         printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
index 630c9a2c5b7bd78887c4eab62924fcde075925b8..44425433075a72d72c2ff2f3d745b6d3e2f31ac1 100644 (file)
@@ -675,12 +675,13 @@ void acpi_ut_init_globals(void)
        acpi_gbl_gpe_fadt_blocks[0] = NULL;
        acpi_gbl_gpe_fadt_blocks[1] = NULL;
 
-       /* Global notify handlers */
+       /* Global handlers */
 
        acpi_gbl_system_notify.handler = NULL;
        acpi_gbl_device_notify.handler = NULL;
        acpi_gbl_exception_handler = NULL;
        acpi_gbl_init_handler = NULL;
+       acpi_gbl_table_handler = NULL;
 
        /* Global Lock support */
 
index 75c354f7a0240cac82bb63b1239156302950cda7..67d152e7fa4443c307922afa1d7483748a6b1402 100644 (file)
@@ -104,12 +104,12 @@ typedef const struct acpi_dmtable_info {
 #define ACPI_DMT_SIG                    27
 
 typedef
-void (*ACPI_TABLE_HANDLER) (struct acpi_table_header * table);
+void (*acpi_dmtable_handler) (struct acpi_table_header * table);
 
 struct acpi_dmtable_data {
        char *signature;
        struct acpi_dmtable_info *table_info;
-       ACPI_TABLE_HANDLER table_handler;
+       acpi_dmtable_handler table_handler;
        char *name;
 };
 
index 44e718ee15797c4d8ff929a5e3b88cdecc75e517..862468616217bdf3b124bd429e35cabcf7a0f008 100644 (file)
@@ -217,6 +217,8 @@ ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
 ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
 ACPI_EXTERN acpi_exception_handler acpi_gbl_exception_handler;
 ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
+ACPI_EXTERN acpi_tbl_handler acpi_gbl_table_handler;
+ACPI_EXTERN void *acpi_gbl_table_handler_context;
 ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
 
 /* Owner ID support */
index d970f7f99549639183b73d8324043c2805020dd5..c92acda1a77fbdc38bbb56b744d617e30bdf363d 100644 (file)
@@ -119,6 +119,11 @@ acpi_status
 acpi_get_table_by_index(acpi_native_uint table_index,
                        struct acpi_table_header **out_table);
 
+acpi_status
+acpi_install_table_handler(acpi_tbl_handler handler, void *context);
+
+acpi_status acpi_remove_table_handler(acpi_tbl_handler handler);
+
 /*
  * Namespace and name interfaces
  */
index 6182b57590ef03dedfc029f447b36912ab9c96a7..766178c6cc816d199569ce2b23e0570d7cfbd5c0 100644 (file)
@@ -730,6 +730,12 @@ struct acpi_system_info {
        u32 debug_layer;
 };
 
+/* Table Event Types */
+
+#define ACPI_TABLE_EVENT_LOAD           0x0
+#define ACPI_TABLE_EVENT_UNLOAD         0x1
+#define ACPI_NUM_TABLE_EVENTS           2
+
 /*
  * Types specific to the OS service interfaces
  */
@@ -759,6 +765,11 @@ acpi_status(*acpi_exception_handler) (acpi_status aml_status,
                                      u16 opcode,
                                      u32 aml_offset, void *context);
 
+/* Table Event handler (Load, load_table etc) and types */
+
+typedef
+acpi_status(*acpi_tbl_handler) (u32 event, void *table, void *context);
+
 /* Address Spaces (For Operation Regions) */
 
 typedef