ACPICA: New common routine for creating and verifying a local FADT.
[deliverable/linux.git] / drivers / acpi / executer / exconfig.c
index a29782fe3ecf20e3bd2c9e44469b3cc9af5b75f6..dd43b00e18b5cd28aced638fbef01f027881c53c 100644 (file)
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("exconfig")
 
 /* Local prototypes */
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
                  struct acpi_namespace_node *parent_node,
                  union acpi_operand_object **ddb_handle);
 
@@ -74,15 +74,14 @@ acpi_ex_add_table(struct acpi_table_header *table,
  ******************************************************************************/
 
 static acpi_status
-acpi_ex_add_table(struct acpi_table_header *table,
+acpi_ex_add_table(acpi_native_uint table_index,
                  struct acpi_namespace_node *parent_node,
                  union acpi_operand_object **ddb_handle)
 {
        acpi_status status;
-       struct acpi_table_desc table_info;
        union acpi_operand_object *obj_desc;
 
-       ACPI_FUNCTION_TRACE("ex_add_table");
+       ACPI_FUNCTION_TRACE(ex_add_table);
 
        /* Create an object to be the table handle */
 
@@ -98,40 +97,16 @@ acpi_ex_add_table(struct acpi_table_header *table,
 
        /* Install the new table into the local data structures */
 
-       ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc));
-
-       table_info.type = ACPI_TABLE_SSDT;
-       table_info.pointer = table;
-       table_info.length = (acpi_size) table->length;
-       table_info.allocation = ACPI_MEM_ALLOCATED;
-
-       status = acpi_tb_install_table(&table_info);
-       obj_desc->reference.object = table_info.installed_desc;
-
-       if (ACPI_FAILURE(status)) {
-               if (status == AE_ALREADY_EXISTS) {
-                       /* Table already exists, just return the handle */
-
-                       return_ACPI_STATUS(AE_OK);
-               }
-               goto cleanup;
-       }
+       obj_desc->reference.object = ACPI_CAST_PTR(void, table_index);
 
        /* Add the table to the namespace */
 
-       status = acpi_ns_load_table(table_info.installed_desc, parent_node);
+       status = acpi_ns_load_table(table_index, parent_node);
        if (ACPI_FAILURE(status)) {
-               /* Uninstall table on error */
-
-               (void)acpi_tb_uninstall_table(table_info.installed_desc);
-               goto cleanup;
+               acpi_ut_remove_reference(obj_desc);
+               *ddb_handle = NULL;
        }
 
-       return_ACPI_STATUS(AE_OK);
-
-      cleanup:
-       acpi_ut_remove_reference(obj_desc);
-       *ddb_handle = NULL;
        return_ACPI_STATUS(status);
 }
 
@@ -154,13 +129,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 {
        acpi_status status;
        union acpi_operand_object **operand = &walk_state->operands[0];
-       struct acpi_table_header *table;
+       acpi_native_uint table_index;
        struct acpi_namespace_node *parent_node;
        struct acpi_namespace_node *start_node;
        struct acpi_namespace_node *parameter_node = NULL;
        union acpi_operand_object *ddb_handle;
+       struct acpi_table_header *table;
 
-       ACPI_FUNCTION_TRACE("ex_load_table_op");
+       ACPI_FUNCTION_TRACE(ex_load_table_op);
 
 #if 0
        /*
@@ -169,6 +145,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
         */
        status = acpi_tb_match_signature(operand[0]->string.pointer, NULL);
        if (status == AE_OK) {
+
                /* Signature matched -- don't allow override */
 
                return_ACPI_STATUS(AE_ALREADY_EXISTS);
@@ -179,7 +156,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 
        status = acpi_tb_find_table(operand[0]->string.pointer,
                                    operand[1]->string.pointer,
-                                   operand[2]->string.pointer, &table);
+                                   operand[2]->string.pointer, &table_index);
        if (ACPI_FAILURE(status)) {
                if (status != AE_NOT_FOUND) {
                        return_ACPI_STATUS(status);
@@ -211,9 +188,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
                 * location within the namespace where the table will be loaded.
                 */
                status =
-                   acpi_ns_get_node_by_path(operand[3]->string.pointer,
-                                            start_node, ACPI_NS_SEARCH_PARENT,
-                                            &parent_node);
+                   acpi_ns_get_node(start_node, operand[3]->string.pointer,
+                                    ACPI_NS_SEARCH_PARENT, &parent_node);
                if (ACPI_FAILURE(status)) {
                        return_ACPI_STATUS(status);
                }
@@ -234,9 +210,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
                /* Find the node referenced by the parameter_path_string */
 
                status =
-                   acpi_ns_get_node_by_path(operand[4]->string.pointer,
-                                            start_node, ACPI_NS_SEARCH_PARENT,
-                                            &parameter_node);
+                   acpi_ns_get_node(start_node, operand[4]->string.pointer,
+                                    ACPI_NS_SEARCH_PARENT, &parameter_node);
                if (ACPI_FAILURE(status)) {
                        return_ACPI_STATUS(status);
                }
@@ -244,7 +219,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
 
        /* Load the table into the namespace */
 
-       status = acpi_ex_add_table(table, parent_node, &ddb_handle);
+       status = acpi_ex_add_table(table_index, parent_node, &ddb_handle);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -252,6 +227,7 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
        /* Parameter Data (optional) */
 
        if (parameter_node) {
+
                /* Store the parameter data into the optional parameter object */
 
                status = acpi_ex_store(operand[5],
@@ -264,6 +240,14 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
                }
        }
 
+       status = acpi_get_table_by_index(table_index, &table);
+       if (ACPI_SUCCESS(status)) {
+               ACPI_INFO((AE_INFO,
+                          "Dynamic OEM Table Load - [%4.4s] OemId [%6.6s] OemTableId [%8.8s]",
+                          table->signature, table->oem_id,
+                          table->oem_table_id));
+       }
+
        *return_desc = ddb_handle;
        return_ACPI_STATUS(status);
 }
@@ -292,11 +276,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
        union acpi_operand_object *ddb_handle;
        union acpi_operand_object *buffer_desc = NULL;
        struct acpi_table_header *table_ptr = NULL;
+       acpi_native_uint table_index;
        acpi_physical_address address;
        struct acpi_table_header table_header;
+       acpi_integer temp;
        u32 i;
 
-       ACPI_FUNCTION_TRACE("ex_load_op");
+       ACPI_FUNCTION_TRACE(ex_load_op);
 
        /* Object can be either an op_region or a Field */
 
@@ -322,7 +308,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
                address = obj_desc->region.address;
 
-               /* Get the table length from the table header */
+               /* Get part of the table header to get the table length */
 
                table_header.length = 0;
                for (i = 0; i < 8; i++) {
@@ -330,11 +316,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                            acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
                                                           (acpi_physical_address)
                                                           (i + address), 8,
-                                                          ((u8 *) &
-                                                           table_header) + i);
+                                                          &temp);
                        if (ACPI_FAILURE(status)) {
                                return_ACPI_STATUS(status);
                        }
+
+                       /* Get the one valid byte of the returned 64-bit value */
+
+                       ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp;
                }
 
                /* Sanity check the table length */
@@ -345,7 +334,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
                /* Allocate a buffer for the entire table */
 
-               table_ptr = ACPI_MEM_ALLOCATE(table_header.length);
+               table_ptr = ACPI_ALLOCATE(table_header.length);
                if (!table_ptr) {
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
@@ -357,11 +346,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                            acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
                                                           (acpi_physical_address)
                                                           (i + address), 8,
-                                                          ((u8 *) table_ptr +
-                                                           i));
+                                                          &temp);
                        if (ACPI_FAILURE(status)) {
                                goto cleanup;
                        }
