acpi_status acpi_tb_install_table ( acpi_table_header *table_ptr, acpi_table_desc *table_info) { acpi_status status; FUNCTION_TRACE ("Tb_install_table"); /* * Check the table signature and make sure it is recognized * Also checks the header checksum */ status = acpi_tb_recognize_table (table_ptr, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Lock tables while installing */ acpi_ut_acquire_mutex (ACPI_MTX_TABLES); /* Install the table into the global data structure */ status = acpi_tb_init_table_descriptor (table_info->type, table_info); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer)); acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); }
acpi_status acpi_tb_get_primary_table ( struct acpi_pointer *address, struct acpi_table_desc *table_info) { acpi_status status; struct acpi_table_header header; ACPI_FUNCTION_TRACE ("tb_get_primary_table"); /* Ignore a NULL address in the RSDT */ if (!address->pointer.value) { return_ACPI_STATUS (AE_OK); } /* * Get the header in order to get signature and table size */ status = acpi_tb_get_table_header (address, &header); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Clear the table_info */ ACPI_MEMSET (table_info, 0, sizeof (struct acpi_table_desc)); /* * Check the table signature and make sure it is recognized. * Also checks the header checksum */ table_info->pointer = &header; status = acpi_tb_recognize_table (table_info, ACPI_TABLE_PRIMARY); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the entire table */ status = acpi_tb_get_table_body (address, &header, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the table */ status = acpi_tb_install_table (table_info); return_ACPI_STATUS (status); }
static acpi_status acpi_tb_get_secondary_table ( struct acpi_pointer *address, acpi_string signature, struct acpi_table_desc *table_info) { acpi_status status; struct acpi_table_header header; ACPI_FUNCTION_TRACE_STR ("tb_get_secondary_table", signature); /* Get the header in order to match the signature */ status = acpi_tb_get_table_header (address, &header); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Signature must match request */ if (ACPI_STRNCMP (header.signature, signature, ACPI_NAME_SIZE)) { ACPI_REPORT_ERROR (( "Incorrect table signature - wanted [%s] found [%4.4s]\n", signature, header.signature)); return_ACPI_STATUS (AE_BAD_SIGNATURE); } /* * Check the table signature and make sure it is recognized. * Also checks the header checksum */ table_info->pointer = &header; status = acpi_tb_recognize_table (table_info, ACPI_TABLE_SECONDARY); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Get the entire table */ status = acpi_tb_get_table_body (address, &header, table_info); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* Install the table */ status = acpi_tb_install_table (table_info); 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; 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); } /* Check signature for a valid table type */ status = acpi_tb_recognize_table(&table_info, ACPI_TABLE_ALL); 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)) { if (status == AE_ALREADY_EXISTS) { /* Table already exists, no error */ status = AE_OK; } /* 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_ID_FADT: status = acpi_tb_convert_table_fadt(); break; case ACPI_TABLE_ID_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); }