X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Facpi%2Ftables%2Ftbutils.c;h=209a401801e3aba9ad3715247c9efe0cc58ca59c;hb=refs%2Fheads%2Fvserver;hp=fef603f407bda0355600b3ebe05c5974041f435b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index fef603f40..209a40180 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2004, R. Byron Moore + * Copyright (C) 2000 - 2006, R. Byron Moore * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,57 +41,85 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #include #include - #define _COMPONENT ACPI_TABLES - ACPI_MODULE_NAME ("tbutils") +ACPI_MODULE_NAME("tbutils") +/* Local prototypes */ +#ifdef ACPI_OBSOLETE_FUNCTIONS +acpi_status +acpi_tb_handle_to_object(u16 table_id, struct acpi_table_desc **table_desc); +#endif /******************************************************************************* * - * FUNCTION: acpi_tb_handle_to_object + * FUNCTION: acpi_tb_is_table_installed * - * PARAMETERS: table_id - Id for which the function is searching - * table_desc - Pointer to return the matching table - * descriptor. + * PARAMETERS: new_table_desc - Descriptor for new table being installed * - * RETURN: Search the tables to find one with a matching table_id and - * return a pointer to that table descriptor. + * RETURN: Status - AE_ALREADY_EXISTS if the table is already installed + * + * DESCRIPTION: Determine if an ACPI table is already installed + * + * MUTEX: Table data structures should be locked * ******************************************************************************/ -acpi_status -acpi_tb_handle_to_object ( - u16 table_id, - struct acpi_table_desc **return_table_desc) +acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) { - u32 i; - struct acpi_table_desc *table_desc; - - - ACPI_FUNCTION_NAME ("tb_handle_to_object"); + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_TRACE(tb_is_table_installed); + + /* Get the list descriptor and first table descriptor */ + + table_desc = acpi_gbl_table_lists[new_table_desc->type].next; + + /* Examine all installed tables of this type */ + + while (table_desc) { + /* + * If the table lengths match, perform a full bytewise compare. This + * means that we will allow tables with duplicate oem_table_id(s), as + * long as the tables are different in some way. + * + * Checking if the table has been loaded into the namespace means that + * we don't check for duplicate tables during the initial installation + * of tables within the RSDT/XSDT. + */ + if ((table_desc->loaded_into_namespace) && + (table_desc->pointer->length == + new_table_desc->pointer->length) + && + (!ACPI_MEMCMP + (table_desc->pointer, new_table_desc->pointer, + new_table_desc->pointer->length))) { + + /* Match: this table is already installed */ + + ACPI_DEBUG_PRINT((ACPI_DB_TABLES, + "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", + new_table_desc->pointer->signature, + new_table_desc->pointer->revision, + new_table_desc->pointer-> + oem_table_id)); + + new_table_desc->owner_id = table_desc->owner_id; + new_table_desc->installed_desc = table_desc; + + return_ACPI_STATUS(AE_ALREADY_EXISTS); + } + /* Get next table on the list */ - for (i = 0; i < ACPI_TABLE_MAX; i++) { - table_desc = acpi_gbl_table_lists[i].next; - while (table_desc) { - if (table_desc->table_id == table_id) { - *return_table_desc = table_desc; - return (AE_OK); - } - - table_desc = table_desc->next; - } + table_desc = table_desc->next; } - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id)); - return (AE_BAD_PARAMETER); + return_ACPI_STATUS(AE_OK); } - /******************************************************************************* * * FUNCTION: acpi_tb_validate_table_header @@ -113,127 +141,202 @@ acpi_tb_handle_to_object ( ******************************************************************************/ acpi_status -acpi_tb_validate_table_header ( - struct acpi_table_header *table_header) +acpi_tb_validate_table_header(struct acpi_table_header *table_header) { - acpi_name signature; - - - ACPI_FUNCTION_NAME ("tb_validate_table_header"); + acpi_name signature; + ACPI_FUNCTION_ENTRY(); /* Verify that this is a valid address */ - if (!acpi_os_readable (table_header, sizeof (struct acpi_table_header))) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Cannot read table header at %p\n", table_header)); + if (!acpi_os_readable(table_header, sizeof(struct acpi_table_header))) { + ACPI_ERROR((AE_INFO, + "Cannot read table header at %p", table_header)); + return (AE_BAD_ADDRESS); } /* Ensure that the signature is 4 ASCII characters */ - ACPI_MOVE_32_TO_32 (&signature, table_header->signature); - if (!acpi_ut_valid_acpi_name (signature)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Table signature at %p [%p] has invalid characters\n", - table_header, &signature)); + ACPI_MOVE_32_TO_32(&signature, table_header->signature); + if (!acpi_ut_valid_acpi_name(signature)) { + ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", + signature)); - ACPI_REPORT_WARNING (("Invalid table signature found: [%4.4s]\n", - (char *) &signature)); - ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header)); + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); return (AE_BAD_SIGNATURE); } /* Validate the table length */ - if (table_header->length < sizeof (struct acpi_table_header)) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Invalid length in table header %p name %4.4s\n", - table_header, (char *) &signature)); + if (table_header->length < sizeof(struct acpi_table_header)) { + ACPI_ERROR((AE_INFO, + "Invalid length 0x%X in table with signature %4.4s", + (u32) table_header->length, + ACPI_CAST_PTR(char, &signature))); - ACPI_REPORT_WARNING (("Invalid table header length (0x%X) found\n", - (u32) table_header->length)); - ACPI_DUMP_BUFFER (table_header, sizeof (struct acpi_table_header)); + ACPI_DUMP_BUFFER(table_header, + sizeof(struct acpi_table_header)); return (AE_BAD_HEADER); } return (AE_OK); } - /******************************************************************************* * - * FUNCTION: acpi_tb_verify_table_checksum + * FUNCTION: acpi_tb_sum_table * - * PARAMETERS: *table_header - ACPI table to verify + * PARAMETERS: Buffer - Buffer to sum + * Length - Size of the buffer * - * RETURN: 8 bit checksum of table + * RETURN: 8 bit sum of buffer * - * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct - * table should have a checksum of 0. + * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. * ******************************************************************************/ -acpi_status -acpi_tb_verify_table_checksum ( - struct acpi_table_header *table_header) +u8 acpi_tb_sum_table(void *buffer, u32 length) { - u8 checksum; - acpi_status status = AE_OK; + acpi_native_uint i; + u8 sum = 0; + + if (!buffer || !length) { + return (0); + } + + for (i = 0; i < length; i++) { + sum = (u8) (sum + ((u8 *) buffer)[i]); + } + return (sum); +} +/******************************************************************************* + * + * FUNCTION: acpi_tb_generate_checksum + * + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) + * + * RETURN: 8 bit checksum of buffer + * + * DESCRIPTION: Computes an 8 bit checksum of the table. + * + ******************************************************************************/ - ACPI_FUNCTION_TRACE ("tb_verify_table_checksum"); +u8 acpi_tb_generate_checksum(struct acpi_table_header * table) +{ + u8 checksum; + /* Sum the entire table as-is */ - /* Compute the checksum on the table */ + checksum = acpi_tb_sum_table(table, table->length); - checksum = acpi_tb_checksum (table_header, table_header->length); + /* Subtract off the existing checksum value in the table */ - /* Return the appropriate exception */ + checksum = (u8) (checksum - table->checksum); - if (checksum) { - ACPI_REPORT_WARNING (("Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)\n", - table_header->signature, (u32) table_header->checksum, (u32) checksum)); + /* Compute the final checksum */ - status = AE_BAD_CHECKSUM; - } - return_ACPI_STATUS (status); + checksum = (u8) (0 - checksum); + return (checksum); } +/******************************************************************************* + * + * FUNCTION: acpi_tb_set_checksum + * + * PARAMETERS: Table - Pointer to a valid ACPI table (with a + * standard ACPI header) + * + * RETURN: None. Sets the table checksum field + * + * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the + * checksum into the table header. + * + ******************************************************************************/ + +void acpi_tb_set_checksum(struct acpi_table_header *table) +{ + + table->checksum = acpi_tb_generate_checksum(table); +} /******************************************************************************* * - * FUNCTION: acpi_tb_checksum + * FUNCTION: acpi_tb_verify_table_checksum * - * PARAMETERS: Buffer - Buffer to checksum - * Length - Size of the buffer + * PARAMETERS: *table_header - ACPI table to verify * - * RETURNS 8 bit checksum of buffer + * RETURN: 8 bit checksum of table * - * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. + * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares + * it to the existing checksum value. * ******************************************************************************/ -u8 -acpi_tb_checksum ( - void *buffer, - u32 length) +acpi_status +acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) { - const u8 *limit; - const u8 *rover; - u8 sum = 0; + u8 checksum; + ACPI_FUNCTION_TRACE(tb_verify_table_checksum); - if (buffer && length) { - /* Buffer and Length are valid */ + /* Compute the checksum on the table */ - limit = (u8 *) buffer + length; + checksum = acpi_tb_generate_checksum(table_header); - for (rover = buffer; rover < limit; rover++) { - sum = (u8) (sum + *rover); - } + /* Checksum ok? */ + + if (checksum == table_header->checksum) { + return_ACPI_STATUS(AE_OK); } - return (sum); + + ACPI_WARNING((AE_INFO, + "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", + table_header->signature, table_header->checksum, + checksum)); + + return_ACPI_STATUS(AE_BAD_CHECKSUM); } +#ifdef ACPI_OBSOLETE_FUNCTIONS +/******************************************************************************* + * + * FUNCTION: acpi_tb_handle_to_object + * + * PARAMETERS: table_id - Id for which the function is searching + * table_desc - Pointer to return the matching table + * descriptor. + * + * RETURN: Search the tables to find one with a matching table_id and + * return a pointer to that table descriptor. + * + ******************************************************************************/ + +acpi_status +acpi_tb_handle_to_object(u16 table_id, + struct acpi_table_desc **return_table_desc) +{ + u32 i; + struct acpi_table_desc *table_desc; + + ACPI_FUNCTION_NAME(tb_handle_to_object); + + for (i = 0; i < ACPI_TABLE_MAX; i++) { + table_desc = acpi_gbl_table_lists[i].next; + while (table_desc) { + if (table_desc->table_id == table_id) { + *return_table_desc = table_desc; + return (AE_OK); + } + table_desc = table_desc->next; + } + } + + ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); + return (AE_BAD_PARAMETER); +} +#endif