aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/exconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/exconfig.c')
-rw-r--r--drivers/acpi/acpica/exconfig.c82
1 files changed, 42 insertions, 40 deletions
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 8ba1464efd11..7d2949420db7 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -343,16 +343,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
343 struct acpi_walk_state *walk_state) 343 struct acpi_walk_state *walk_state)
344{ 344{
345 union acpi_operand_object *ddb_handle; 345 union acpi_operand_object *ddb_handle;
346 struct acpi_table_header *table_header;
346 struct acpi_table_header *table; 347 struct acpi_table_header *table;
347 struct acpi_table_desc table_desc;
348 u32 table_index; 348 u32 table_index;
349 acpi_status status; 349 acpi_status status;
350 u32 length; 350 u32 length;
351 351
352 ACPI_FUNCTION_TRACE(ex_load_op); 352 ACPI_FUNCTION_TRACE(ex_load_op);
353 353
354 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
355
356 /* Source Object can be either an op_region or a Buffer/Field */ 354 /* Source Object can be either an op_region or a Buffer/Field */
357 355
358 switch (obj_desc->common.type) { 356 switch (obj_desc->common.type) {
@@ -380,17 +378,17 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
380 378
381 /* Get the table header first so we can get the table length */ 379 /* Get the table header first so we can get the table length */
382 380
383 table = ACPI_ALLOCATE(sizeof(struct acpi_table_header)); 381 table_header = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
384 if (!table) { 382 if (!table_header) {
385 return_ACPI_STATUS(AE_NO_MEMORY); 383 return_ACPI_STATUS(AE_NO_MEMORY);
386 } 384 }
387 385
388 status = 386 status =
389 acpi_ex_region_read(obj_desc, 387 acpi_ex_region_read(obj_desc,
390 sizeof(struct acpi_table_header), 388 sizeof(struct acpi_table_header),
391 ACPI_CAST_PTR(u8, table)); 389 ACPI_CAST_PTR(u8, table_header));
392 length = table->length; 390 length = table_header->length;
393 ACPI_FREE(table); 391 ACPI_FREE(table_header);
394 392
395 if (ACPI_FAILURE(status)) { 393 if (ACPI_FAILURE(status)) {
396 return_ACPI_STATUS(status); 394 return_ACPI_STATUS(status);
@@ -420,22 +418,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
420 418
421 /* Allocate a buffer for the table */ 419 /* Allocate a buffer for the table */
422 420
423 table_desc.pointer = ACPI_ALLOCATE(length); 421 table = ACPI_ALLOCATE(length);
424 if (!table_desc.pointer) { 422 if (!table) {
425 return_ACPI_STATUS(AE_NO_MEMORY); 423 return_ACPI_STATUS(AE_NO_MEMORY);
426 } 424 }
427 425
428 /* Read the entire table */ 426 /* Read the entire table */
429 427
430 status = acpi_ex_region_read(obj_desc, length, 428 status = acpi_ex_region_read(obj_desc, length,
431 ACPI_CAST_PTR(u8, 429 ACPI_CAST_PTR(u8, table));
432 table_desc.pointer));
433 if (ACPI_FAILURE(status)) { 430 if (ACPI_FAILURE(status)) {
434 ACPI_FREE(table_desc.pointer); 431 ACPI_FREE(table);
435 return_ACPI_STATUS(status); 432 return_ACPI_STATUS(status);
436 } 433 }
437
438 table_desc.address = obj_desc->region.address;
439 break; 434 break;
440 435
441 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ 436 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
@@ -452,10 +447,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
452 447
453 /* Get the actual table length from the table header */ 448 /* Get the actual table length from the table header */
454 449
455 table = 450 table_header =
456 ACPI_CAST_PTR(struct acpi_table_header, 451 ACPI_CAST_PTR(struct acpi_table_header,
457 obj_desc->buffer.pointer); 452 obj_desc->buffer.pointer);
458 length = table->length; 453 length = table_header->length;
459 454
460 /* Table cannot extend beyond the buffer */ 455 /* Table cannot extend beyond the buffer */
461 456
@@ -470,13 +465,12 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
470 * Copy the table from the buffer because the buffer could be modified 465 * Copy the table from the buffer because the buffer could be modified
471 * or even deleted in the future 466 * or even deleted in the future
472 */ 467 */
473 table_desc.pointer = ACPI_ALLOCATE(length); 468 table = ACPI_ALLOCATE(length);
474 if (!table_desc.pointer) { 469 if (!table) {
475 return_ACPI_STATUS(AE_NO_MEMORY); 470 return_ACPI_STATUS(AE_NO_MEMORY);
476 } 471 }
477 472
478 ACPI_MEMCPY(table_desc.pointer, table, length); 473 ACPI_MEMCPY(table, table_header, length);
479 table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
480 break; 474 break;
481 475
482 default: 476 default:
@@ -484,27 +478,32 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
484 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 478 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
485 } 479 }
486 480
487 /* Validate table checksum (will not get validated in tb_add_table) */ 481 /* Install the new table into the local data structures */
488
489 status = acpi_tb_verify_checksum(table_desc.pointer, length);
490 if (ACPI_FAILURE(status)) {
491 ACPI_FREE(table_desc.pointer);
492 return_ACPI_STATUS(status);
493 }
494
495 /* Complete the table descriptor */
496 482
497 table_desc.length = length; 483 ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
498 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED; 484 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
499 485
500 /* Install the new table into the local data structures */ 486 status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table),
487 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
488 TRUE, TRUE, &table_index);
501 489
502 status = acpi_tb_add_table(&table_desc, &table_index); 490 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
503 if (ACPI_FAILURE(status)) { 491 if (ACPI_FAILURE(status)) {
504 492
505 /* Delete allocated table buffer */ 493 /* Delete allocated table buffer */
506 494
507 acpi_tb_delete_table(&table_desc); 495 ACPI_FREE(table);
496 return_ACPI_STATUS(status);
497 }
498
499 /*
500 * Note: Now table is "INSTALLED", it must be validated before
501 * loading.
502 */
503 status =
504 acpi_tb_validate_table(&acpi_gbl_root_table_list.
505 tables[table_index]);
506 if (ACPI_FAILURE(status)) {
508 return_ACPI_STATUS(status); 507 return_ACPI_STATUS(status);
509 } 508 }
510 509
@@ -536,9 +535,6 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
536 return_ACPI_STATUS(status); 535 return_ACPI_STATUS(status);
537 } 536 }
538 537
539 ACPI_INFO((AE_INFO, "Dynamic OEM Table Load:"));
540 acpi_tb_print_table_header(0, table_desc.pointer);
541
542 /* Remove the reference by added by acpi_ex_store above */ 538 /* Remove the reference by added by acpi_ex_store above */
543 539
544 acpi_ut_remove_reference(ddb_handle); 540 acpi_ut_remove_reference(ddb_handle);
@@ -546,8 +542,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
546 /* Invoke table handler if present */ 542 /* Invoke table handler if present */
547 543
548 if (acpi_gbl_table_handler) { 544 if (acpi_gbl_table_handler) {
549 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, 545 (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
550 table_desc.pointer,
551 acpi_gbl_table_handler_context); 546 acpi_gbl_table_handler_context);
552 } 547 }
553 548
@@ -576,6 +571,13 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
576 ACPI_FUNCTION_TRACE(ex_unload_table); 571 ACPI_FUNCTION_TRACE(ex_unload_table);
577 572
578 /* 573 /*
574 * Temporarily emit a warning so that the ASL for the machine can be
575 * hopefully obtained. This is to say that the Unload() operator is
576 * extremely rare if not completely unused.
577 */
578 ACPI_WARNING((AE_INFO, "Received request to unload an ACPI table"));
579
580 /*
579 * Validate the handle 581 * Validate the handle
580 * Although the handle is partially validated in acpi_ex_reconfiguration() 582 * Although the handle is partially validated in acpi_ex_reconfiguration()
581 * when it calls acpi_ex_resolve_operands(), the handle is more completely 583 * when it calls acpi_ex_resolve_operands(), the handle is more completely