aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/tbinstal.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/tbinstal.c')
-rw-r--r--drivers/acpi/acpica/tbinstal.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b21969d..f865d5a096de 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
103 * 103 *
104 * RETURN: Status 104 * RETURN: Status
105 * 105 *
106 * DESCRIPTION: This function is called to add the ACPI table 106 * DESCRIPTION: This function is called to add an ACPI table. It is used to
107 * dynamically load tables via the Load and load_table AML
108 * operators.
107 * 109 *
108 ******************************************************************************/ 110 ******************************************************************************/
109 111
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
112{ 114{
113 u32 i; 115 u32 i;
114 acpi_status status = AE_OK; 116 acpi_status status = AE_OK;
117 struct acpi_table_header *override_table = NULL;
115 118
116 ACPI_FUNCTION_TRACE(tb_add_table); 119 ACPI_FUNCTION_TRACE(tb_add_table);
117 120
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
201 } 204 }
202 } 205 }
203 206
207 /*
208 * ACPI Table Override:
209 * Allow the host to override dynamically loaded tables.
210 */
211 status = acpi_os_table_override(table_desc->pointer, &override_table);
212 if (ACPI_SUCCESS(status) && override_table) {
213 ACPI_INFO((AE_INFO,
214 "%4.4s @ 0x%p Table override, replaced with:",
215 table_desc->pointer->signature,
216 ACPI_CAST_PTR(void, table_desc->address)));
217
218 /* We can delete the table that was passed as a parameter */
219
220 acpi_tb_delete_table(table_desc);
221
222 /* Setup descriptor for the new table */
223
224 table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
225 table_desc->pointer = override_table;
226 table_desc->length = override_table->length;
227 table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
228 }
229
204 /* Add the table to the global root table list */ 230 /* Add the table to the global root table list */
205 231
206 status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 232 status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
247 /* Increase the Table Array size */ 273 /* Increase the Table Array size */
248 274
249 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. 275 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
250 size + ACPI_ROOT_TABLE_SIZE_INCREMENT) 276 size +
251 * sizeof(struct acpi_table_desc)); 277 ACPI_ROOT_TABLE_SIZE_INCREMENT) *
278 sizeof(struct acpi_table_desc));
252 if (!tables) { 279 if (!tables) {
253 ACPI_ERROR((AE_INFO, 280 ACPI_ERROR((AE_INFO,
254 "Could not allocate new root table array")); 281 "Could not allocate new root table array"));
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void)
407 * 434 *
408 * PARAMETERS: table_index - Table index 435 * PARAMETERS: table_index - Table index
409 * 436 *
410 * RETURN: None 437 * RETURN: Status
411 * 438 *
412 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 439 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
413 * 440 *
414 ******************************************************************************/ 441 ******************************************************************************/
415 442
416void acpi_tb_delete_namespace_by_owner(u32 table_index) 443acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
417{ 444{
418 acpi_owner_id owner_id; 445 acpi_owner_id owner_id;
446 acpi_status status;
447
448 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
449
450 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
451 if (ACPI_FAILURE(status)) {
452 return_ACPI_STATUS(status);
453 }
454
455 if (table_index >= acpi_gbl_root_table_list.count) {
456
457 /* The table index does not exist */
419 458
420 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
421 if (table_index < acpi_gbl_root_table_list.count) {
422 owner_id =
423 acpi_gbl_root_table_list.tables[table_index].owner_id;
424 } else {
425 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 459 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
426 return; 460 return_ACPI_STATUS(AE_NOT_EXIST);
427 } 461 }
428 462
463 /* Get the owner ID for this table, used to delete namespace nodes */
464
465 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
429 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 466 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
467
468 /*
469 * Need to acquire the namespace writer lock to prevent interference
470 * with any concurrent namespace walks. The interpreter must be
471 * released during the deletion since the acquisition of the deletion
472 * lock may block, and also since the execution of a namespace walk
473 * must be allowed to use the interpreter.
474 */
475 acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
476 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
477
430 acpi_ns_delete_namespace_by_owner(owner_id); 478 acpi_ns_delete_namespace_by_owner(owner_id);
479 if (ACPI_FAILURE(status)) {
480 return_ACPI_STATUS(status);
481 }
482
483 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
484
485 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
486 return_ACPI_STATUS(status);
431} 487}
432 488
433/******************************************************************************* 489/*******************************************************************************
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_index)
535 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 591 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
536 if (table_index < acpi_gbl_root_table_list.count) { 592 if (table_index < acpi_gbl_root_table_list.count) {
537 is_loaded = (u8) 593 is_loaded = (u8)
538 (acpi_gbl_root_table_list.tables[table_index]. 594 (acpi_gbl_root_table_list.tables[table_index].flags &
539 flags & ACPI_TABLE_IS_LOADED); 595 ACPI_TABLE_IS_LOADED);
540 } 596 }
541 597
542 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 598 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);