--- zzzz-none-000/linux-3.10.107/drivers/acpi/acpica/tbxfload.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/acpi/acpica/tbxfload.c 2021-02-04 17:41:59.000000000 +0000 @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2013, Intel Corp. + * Copyright (C) 2000 - 2015, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ -#include +#define EXPORT_ACPI_INTERFACES + #include #include "accommon.h" #include "acnamesp.h" @@ -50,11 +51,6 @@ #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME("tbxfload") -/* Local prototypes */ -static acpi_status acpi_tb_load_namespace(void); - -static int no_auto_ssdt; - /******************************************************************************* * * FUNCTION: acpi_load_tables @@ -66,8 +62,7 @@ * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT * ******************************************************************************/ - -acpi_status acpi_load_tables(void) +acpi_status __init acpi_load_tables(void) { acpi_status status; @@ -76,6 +71,13 @@ /* Load the namespace from the tables */ status = acpi_tb_load_namespace(); + + /* Don't let single failures abort the load */ + + if (status == AE_CTRL_TERMINATE) { + status = AE_OK; + } + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "While loading namespace from ACPI tables")); @@ -84,7 +86,7 @@ return_ACPI_STATUS(status); } -ACPI_EXPORT_SYMBOL(acpi_load_tables) +ACPI_EXPORT_SYMBOL_INIT(acpi_load_tables) /******************************************************************************* * @@ -98,11 +100,14 @@ * the RSDT/XSDT. * ******************************************************************************/ -static acpi_status acpi_tb_load_namespace(void) +acpi_status acpi_tb_load_namespace(void) { acpi_status status; u32 i; struct acpi_table_header *new_dsdt; + struct acpi_table_desc *table; + u32 tables_loaded = 0; + u32 tables_failed = 0; ACPI_FUNCTION_TRACE(tb_load_namespace); @@ -112,15 +117,11 @@ * Load the namespace. The DSDT is required, but any SSDT and * PSDT tables are optional. Verify the DSDT. */ + table = &acpi_gbl_root_table_list.tables[acpi_gbl_dsdt_index]; + if (!acpi_gbl_root_table_list.current_table_count || - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT].signature), - ACPI_SIG_DSDT) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list. - tables[ACPI_TABLE_INDEX_DSDT]))) { + !ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_DSDT) || + ACPI_FAILURE(acpi_tb_validate_table(table))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } @@ -129,10 +130,9 @@ * Save the DSDT pointer for simple access. This is the mapped memory * address. We must take care here because the address of the .Tables * array can change dynamically as tables are loaded at run-time. Note: - * .Pointer field is not validated until after call to acpi_tb_verify_table. + * .Pointer field is not validated until after call to acpi_tb_validate_table. */ - acpi_gbl_DSDT = - acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; + acpi_gbl_DSDT = table->pointer; /* * Optionally copy the entire DSDT to local memory (instead of simply @@ -141,7 +141,7 @@ * the DSDT. */ if (acpi_gbl_copy_dsdt_locally) { - new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT); + new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index); if (new_dsdt) { acpi_gbl_DSDT = new_dsdt; } @@ -151,56 +151,119 @@ * Save the original DSDT header for detection of table corruption * and/or replacement of the DSDT from outside the OS. */ - ACPI_MEMCPY(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, - sizeof(struct acpi_table_header)); + memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, + sizeof(struct acpi_table_header)); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); /* Load and parse tables */ - status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); + status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed")); + tables_failed++; + } else { + tables_loaded++; } /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { - if ((!ACPI_COMPARE_NAME - (&(acpi_gbl_root_table_list.tables[i].signature), - ACPI_SIG_SSDT) - && - !ACPI_COMPARE_NAME(& - (acpi_gbl_root_table_list.tables[i]. - signature), ACPI_SIG_PSDT)) - || - ACPI_FAILURE(acpi_tb_verify_table - (&acpi_gbl_root_table_list.tables[i]))) { - continue; - } + table = &acpi_gbl_root_table_list.tables[i]; - if (no_auto_ssdt) { - printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); + if (!acpi_gbl_root_table_list.tables[i].address || + (!ACPI_COMPARE_NAME(table->signature.ascii, ACPI_SIG_SSDT) + && !ACPI_COMPARE_NAME(table->signature.ascii, + ACPI_SIG_PSDT) + && !ACPI_COMPARE_NAME(table->signature.ascii, + ACPI_SIG_OSDT)) + || ACPI_FAILURE(acpi_tb_validate_table(table))) { continue; } /* Ignore errors while loading tables, get as many as possible */ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); - (void)acpi_ns_load_table(i, acpi_gbl_root_node); + status = acpi_ns_load_table(i, acpi_gbl_root_node); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, + "(%4.4s:%8.8s) while loading table", + table->signature.ascii, + table->pointer->oem_table_id)); + tables_failed++; + + ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, + "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n", + table->signature.ascii, + table->pointer->oem_table_id)); + } else { + tables_loaded++; + } + (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); } - ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired")); + if (!tables_failed) { + ACPI_INFO((AE_INFO, + "%u ACPI AML tables successfully acquired and loaded", + tables_loaded)); + } else { + ACPI_ERROR((AE_INFO, + "%u table load failures, %u successful", + tables_failed, tables_loaded)); - unlock_and_exit: + /* Indicate at least one failure */ + + status = AE_CTRL_TERMINATE; + } + +unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); } /******************************************************************************* * + * FUNCTION: acpi_install_table + * + * PARAMETERS: address - Address of the ACPI table to be installed. + * physical - Whether the address is a physical table + * address or not + * + * RETURN: Status + * + * DESCRIPTION: Dynamically install an ACPI table. + * Note: This function should only be invoked after + * acpi_initialize_tables() and before acpi_load_tables(). + * + ******************************************************************************/ + +acpi_status __init +acpi_install_table(acpi_physical_address address, u8 physical) +{ + acpi_status status; + u8 flags; + u32 table_index; + + ACPI_FUNCTION_TRACE(acpi_install_table); + + if (physical) { + flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; + } else { + flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; + } + + status = acpi_tb_install_standard_table(address, flags, + FALSE, FALSE, &table_index); + + return_ACPI_STATUS(status); +} + +ACPI_EXPORT_SYMBOL_INIT(acpi_install_table) + +/******************************************************************************* + * * FUNCTION: acpi_load_table * * PARAMETERS: table - Pointer to a buffer containing the ACPI @@ -215,11 +278,9 @@ * to ensure that the table is not deleted or unmapped. * ******************************************************************************/ - acpi_status acpi_load_table(struct acpi_table_header *table) { acpi_status status; - struct acpi_table_desc table_desc; u32 table_index; ACPI_FUNCTION_TRACE(acpi_load_table); @@ -230,14 +291,6 @@ return_ACPI_STATUS(AE_BAD_PARAMETER); } - /* Init local table descriptor */ - - ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); - table_desc.address = ACPI_PTR_TO_PHYSADDR(table); - table_desc.pointer = table; - table_desc.length = table->length; - table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; - /* Must acquire the interpreter lock during this operation */ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); @@ -248,7 +301,24 @@ /* Install the table and load it into the namespace */ ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); - status = acpi_tb_add_table(&table_desc, &table_index); + (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); + + status = acpi_tb_install_standard_table(ACPI_PTR_TO_PHYSADDR(table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, + TRUE, FALSE, &table_index); + + (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); + if (ACPI_FAILURE(status)) { + goto unlock_and_exit; + } + + /* + * Note: Now table is "INSTALLED", it must be validated before + * using. + */ + status = + acpi_tb_validate_table(&acpi_gbl_root_table_list. + tables[table_index]); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -262,7 +332,7 @@ acpi_gbl_table_handler_context); } - unlock_and_exit: +unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); return_ACPI_STATUS(status); } @@ -376,14 +446,3 @@ } ACPI_EXPORT_SYMBOL(acpi_unload_parent_table) - -static int __init acpi_no_auto_ssdt_setup(char *s) { - - printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n"); - - no_auto_ssdt = 1; - - return 1; -} - -__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);