ACPI: Add support for acpi_load_table/acpi_unload_table_id
[sfrench/cifs-2.6.git] / drivers / acpi / tables / tbxface.c
index 9fe53c9d5b9ad4a78f30af8bfcd1cd35d1e30e8d..5ba9303293ad968c4366ca49c4044291cd4bf10c 100644 (file)
@@ -42,8 +42,6 @@
  * POSSIBILITY OF SUCH DAMAGES.
  */
 
-#include <linux/module.h>
-
 #include <acpi/acpi.h>
 #include <acpi/acnamesp.h>
 #include <acpi/actables.h>
@@ -68,7 +66,7 @@ acpi_status acpi_load_tables(void)
        struct acpi_pointer rsdp_address;
        acpi_status status;
 
-       ACPI_FUNCTION_TRACE("acpi_load_tables");
+       ACPI_FUNCTION_TRACE(acpi_load_tables);
 
        /* Get the RSDP */
 
@@ -123,7 +121,8 @@ acpi_status acpi_load_tables(void)
        return_ACPI_STATUS(status);
 }
 
-#ifdef ACPI_FUTURE_USAGE
+ACPI_EXPORT_SYMBOL(acpi_load_tables)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_table
@@ -134,19 +133,18 @@ acpi_status acpi_load_tables(void)
  * 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.
  *
  ******************************************************************************/