+
+                       /* Get the one valid byte of the returned 64-bit value */
+
+                       ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp;
                }
                break;
 
@@ -407,12 +399,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
        /* The table must be either an SSDT or a PSDT */
 
-       if ((!ACPI_STRNCMP(table_ptr->signature,
-                          acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
-                          acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
-           (!ACPI_STRNCMP(table_ptr->signature,
-                          acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
-                          acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
+       if ((!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_PSDT)) &&
+           (!ACPI_COMPARE_NAME(table_ptr->signature, ACPI_SIG_SSDT))) {
                ACPI_ERROR((AE_INFO,
                            "Table has invalid signature [%4.4s], must be SSDT or PSDT",
                            table_ptr->signature));
@@ -420,10 +408,18 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                goto cleanup;
        }
 
-       /* Install the new table into the local data structures */
+       /*
+        * Install the new table into the local data structures
+        */
+       status = acpi_tb_add_table(table_ptr, &table_index);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
 
-       status = acpi_ex_add_table(table_ptr, acpi_gbl_root_node, &ddb_handle);
+       status =
+           acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle);
        if (ACPI_FAILURE(status)) {
+
                /* On error, table_ptr was deallocated above */
 
                return_ACPI_STATUS(status);
@@ -440,9 +436,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(status);
        }
 
+       ACPI_INFO((AE_INFO,
+                  "Dynamic SSDT Load - OemId [%6.6s] OemTableId [%8.8s]",
+                  table_ptr->oem_id, table_ptr->oem_table_id));
+
       cleanup:
        if (ACPI_FAILURE(status)) {
-               ACPI_MEM_FREE(table_ptr);
+               ACPI_FREE(table_ptr);
        }
        return_ACPI_STATUS(status);
 }
@@ -463,9 +463,9 @@ 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;
-       struct acpi_table_desc *table_info;
+       acpi_native_uint table_index;
 
-       ACPI_FUNCTION_TRACE("ex_unload_table");
+       ACPI_FUNCTION_TRACE(ex_unload_table);
 
        /*
         * Validate the handle
@@ -479,20 +479,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
-       /* Get the actual table descriptor from the ddb_handle */
+       /* Get the table index from the ddb_handle */
 
-       table_info = (struct acpi_table_desc *)table_desc->reference.object;
+       table_index = (acpi_native_uint) table_desc->reference.object;
 
        /*
         * Delete the entire namespace under this table Node
         * (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 */
+       acpi_tb_delete_namespace_by_owner(table_index);
+       acpi_tb_release_owner_id(table_index);
 
-       (void)acpi_tb_uninstall_table(table_info->installed_desc);
+       acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
        /* Delete the table descriptor (ddb_handle) */
 
This page took 0.052031 seconds and 5 git commands to generate.