]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/tables/tbinstal.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.git] / drivers / acpi / tables / tbinstal.c
index 5336ce88f89f74b47790be39ceadabd8a5b345b3..18747ce8dd2f2b15b83e6e5465fc8b34c8118258 100644 (file)
@@ -107,11 +107,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
  ******************************************************************************/
 
 acpi_status
-acpi_tb_add_table(struct acpi_table_desc *table_desc,
-                 acpi_native_uint * table_index)
+acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
 {
-       acpi_native_uint i;
-       acpi_native_uint length;
+       u32 i;
        acpi_status status = AE_OK;
 
        ACPI_FUNCTION_TRACE(tb_add_table);
@@ -146,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
                        }
                }
 
-               length = ACPI_MIN(table_desc->length,
-                                 acpi_gbl_root_table_list.tables[i].length);
+               /*
+                * Check for a table match on the entire table length,
+                * not just the header.
+                */
+               if (table_desc->length !=
+                   acpi_gbl_root_table_list.tables[i].length) {
+                       continue;
+               }
+
                if (ACPI_MEMCMP(table_desc->pointer,
                                acpi_gbl_root_table_list.tables[i].pointer,
-                               length)) {
+                               acpi_gbl_root_table_list.tables[i].length)) {
                        continue;
                }
 
-               /* Table is already registered */
-
+               /*
+                * Note: the current mechanism does not unregister a table if it is
+                * dynamically unloaded. The related namespace entries are deleted,
+                * but the table remains in the root table list.
+                *
+                * The assumption here is that the number of different tables that
+                * will be loaded is actually small, and there is minimal overhead
+                * in just keeping the table in case it is needed again.
+                *
+                * If this assumption changes in the future (perhaps on large
+                * machines with many table load/unload operations), tables will
+                * need to be unregistered when they are unloaded, and slots in the
+                * root table list should be reused when empty.
+                */
+
+               /*
+                * Table is already registered.
+                * We can delete the table that was passed as a parameter.
+                */
                acpi_tb_delete_table(table_desc);
                *table_index = i;
-               status = AE_ALREADY_EXISTS;
-               goto release;
+
+               if (acpi_gbl_root_table_list.tables[i].
+                   flags & ACPI_TABLE_IS_LOADED) {
+
+                       /* Table is still loaded, this is an error */
+
+                       status = AE_ALREADY_EXISTS;
+                       goto release;
+               } else {
+                       /* Table was unloaded, allow it to be reloaded */
+
+                       table_desc->pointer =
+                           acpi_gbl_root_table_list.tables[i].pointer;
+                       table_desc->address =
+                           acpi_gbl_root_table_list.tables[i].address;
+                       status = AE_OK;
+                       goto print_header;
+               }
        }
 
-       /*
-        * Add the table to the global table list
-        */
+       /* Add the table to the global root table list */
+
        status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
                                     table_desc->length, table_desc->flags,
                                     table_index);
@@ -172,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc,
                goto release;
        }
 
+      print_header:
        acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
 
       release:
@@ -207,8 +245,8 @@ acpi_status acpi_tb_resize_root_table_list(void)
 
        /* Increase the Table Array size */
 
-       tables = ACPI_ALLOCATE_ZEROED((acpi_gbl_root_table_list.size +
-                                      ACPI_ROOT_TABLE_SIZE_INCREMENT)
+       tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
+                                      size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
                                      * sizeof(struct acpi_table_desc));
        if (!tables) {
                ACPI_ERROR((AE_INFO,
@@ -220,7 +258,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
 
        if (acpi_gbl_root_table_list.tables) {
                ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
-                           acpi_gbl_root_table_list.size *
+                           (acpi_size) acpi_gbl_root_table_list.size *
                            sizeof(struct acpi_table_desc));
 
                if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
@@ -253,7 +291,7 @@ acpi_status acpi_tb_resize_root_table_list(void)
 acpi_status
 acpi_tb_store_table(acpi_physical_address address,
                    struct acpi_table_header *table,
-                   u32 length, u8 flags, acpi_native_uint * table_index)
+                   u32 length, u8 flags, u32 *table_index)
 {
        acpi_status status = AE_OK;
 
@@ -334,7 +372,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
 
 void acpi_tb_terminate(void)
 {
-       acpi_native_uint i;
+       u32 i;
 
        ACPI_FUNCTION_TRACE(tb_terminate);
 
@@ -374,7 +412,7 @@ void acpi_tb_terminate(void)
  *
  ******************************************************************************/
 
-void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
+void acpi_tb_delete_namespace_by_owner(u32 table_index)
 {
        acpi_owner_id owner_id;
 
@@ -403,7 +441,7 @@ void acpi_tb_delete_namespace_by_owner(acpi_native_uint table_index)
  *
  ******************************************************************************/
 
-acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
+acpi_status acpi_tb_allocate_owner_id(u32 table_index)
 {
        acpi_status status = AE_BAD_PARAMETER;
 
@@ -431,7 +469,7 @@ acpi_status acpi_tb_allocate_owner_id(acpi_native_uint table_index)
  *
  ******************************************************************************/
 
-acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
+acpi_status acpi_tb_release_owner_id(u32 table_index)
 {
        acpi_status status = AE_BAD_PARAMETER;
 
@@ -462,8 +500,7 @@ acpi_status acpi_tb_release_owner_id(acpi_native_uint table_index)
  *
  ******************************************************************************/
 
-acpi_status
-acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
+acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id)
 {
        acpi_status status = AE_BAD_PARAMETER;
 
@@ -490,7 +527,7 @@ acpi_tb_get_owner_id(acpi_native_uint table_index, acpi_owner_id * owner_id)
  *
  ******************************************************************************/
 
-u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
+u8 acpi_tb_is_table_loaded(u32 table_index)
 {
        u8 is_loaded = FALSE;
 
@@ -518,7 +555,7 @@ u8 acpi_tb_is_table_loaded(acpi_native_uint table_index)
  *
  ******************************************************************************/
 
-void acpi_tb_set_table_loaded_flag(acpi_native_uint table_index, u8 is_loaded)
+void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded)
 {
 
        (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);