-
 acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
 {
        acpi_status status;
        struct acpi_table_desc table_info;
        struct acpi_pointer address;
 
-       ACPI_FUNCTION_TRACE("acpi_load_table");
+       ACPI_FUNCTION_TRACE(acpi_load_table);
 
        if (!table_ptr) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -174,6 +172,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
        status = acpi_tb_install_table(&table_info);
        if (ACPI_FAILURE(status)) {
                if (status == AE_ALREADY_EXISTS) {
+
                        /* Table already exists, no error */
 
                        status = AE_OK;
@@ -188,12 +187,12 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
        /* Convert the table to common format if necessary */
 
        switch (table_info.type) {
-       case ACPI_TABLE_FADT:
+       case ACPI_TABLE_ID_FADT:
 
                status = acpi_tb_convert_table_fadt();
                break;
 
-       case ACPI_TABLE_FACS:
+       case ACPI_TABLE_ID_FACS:
 
                status = acpi_tb_build_common_facs(&table_info);
                break;
@@ -208,6 +207,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
        }
 
        if (ACPI_FAILURE(status)) {
+
                /* Uninstall table and free the buffer */
 
                (void)acpi_tb_uninstall_table(table_info.installed_desc);
@@ -216,6 +216,61 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
        return_ACPI_STATUS(status);
 }
 
+ACPI_EXPORT_SYMBOL(acpi_load_table)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_unload_table_id
+ *
+ * PARAMETERS:  table_type    - Type of table to be unloaded
+ *              id            - Owner ID of the table to be removed.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This routine is used to force the unload of a table (by id)
+ *
+ ******************************************************************************/
+acpi_status acpi_unload_table_id(acpi_table_type table_type, acpi_owner_id id)
+{
+       struct acpi_table_desc *table_desc;
+       acpi_status status;
+
+       ACPI_FUNCTION_TRACE(acpi_unload_table);
+
+       /* Parameter validation */
+       if (table_type > ACPI_TABLE_ID_MAX)
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+       /* Find table from the requested type list */
+       table_desc = acpi_gbl_table_lists[table_type].next;
+       while (table_desc && table_desc->owner_id != id)
+               table_desc = table_desc->next;
+
+       if (!table_desc)
+               return_ACPI_STATUS(AE_NOT_EXIST);
+
+       /*
+        * 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);
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+       if (ACPI_FAILURE(status))
+               return_ACPI_STATUS(status);
+
+       (void)acpi_tb_uninstall_table(table_desc);
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+       return_ACPI_STATUS(AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
+
+#ifdef ACPI_FUTURE_USAGE
 /*******************************************************************************
  *
  * FUNCTION:    acpi_unload_table
@@ -227,31 +282,33 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
  * DESCRIPTION: This routine is used to force the unload of a table
  *
  ******************************************************************************/
-
 acpi_status acpi_unload_table(acpi_table_type table_type)
 {
        struct acpi_table_desc *table_desc;
 
-       ACPI_FUNCTION_TRACE("acpi_unload_table");
+       ACPI_FUNCTION_TRACE(acpi_unload_table);
 
        /* Parameter validation */
 
-       if (table_type > ACPI_TABLE_MAX) {
+       if (table_type > ACPI_TABLE_ID_MAX) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
        /* 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;
        }
 
@@ -261,6 +318,8 @@ acpi_status acpi_unload_table(acpi_table_type table_type)
        return_ACPI_STATUS(AE_OK);
 }
 
+ACPI_EXPORT_SYMBOL(acpi_unload_table)
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_get_table_header
@@ -271,17 +330,16 @@ acpi_status acpi_unload_table(acpi_table_type table_type)
  *                                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.
  *
  ******************************************************************************/
-
 acpi_status
 acpi_get_table_header(acpi_table_type table_type,
                      u32 instance, struct acpi_table_header *out_table_header)
@@ -289,16 +347,16 @@ acpi_get_table_header(acpi_table_type table_type,
        struct acpi_table_header *tbl_ptr;
        acpi_status status;
 
-       ACPI_FUNCTION_TRACE("acpi_get_table_header");
+       ACPI_FUNCTION_TRACE(acpi_get_table_header);
 
        if ((instance == 0) ||
-           (table_type == ACPI_TABLE_RSDP) || (!out_table_header)) {
+           (table_type == ACPI_TABLE_ID_RSDP) || (!out_table_header)) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
        /* Check the table type and instance */
 
-       if ((table_type > ACPI_TABLE_MAX) ||
+       if ((table_type > ACPI_TABLE_ID_MAX) ||
            (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
             instance > 1)) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -319,12 +377,14 @@ 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);
 }
 
+ACPI_EXPORT_SYMBOL(acpi_get_table_header)
 #endif                         /*  ACPI_FUTURE_USAGE  */
 
 /*******************************************************************************
@@ -340,16 +400,15 @@ acpi_get_table_header(acpi_table_type table_type,
  *
  * 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.
  *
  ******************************************************************************/
-
 acpi_status
 acpi_get_table(acpi_table_type table_type,
               u32 instance, struct acpi_buffer *ret_buffer)
@@ -358,7 +417,7 @@ acpi_get_table(acpi_table_type table_type,
        acpi_status status;
        acpi_size table_length;
 
-       ACPI_FUNCTION_TRACE("acpi_get_table");
+       ACPI_FUNCTION_TRACE(acpi_get_table);
 
        /* Parameter validation */
 
@@ -373,7 +432,7 @@ acpi_get_table(acpi_table_type table_type,
 
        /* Check the table type and instance */
 
-       if ((table_type > ACPI_TABLE_MAX) ||
+       if ((table_type > ACPI_TABLE_ID_MAX) ||
            (ACPI_IS_SINGLE_TABLE(acpi_gbl_table_data[table_type].flags) &&
             instance > 1)) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -396,7 +455,8 @@ acpi_get_table(acpi_table_type table_type,
 
        /* Get the table length */
 
-       if (table_type == ACPI_TABLE_RSDP) {
+       if (table_type == ACPI_TABLE_ID_RSDP) {
+
                /* RSD PTR is the only "table" without a header */
 
                table_length = sizeof(struct rsdp_descriptor);
@@ -413,8 +473,10 @@ 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);
 }
 
-EXPORT_SYMBOL(acpi_get_table);
+ACPI_EXPORT_SYMBOL(acpi_get_table)