Commit 428f2112 authored by Alexey Starikovskiy's avatar Alexey Starikovskiy Committed by Len Brown

ACPICA: Miscellaneous table manager updates and optimizations

Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 77f6a9fc
...@@ -103,7 +103,7 @@ int __init acpi_blacklisted(void) ...@@ -103,7 +103,7 @@ int __init acpi_blacklisted(void)
{ {
int i = 0; int i = 0;
int blacklisted = 0; int blacklisted = 0;
struct acpi_table_header *table_header; struct acpi_table_header table_header;
while (acpi_blacklist[i].oem_id[0] != '\0') { while (acpi_blacklist[i].oem_id[0] != '\0') {
if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) { if (acpi_get_table_header(acpi_blacklist[i].table, 0, &table_header)) {
...@@ -111,13 +111,13 @@ int __init acpi_blacklisted(void) ...@@ -111,13 +111,13 @@ int __init acpi_blacklisted(void)
continue; continue;
} }
if (strncmp(acpi_blacklist[i].oem_id, table_header->oem_id, 6)) { if (strncmp(acpi_blacklist[i].oem_id, table_header.oem_id, 6)) {
i++; i++;
continue; continue;
} }
if (strncmp if (strncmp
(acpi_blacklist[i].oem_table_id, table_header->oem_table_id, (acpi_blacklist[i].oem_table_id, table_header.oem_table_id,
8)) { 8)) {
i++; i++;
continue; continue;
...@@ -126,14 +126,14 @@ int __init acpi_blacklisted(void) ...@@ -126,14 +126,14 @@ int __init acpi_blacklisted(void)
if ((acpi_blacklist[i].oem_revision_predicate == all_versions) if ((acpi_blacklist[i].oem_revision_predicate == all_versions)
|| (acpi_blacklist[i].oem_revision_predicate == || (acpi_blacklist[i].oem_revision_predicate ==
less_than_or_equal less_than_or_equal
&& table_header->oem_revision <= && table_header.oem_revision <=
acpi_blacklist[i].oem_revision) acpi_blacklist[i].oem_revision)
|| (acpi_blacklist[i].oem_revision_predicate == || (acpi_blacklist[i].oem_revision_predicate ==
greater_than_or_equal greater_than_or_equal
&& table_header->oem_revision >= && table_header.oem_revision >=
acpi_blacklist[i].oem_revision) acpi_blacklist[i].oem_revision)
|| (acpi_blacklist[i].oem_revision_predicate == equal || (acpi_blacklist[i].oem_revision_predicate == equal
&& table_header->oem_revision == && table_header.oem_revision ==
acpi_blacklist[i].oem_revision)) { acpi_blacklist[i].oem_revision)) {
printk(KERN_ERR PREFIX printk(KERN_ERR PREFIX
......
...@@ -279,13 +279,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -279,13 +279,14 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
acpi_native_uint table_index; acpi_native_uint table_index;
acpi_physical_address address; acpi_physical_address address;
struct acpi_table_header table_header; struct acpi_table_header table_header;
struct acpi_table_desc table_desc;
acpi_integer temp; acpi_integer temp;
u32 i; u32 i;
ACPI_FUNCTION_TRACE(ex_load_op); ACPI_FUNCTION_TRACE(ex_load_op);
/* Object can be either an op_region or a Field */ /* Object can be either an op_region or a Field */
ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc));
switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
case ACPI_TYPE_REGION: case ACPI_TYPE_REGION:
...@@ -408,10 +409,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, ...@@ -408,10 +409,13 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
goto cleanup; goto cleanup;
} }
table_desc.pointer = table_ptr;
table_desc.length = table_ptr->length;
table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
/* /*
* Install the new table into the local data structures * Install the new table into the local data structures
*/ */
status = acpi_tb_add_table(table_ptr, &table_index); status = acpi_tb_add_table(&table_desc, &table_index);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto cleanup; goto cleanup;
} }
......
...@@ -61,16 +61,19 @@ ACPI_MODULE_NAME("tbinstal") ...@@ -61,16 +61,19 @@ ACPI_MODULE_NAME("tbinstal")
*****************************************************************************/ *****************************************************************************/
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
{ {
acpi_status status; acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE(tb_verify_table); ACPI_FUNCTION_TRACE(tb_verify_table);
/* Map the table if necessary */ /* Map the table if necessary */
if (!table_desc->pointer) { if (!table_desc->pointer) {
table_desc->pointer = if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) ==
acpi_tb_map(table_desc->address, table_desc->length, ACPI_TABLE_ORIGIN_MAPPED) {
table_desc->flags & ACPI_TABLE_ORIGIN_MASK); table_desc->pointer =
acpi_os_map_memory(table_desc->address,
table_desc->length);
}
if (!table_desc->pointer) { if (!table_desc->pointer) {
return_ACPI_STATUS(AE_NO_MEMORY); return_ACPI_STATUS(AE_NO_MEMORY);
} }
...@@ -78,14 +81,15 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ...@@ -78,14 +81,15 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
/* FACS is the odd table, has no standard ACPI header and no checksum */ /* FACS is the odd table, has no standard ACPI header and no checksum */
if (ACPI_COMPARE_NAME(&(table_desc->signature), ACPI_SIG_FACS)) { if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) {
return_ACPI_STATUS(AE_OK);
}
/* Always calculate checksum, ignore bad checksum if requested */ /* Always calculate checksum, ignore bad checksum if requested */
status =
acpi_tb_verify_checksum(table_desc->pointer,
table_desc->length);
}
status =
acpi_tb_verify_checksum(table_desc->pointer, table_desc->length);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -93,7 +97,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ...@@ -93,7 +97,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
* *
* FUNCTION: acpi_tb_add_table * FUNCTION: acpi_tb_add_table
* *
* PARAMETERS: Table - Pointer to the table header * PARAMETERS: table_desc - Table descriptor
* table_index - Where the table index is returned * table_index - Where the table index is returned
* *
* RETURN: Status * RETURN: Status
...@@ -103,7 +107,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) ...@@ -103,7 +107,7 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_tb_add_table(struct acpi_table_header *table, acpi_tb_add_table(struct acpi_table_desc *table_desc,
acpi_native_uint * table_index) acpi_native_uint * table_index)
{ {
acpi_native_uint i; acpi_native_uint i;
...@@ -112,6 +116,25 @@ acpi_tb_add_table(struct acpi_table_header *table, ...@@ -112,6 +116,25 @@ acpi_tb_add_table(struct acpi_table_header *table,
ACPI_FUNCTION_TRACE(tb_add_table); ACPI_FUNCTION_TRACE(tb_add_table);
if (!table_desc->pointer) {
status = acpi_tb_verify_table(table_desc);
if (ACPI_FAILURE(status) || !table_desc->pointer) {
return_ACPI_STATUS(status);
}
}
/* The table must be either an SSDT or a PSDT */
if ((!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT))
&&
(!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)))
{
ACPI_ERROR((AE_INFO,
"Table has invalid signature [%4.4s], must be SSDT or PSDT",
table_desc->pointer->signature));
return_ACPI_STATUS(AE_BAD_SIGNATURE);
}
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
/* Check if table is already registered */ /* Check if table is already registered */
...@@ -127,18 +150,17 @@ acpi_tb_add_table(struct acpi_table_header *table, ...@@ -127,18 +150,17 @@ acpi_tb_add_table(struct acpi_table_header *table,
} }
} }
length = ACPI_MIN(table->length, length = ACPI_MIN(table_desc->length,
acpi_gbl_root_table_list.tables[i].pointer-> acpi_gbl_root_table_list.tables[i].length);
length); if (ACPI_MEMCMP(table_desc->pointer,
if (ACPI_MEMCMP acpi_gbl_root_table_list.tables[i].pointer,
(table, acpi_gbl_root_table_list.tables[i].pointer, length)) {
length)) {
continue; continue;
} }
/* Table is already registered */ /* Table is already registered */
ACPI_FREE(table); acpi_tb_delete_table(table_desc);
*table_index = i; *table_index = i;
goto release; goto release;
} }
...@@ -146,14 +168,14 @@ acpi_tb_add_table(struct acpi_table_header *table, ...@@ -146,14 +168,14 @@ acpi_tb_add_table(struct acpi_table_header *table,
/* /*
* Add the table to the global table list * Add the table to the global table list
*/ */
status = acpi_tb_store_table(ACPI_TO_INTEGER(table), status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
table, table->length, table_desc->length, table_desc->flags,
ACPI_TABLE_ORIGIN_ALLOCATED, table_index); table_index);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
goto release; goto release;
} }
acpi_tb_print_table_header(0, table); acpi_tb_print_table_header(table_desc->address, table_desc->pointer);
release: release:
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
...@@ -282,25 +304,20 @@ acpi_tb_store_table(acpi_physical_address address, ...@@ -282,25 +304,20 @@ acpi_tb_store_table(acpi_physical_address address,
* *
******************************************************************************/ ******************************************************************************/
void acpi_tb_delete_table(acpi_native_uint table_index) void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
{ {
struct acpi_table_desc *table_desc;
/* table_index assumed valid */
table_desc = &acpi_gbl_root_table_list.tables[table_index];
/* Table must be mapped or allocated */ /* Table must be mapped or allocated */
if (!table_desc->pointer) { if (!table_desc->pointer) {
return; return;
} }
switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
if (table_desc->flags & ACPI_TABLE_ORIGIN_MAPPED) { case ACPI_TABLE_ORIGIN_MAPPED:
acpi_tb_unmap(table_desc->pointer, table_desc->length, acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
table_desc->flags & ACPI_TABLE_ORIGIN_MASK); break;
} else if (table_desc->flags & ACPI_TABLE_ORIGIN_ALLOCATED) { case ACPI_TABLE_ORIGIN_ALLOCATED:
ACPI_FREE(table_desc->pointer); ACPI_FREE(table_desc->pointer);
break;
default:;
} }
table_desc->pointer = NULL; table_desc->pointer = NULL;
...@@ -329,7 +346,7 @@ void acpi_tb_terminate(void) ...@@ -329,7 +346,7 @@ void acpi_tb_terminate(void)
/* Delete the individual tables */ /* Delete the individual tables */
for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
acpi_tb_delete_table(i); acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]);
} }
/* /*
......
...@@ -462,49 +462,3 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) ...@@ -462,49 +462,3 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
/******************************************************************************
*
* FUNCTION: acpi_tb_map
*
* PARAMETERS: Address - Address to be mapped
* Length - Length to be mapped
* Flags - Logical or physical addressing mode
*
* RETURN: Pointer to mapped region
*
* DESCRIPTION: Maps memory according to flag
*
*****************************************************************************/
void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags)
{
if (flags == ACPI_TABLE_ORIGIN_MAPPED) {
return (acpi_os_map_memory(address, length));
} else {
return (ACPI_CAST_PTR(void, address));
}
}
/******************************************************************************
*
* FUNCTION: acpi_tb_unmap
*
* PARAMETERS: Pointer - To mapped region
* Length - Length to be unmapped
* Flags - Logical or physical addressing mode
*
* RETURN: None
*
* DESCRIPTION: Unmaps memory according to flag
*
*****************************************************************************/
void acpi_tb_unmap(void *pointer, u32 length, u32 flags)
{
if (flags == ACPI_TABLE_ORIGIN_MAPPED) {
acpi_os_unmap_memory(pointer, length);
}
}
...@@ -220,16 +220,25 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr) ...@@ -220,16 +220,25 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
{ {
acpi_status status; acpi_status status;
acpi_native_uint table_index; acpi_native_uint 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 * Install the new table into the local data structures
*/ */
status = acpi_tb_add_table(table_ptr, &table_index); status = acpi_tb_add_table(&table_desc, &table_index);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return status;
} }
status = acpi_ns_load_table(table_index, acpi_gbl_root_node); status = acpi_ns_load_table(table_index, acpi_gbl_root_node);
return_ACPI_STATUS(status); return status;
} }
ACPI_EXPORT_SYMBOL(acpi_load_table) ACPI_EXPORT_SYMBOL(acpi_load_table)
...@@ -240,8 +249,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) ...@@ -240,8 +249,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
* *
* PARAMETERS: Signature - ACPI signature of needed table * PARAMETERS: Signature - ACPI signature of needed table
* Instance - Which instance (for SSDTs) * Instance - Which instance (for SSDTs)
* out_table_header - Where the pointer to the table header * out_table_header - The pointer to the table header to fill
* is returned
* *
* RETURN: Status and pointer to mapped table header * RETURN: Status and pointer to mapped table header
* *
...@@ -254,10 +262,11 @@ ACPI_EXPORT_SYMBOL(acpi_load_table) ...@@ -254,10 +262,11 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
acpi_status acpi_status
acpi_get_table_header(char *signature, acpi_get_table_header(char *signature,
acpi_native_uint instance, acpi_native_uint instance,
struct acpi_table_header **out_table_header) struct acpi_table_header *out_table_header)
{ {
acpi_native_uint i; acpi_native_uint i;
acpi_native_uint j; acpi_native_uint j;
struct acpi_table_header *header;
/* Parameter validation */ /* Parameter validation */
...@@ -279,16 +288,31 @@ acpi_get_table_header(char *signature, ...@@ -279,16 +288,31 @@ acpi_get_table_header(char *signature,
continue; continue;
} }
*out_table_header = if (!acpi_gbl_root_table_list.tables[i].pointer) {
acpi_tb_map(acpi_gbl_root_table_list.tables[i].address, if ((acpi_gbl_root_table_list.tables[i].
(u32) sizeof(struct acpi_table_header), flags & ACPI_TABLE_ORIGIN_MASK) ==
acpi_gbl_root_table_list.tables[i]. ACPI_TABLE_ORIGIN_MAPPED) {
flags & ACPI_TABLE_ORIGIN_MASK); header =
acpi_os_map_memory(acpi_gbl_root_table_list.
if (!(*out_table_header)) { tables[i].address,
return (AE_NO_MEMORY); sizeof(struct
acpi_table_header));
if (!header) {
return AE_NO_MEMORY;
}
ACPI_MEMCPY(out_table_header, header,
sizeof(struct acpi_table_header));
acpi_os_unmap_memory(header,
sizeof(struct
acpi_table_header));
} else {
return AE_NOT_FOUND;
}
} else {
ACPI_MEMCPY(out_table_header,
acpi_gbl_root_table_list.tables[i].pointer,
sizeof(struct acpi_table_header));
} }
return (AE_OK); return (AE_OK);
} }
......
...@@ -109,7 +109,7 @@ acpi_status acpi_unload_table_id(acpi_owner_id id); ...@@ -109,7 +109,7 @@ acpi_status acpi_unload_table_id(acpi_owner_id id);
acpi_status acpi_status
acpi_get_table_header(acpi_string signature, acpi_get_table_header(acpi_string signature,
acpi_native_uint instance, acpi_native_uint instance,
struct acpi_table_header **out_table_header); struct acpi_table_header *out_table_header);
acpi_status acpi_status
acpi_get_table(acpi_string signature, acpi_get_table(acpi_string signature,
......
...@@ -69,7 +69,7 @@ acpi_status acpi_tb_resize_root_table_list(void); ...@@ -69,7 +69,7 @@ acpi_status acpi_tb_resize_root_table_list(void);
acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc); acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc);
acpi_status acpi_status
acpi_tb_add_table(struct acpi_table_header *table, acpi_tb_add_table(struct acpi_table_desc *table_desc,
acpi_native_uint * table_index); acpi_native_uint * table_index);
acpi_status acpi_status
...@@ -77,7 +77,7 @@ acpi_tb_store_table(acpi_physical_address address, ...@@ -77,7 +77,7 @@ acpi_tb_store_table(acpi_physical_address address,
struct acpi_table_header *table, struct acpi_table_header *table,
u32 length, u8 flags, acpi_native_uint * table_index); u32 length, u8 flags, acpi_native_uint * table_index);
void acpi_tb_delete_table(acpi_native_uint table_index); void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void); void acpi_tb_terminate(void);
...@@ -113,8 +113,4 @@ acpi_tb_install_table(acpi_physical_address address, ...@@ -113,8 +113,4 @@ acpi_tb_install_table(acpi_physical_address address,
acpi_status acpi_status
acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags); acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
void *acpi_tb_map(acpi_physical_address address, u32 length, u32 flags);
void acpi_tb_unmap(void *pointer, u32 length, u32 flags);
#endif /* __ACTABLES_H__ */ #endif /* __ACTABLES_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment