/******************************************************************************* * * FUNCTION: acpi_load_table * * PARAMETERS: table - Pointer to a buffer containing the ACPI * table to be loaded. * * RETURN: Status * * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must * be a valid ACPI table with a valid ACPI table header. * Note1: Mainly intended to support hotplug addition of SSDTs. * Note2: Does not copy the incoming table. User is responsible * to ensure that the table is not deleted or unmapped. * ******************************************************************************/ acpi_status acpi_load_table(struct acpi_table_header *table) { acpi_status status; u32 table_index; ACPI_FUNCTION_TRACE(acpi_load_table); /* Parameter validation */ if (!table) { return_ACPI_STATUS(AE_BAD_PARAMETER); } /* Must acquire the interpreter lock during this operation */ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* Install the table and load it into the namespace */ ACPI_INFO((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); (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; } status = acpi_ns_load_table(table_index, acpi_gbl_root_node); /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, acpi_gbl_table_handler_context); } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); return_ACPI_STATUS(status); }
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); /* Parameter validation */ if (!table) { 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); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* 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); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } status = acpi_ns_load_table(table_index, acpi_gbl_root_node); /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, acpi_gbl_table_handler_context); } unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); return_ACPI_STATUS(status); }
acpi_status acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) { struct acpi_table_header *table; acpi_status status; acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(tb_load_table); /* * Note: Now table is "INSTALLED", it must be validated before * using. */ status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ns_load_table(table_index, parent_node); /* * This case handles the legacy option that groups all module-level * code blocks together and defers execution until all of the tables * are loaded. Execute all of these blocks at this time. * Execute any module-level code that was detected during the table * load phase. * * Note: this option is deprecated and will be eliminated in the * future. Use of this option can cause problems with AML code that * depends upon in-order immediate execution of module-level code. */ acpi_ns_exec_module_code_list(); /* * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is * responsible for discovering any new wake GPEs by running _PRW methods * that may have been loaded by this table. */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { acpi_ev_update_gpes(owner_id); } /* Invoke table handler */ acpi_tb_notify_table(ACPI_TABLE_EVENT_LOAD, table); return_ACPI_STATUS(status); }
acpi_status acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node) { struct acpi_table_header *table; acpi_status status; acpi_owner_id owner_id; ACPI_FUNCTION_TRACE(tb_load_table); /* * Note: Now table is "INSTALLED", it must be validated before * using. */ status = acpi_get_table_by_index(table_index, &table); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } status = acpi_ns_load_table(table_index, parent_node); /* Execute any module-level code that was found in the table */ if (!acpi_gbl_parse_table_as_term_list && acpi_gbl_group_module_level_code) { acpi_ns_exec_module_code_list(); } /* * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is * responsible for discovering any new wake GPEs by running _PRW methods * that may have been loaded by this table. */ status = acpi_tb_get_owner_id(table_index, &owner_id); if (ACPI_SUCCESS(status)) { acpi_ev_update_gpes(owner_id); } /* Invoke table handler if present */ if (acpi_gbl_table_handler) { (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table, acpi_gbl_table_handler_context); } return_ACPI_STATUS(status); }
acpi_status acpi_load_table ( acpi_table_header *table_ptr) { acpi_status status; acpi_table_desc table_info; FUNCTION_TRACE ("Acpi_load_table"); if (!table_ptr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Copy the table to a local buffer */ status = acpi_tb_get_table (0, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the new table into the local data structures */ status = acpi_tb_install_table (NULL, &table_info); if (ACPI_FAILURE (status)) { /* Free table allocated by Acpi_tb_get_table */ acpi_tb_delete_single_table (&table_info); return_ACPI_STATUS (status); } status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ acpi_tb_uninstall_table (table_info.installed_desc); return_ACPI_STATUS (status); } return_ACPI_STATUS (status); }
static acpi_status acpi_ex_add_table(u32 table_index, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { acpi_status status; union acpi_operand_object *obj_desc; ACPI_FUNCTION_TRACE(ex_add_table); /* Create an object to be the table handle */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE); if (!obj_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Init the table handle */ obj_desc->reference.opcode = AML_LOAD_OP; *ddb_handle = obj_desc; /* Install the new table into the local data structures */ obj_desc->reference.object = ACPI_CAST_PTR(void, (unsigned long)table_index); /* Add the table to the namespace */ status = acpi_ns_load_table(table_index, parent_node); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(obj_desc); *ddb_handle = NULL; } return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_load_table * * PARAMETERS: table_ptr - pointer to a buffer containing the entire * table to be loaded * * RETURN: Status * * DESCRIPTION: This function is called to load a table from the caller's * buffer. The buffer must contain an entire ACPI Table including * a valid header. The header fields will be verified, and if it * is determined that the table is invalid, the call will fail. * ******************************************************************************/ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) { acpi_status status; u32 table_index; struct acpi_table_desc table_desc; if (!table_ptr) return AE_BAD_PARAMETER; ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); table_desc.pointer = table_ptr; table_desc.length = table_ptr->length; table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; /* * Install the new table into the local data structures */ status = acpi_tb_add_table(&table_desc, &table_index); if (ACPI_FAILURE(status)) { return status; } status = acpi_ns_load_table(table_index, acpi_gbl_root_node); return status; }
/******************************************************************************* * * FUNCTION: acpi_tb_load_namespace * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in * the RSDT/XSDT. * ******************************************************************************/ 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); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* * 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_NAMESEG(table->signature.ascii, ACPI_SIG_DSDT) || ACPI_FAILURE(acpi_tb_validate_table(table))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } /* * 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_validate_table. */ acpi_gbl_DSDT = table->pointer; /* * Optionally copy the entire DSDT to local memory (instead of simply * mapping it.) There are some BIOSs that corrupt or replace the original * DSDT, creating the need for this option. Default is FALSE, do not copy * the DSDT. */ if (acpi_gbl_copy_dsdt_locally) { new_dsdt = acpi_tb_copy_dsdt(acpi_gbl_dsdt_index); if (new_dsdt) { acpi_gbl_DSDT = new_dsdt; } } /* * Save the original DSDT header for detection of table corruption * and/or replacement of the DSDT from outside the OS. */ memcpy(&acpi_gbl_original_dsdt_header, acpi_gbl_DSDT, sizeof(struct acpi_table_header)); /* Load and parse tables */ (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); status = acpi_ns_load_table(acpi_gbl_dsdt_index, acpi_gbl_root_node); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); if (ACPI_FAILURE(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 */ for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { table = &acpi_gbl_root_table_list.tables[i]; if (!table->address || (!ACPI_COMPARE_NAMESEG (table->signature.ascii, ACPI_SIG_SSDT) && !ACPI_COMPARE_NAMESEG(table->signature.ascii, ACPI_SIG_PSDT) && !ACPI_COMPARE_NAMESEG(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); status = acpi_ns_load_table(i, acpi_gbl_root_node); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 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++; } } if (!tables_failed) { ACPI_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)); /* Indicate at least one failure */ status = AE_CTRL_TERMINATE; } #ifdef ACPI_APPLICATION ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\n")); #endif unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); }
acpi_status acpi_load_table ( struct acpi_table_header *table_ptr) { acpi_status status; struct acpi_table_desc table_info; struct acpi_pointer address; ACPI_FUNCTION_TRACE ("acpi_load_table"); if (!table_ptr) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Copy the table to a local buffer */ address.pointer_type = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING; address.pointer.logical = table_ptr; status = acpi_tb_get_table_body (&address, table_ptr, &table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the new table into the local data structures */ status = acpi_tb_install_table (&table_info); if (ACPI_FAILURE (status)) { /* Free table allocated by acpi_tb_get_table_body */ acpi_tb_delete_single_table (&table_info); return_ACPI_STATUS (status); } /* Convert the table to common format if necessary */ switch (table_info.type) { case ACPI_TABLE_FADT: status = acpi_tb_convert_table_fadt (); break; case ACPI_TABLE_FACS: status = acpi_tb_build_common_facs (&table_info); break; default: /* Load table into namespace if it contains executable AML */ status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node); break; } if (ACPI_FAILURE (status)) { /* Uninstall table and free the buffer */ (void) acpi_tb_uninstall_table (table_info.installed_desc); } return_ACPI_STATUS (status); }
static acpi_status acpi_ex_add_table(struct acpi_table_header *table, struct acpi_namespace_node *parent_node, union acpi_operand_object **ddb_handle) { acpi_status status; struct acpi_table_desc table_info; union acpi_operand_object *obj_desc; ACPI_FUNCTION_TRACE(ex_add_table); /* Create an object to be the table handle */ obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE); if (!obj_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } /* Init the table handle */ obj_desc->reference.opcode = AML_LOAD_OP; *ddb_handle = obj_desc; /* Install the new table into the local data structures */ ACPI_MEMSET(&table_info, 0, sizeof(struct acpi_table_desc)); table_info.type = ACPI_TABLE_ID_SSDT; table_info.pointer = table; table_info.length = (acpi_size) table->length; table_info.allocation = ACPI_MEM_ALLOCATED; status = acpi_tb_install_table(&table_info); obj_desc->reference.object = table_info.installed_desc; if (ACPI_FAILURE(status)) { if (status == AE_ALREADY_EXISTS) { /* Table already exists, just return the handle */ return_ACPI_STATUS(AE_OK); } goto cleanup; } /* Add the table to the namespace */ status = acpi_ns_load_table(table_info.installed_desc, parent_node); if (ACPI_FAILURE(status)) { /* Uninstall table on error */ (void)acpi_tb_uninstall_table(table_info.installed_desc); goto cleanup; } return_ACPI_STATUS(AE_OK); cleanup: acpi_ut_remove_reference(obj_desc); *ddb_handle = NULL; return_ACPI_STATUS(status); }
acpi_status acpi_ns_load_table_by_type ( acpi_table_type table_type) { u32 i; acpi_status status = AE_OK; acpi_table_desc *table_desc; FUNCTION_TRACE ("Ns_load_table_by_type"); acpi_ut_acquire_mutex (ACPI_MTX_TABLES); /* * Table types supported are: * DSDT (one), SSDT/PSDT (multiple) */ switch (table_type) { case ACPI_TABLE_DSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n")); table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT]; /* If table already loaded into namespace, just return */ if (table_desc->loaded_into_namespace) { goto unlock_and_exit; } table_desc->table_id = TABLE_ID_DSDT; /* Now load the single DSDT */ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); if (ACPI_SUCCESS (status)) { table_desc->loaded_into_namespace = TRUE; } break; case ACPI_TABLE_SSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n", acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count)); /* * Traverse list of SSDT tables */ table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT]; for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) { /* * Only attempt to load table if it is not * already loaded! */ if (!table_desc->loaded_into_namespace) { status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { break; } table_desc->loaded_into_namespace = TRUE; } table_desc = table_desc->next; } break; case ACPI_TABLE_PSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n", acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count)); /* * Traverse list of PSDT tables */ table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT]; for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) { /* Only attempt to load table if it is not already loaded! */ if (!table_desc->loaded_into_namespace) { status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); if (ACPI_FAILURE (status)) { break; } table_desc->loaded_into_namespace = TRUE; } table_desc = table_desc->next; } break; default: status = AE_SUPPORT; break; } unlock_and_exit: acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); }
/******************************************************************************* * * FUNCTION: acpi_tb_load_namespace * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in * the RSDT/XSDT. * ******************************************************************************/ static acpi_status acpi_tb_load_namespace(void) { acpi_status status; u32 i; struct acpi_table_header *new_dsdt; ACPI_FUNCTION_TRACE(tb_load_namespace); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* * Load the namespace. The DSDT is required, but any SSDT and * PSDT tables are optional. Verify the DSDT. */ 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]))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } /* * 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. */ acpi_gbl_DSDT = acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer; /* * Optionally copy the entire DSDT to local memory (instead of simply * mapping it.) There are some BIOSs that corrupt or replace the original * DSDT, creating the need for this option. Default is FALSE, do not copy * the DSDT. */ if (acpi_gbl_copy_dsdt_locally) { new_dsdt = acpi_tb_copy_dsdt(ACPI_TABLE_INDEX_DSDT); if (new_dsdt) { acpi_gbl_DSDT = new_dsdt; } } /* * 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)); (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); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* 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; } if (no_auto_ssdt) { printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); 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); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); } ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_tb_load_namespace * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in * the RSDT/XSDT. * ******************************************************************************/ static acpi_status acpi_tb_load_namespace(void) { acpi_status status; u32 i; ACPI_FUNCTION_TRACE(tb_load_namespace); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* * Load the namespace. The DSDT is required, but any SSDT and PSDT tables * are optional. */ if (!acpi_gbl_root_table_list.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]))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } /* A valid DSDT is required */ status = acpi_tb_verify_table(&acpi_gbl_root_table_list. tables[ACPI_TABLE_INDEX_DSDT]); if (ACPI_FAILURE(status)) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } (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); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* 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.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; } if (no_auto_ssdt) { printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); 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); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); } ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); }
/******************************************************************************* * * FUNCTION: acpi_tb_load_namespace * * PARAMETERS: None * * RETURN: Status * * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in * the RSDT/XSDT. * ******************************************************************************/ static acpi_status acpi_tb_load_namespace(void) { acpi_status status; struct acpi_table_header *table; u32 i; ACPI_FUNCTION_TRACE(tb_load_namespace); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); /* * Load the namespace. The DSDT is required, but any SSDT and PSDT tables * are optional. */ if (!acpi_gbl_root_table_list.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]))) { status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } /* * Find DSDT table */ status = acpi_os_table_override(acpi_gbl_root_table_list. tables[ACPI_TABLE_INDEX_DSDT].pointer, &table); if (ACPI_SUCCESS(status) && table) { /* * DSDT table has been found */ acpi_tb_delete_table(&acpi_gbl_root_table_list. tables[ACPI_TABLE_INDEX_DSDT]); acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = table; acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = table->length; acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = ACPI_TABLE_ORIGIN_UNKNOWN; ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); acpi_tb_print_table_header(0, table); if (no_auto_ssdt == 0) { printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); } } status = acpi_tb_verify_table(&acpi_gbl_root_table_list. tables[ACPI_TABLE_INDEX_DSDT]); if (ACPI_FAILURE(status)) { /* A valid DSDT is required */ status = AE_NO_ACPI_TABLES; goto unlock_and_exit; } (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); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } /* * 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.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; } if (no_auto_ssdt) { printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n"); 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); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); } ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); return_ACPI_STATUS(status); }