aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/tables/tbinstal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/tables/tbinstal.c')
-rw-r--r--drivers/acpi/tables/tbinstal.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c
index b22185f55a16..18747ce8dd2f 100644
--- a/drivers/acpi/tables/tbinstal.c
+++ b/drivers/acpi/tables/tbinstal.c
@@ -110,7 +110,6 @@ acpi_status
110acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 110acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
111{ 111{
112 u32 i; 112 u32 i;
113 u32 length;
114 acpi_status status = AE_OK; 113 acpi_status status = AE_OK;
115 114
116 ACPI_FUNCTION_TRACE(tb_add_table); 115 ACPI_FUNCTION_TRACE(tb_add_table);
@@ -145,25 +144,64 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
145 } 144 }
146 } 145 }
147 146
148 length = ACPI_MIN(table_desc->length, 147 /*
149 acpi_gbl_root_table_list.tables[i].length); 148 * Check for a table match on the entire table length,
149 * not just the header.
150 */
151 if (table_desc->length !=
152 acpi_gbl_root_table_list.tables[i].length) {
153 continue;
154 }
155
150 if (ACPI_MEMCMP(table_desc->pointer, 156 if (ACPI_MEMCMP(table_desc->pointer,
151 acpi_gbl_root_table_list.tables[i].pointer, 157 acpi_gbl_root_table_list.tables[i].pointer,
152 length)) { 158 acpi_gbl_root_table_list.tables[i].length)) {
153 continue; 159 continue;
154 } 160 }
155 161
156 /* Table is already registered */ 162 /*
157 163 * Note: the current mechanism does not unregister a table if it is
164 * dynamically unloaded. The related namespace entries are deleted,
165 * but the table remains in the root table list.
166 *
167 * The assumption here is that the number of different tables that
168 * will be loaded is actually small, and there is minimal overhead
169 * in just keeping the table in case it is needed again.
170 *
171 * If this assumption changes in the future (perhaps on large
172 * machines with many table load/unload operations), tables will
173 * need to be unregistered when they are unloaded, and slots in the
174 * root table list should be reused when empty.
175 */
176
177 /*
178 * Table is already registered.
179 * We can delete the table that was passed as a parameter.
180 */
158 acpi_tb_delete_table(table_desc); 181 acpi_tb_delete_table(table_desc);
159 *table_index = i; 182 *table_index = i;
160 status = AE_ALREADY_EXISTS; 183
161 goto release; 184 if (acpi_gbl_root_table_list.tables[i].
185 flags & ACPI_TABLE_IS_LOADED) {
186
187 /* Table is still loaded, this is an error */
188
189 status = AE_ALREADY_EXISTS;
190 goto release;
191 } else {
192 /* Table was unloaded, allow it to be reloaded */
193
194 table_desc->pointer =
195 acpi_gbl_root_table_list.tables[i].pointer;
196 table_desc->address =
197 acpi_gbl_root_table_list.tables[i].address;
198 status = AE_OK;
199 goto print_header;
200 }
162 } 201 }
163 202
164 /* 203 /* Add the table to the global root table list */
165 * Add the table to the global table list 204
166 */
167 status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 205 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
168 table_desc->length, table_desc->flags, 206 table_desc->length, table_desc->flags,
169 table_index); 207 table_index);
@@ -171,6 +209,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
171 goto release; 209 goto release;
172 } 210 }
173 211
212 print_header:
174 acpi_tb_print_table_header(table_desc->address, table_desc->pointer); 213 acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
175 214
176 release: 215 release: