diff options
Diffstat (limited to 'drivers/acpi/tables/tbutils.c')
| -rw-r--r-- | drivers/acpi/tables/tbutils.c | 149 |
1 files changed, 95 insertions, 54 deletions
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index bc571592f087..209a401801e3 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
| @@ -71,7 +71,7 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) | |||
| 71 | { | 71 | { |
| 72 | struct acpi_table_desc *table_desc; | 72 | struct acpi_table_desc *table_desc; |
| 73 | 73 | ||
| 74 | ACPI_FUNCTION_TRACE("tb_is_table_installed"); | 74 | ACPI_FUNCTION_TRACE(tb_is_table_installed); |
| 75 | 75 | ||
| 76 | /* Get the list descriptor and first table descriptor */ | 76 | /* Get the list descriptor and first table descriptor */ |
| 77 | 77 | ||
| @@ -96,10 +96,11 @@ acpi_status acpi_tb_is_table_installed(struct acpi_table_desc *new_table_desc) | |||
| 96 | (!ACPI_MEMCMP | 96 | (!ACPI_MEMCMP |
| 97 | (table_desc->pointer, new_table_desc->pointer, | 97 | (table_desc->pointer, new_table_desc->pointer, |
| 98 | new_table_desc->pointer->length))) { | 98 | new_table_desc->pointer->length))) { |
| 99 | |||
| 99 | /* Match: this table is already installed */ | 100 | /* Match: this table is already installed */ |
| 100 | 101 | ||
| 101 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, | 102 | ACPI_DEBUG_PRINT((ACPI_DB_TABLES, |
| 102 | "Table [%4.4s] already installed: Rev %X oem_table_id [%8.8s]\n", | 103 | "Table [%4.4s] already installed: Rev %X OemTableId [%8.8s]\n", |
| 103 | new_table_desc->pointer->signature, | 104 | new_table_desc->pointer->signature, |
| 104 | new_table_desc->pointer->revision, | 105 | new_table_desc->pointer->revision, |
| 105 | new_table_desc->pointer-> | 106 | new_table_desc->pointer-> |
| @@ -159,12 +160,8 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) | |||
| 159 | 160 | ||
| 160 | ACPI_MOVE_32_TO_32(&signature, table_header->signature); | 161 | ACPI_MOVE_32_TO_32(&signature, table_header->signature); |
| 161 | if (!acpi_ut_valid_acpi_name(signature)) { | 162 | if (!acpi_ut_valid_acpi_name(signature)) { |
| 162 | ACPI_ERROR((AE_INFO, | 163 | ACPI_ERROR((AE_INFO, "Invalid table signature 0x%8.8X", |
| 163 | "Table signature at %p [%p] has invalid characters", | 164 | signature)); |
| 164 | table_header, &signature)); | ||
| 165 | |||
| 166 | ACPI_WARNING((AE_INFO, "Invalid table signature found: [%4.4s]", | ||
| 167 | ACPI_CAST_PTR(char, &signature))); | ||
| 168 | 165 | ||
| 169 | ACPI_DUMP_BUFFER(table_header, | 166 | ACPI_DUMP_BUFFER(table_header, |
| 170 | sizeof(struct acpi_table_header)); | 167 | sizeof(struct acpi_table_header)); |
| @@ -175,12 +172,9 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) | |||
| 175 | 172 | ||
| 176 | if (table_header->length < sizeof(struct acpi_table_header)) { | 173 | if (table_header->length < sizeof(struct acpi_table_header)) { |
| 177 | ACPI_ERROR((AE_INFO, | 174 | ACPI_ERROR((AE_INFO, |
| 178 | "Invalid length in table header %p name %4.4s", | 175 | "Invalid length 0x%X in table with signature %4.4s", |
| 179 | table_header, (char *)&signature)); | 176 | (u32) table_header->length, |
| 180 | 177 | ACPI_CAST_PTR(char, &signature))); | |
| 181 | ACPI_WARNING((AE_INFO, | ||
| 182 | "Invalid table header length (0x%X) found", | ||
| 183 | (u32) table_header->length)); | ||
| 184 | 178 | ||
| 185 | ACPI_DUMP_BUFFER(table_header, | 179 | ACPI_DUMP_BUFFER(table_header, |
| 186 | sizeof(struct acpi_table_header)); | 180 | sizeof(struct acpi_table_header)); |
| @@ -192,72 +186,119 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) | |||
| 192 | 186 | ||
| 193 | /******************************************************************************* | 187 | /******************************************************************************* |
| 194 | * | 188 | * |
| 195 | * FUNCTION: acpi_tb_verify_table_checksum | 189 | * FUNCTION: acpi_tb_sum_table |
| 196 | * | 190 | * |
| 197 | * PARAMETERS: *table_header - ACPI table to verify | 191 | * PARAMETERS: Buffer - Buffer to sum |
| 192 | * Length - Size of the buffer | ||
| 198 | * | 193 | * |
| 199 | * RETURN: 8 bit checksum of table | 194 | * RETURN: 8 bit sum of buffer |
| 200 | * | 195 | * |
| 201 | * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct | 196 | * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. |
| 202 | * table should have a checksum of 0. | ||
| 203 | * | 197 | * |
| 204 | ******************************************************************************/ | 198 | ******************************************************************************/ |
| 205 | 199 | ||
| 206 | acpi_status | 200 | u8 acpi_tb_sum_table(void *buffer, u32 length) |
| 207 | acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) | 201 | { |
| 202 | acpi_native_uint i; | ||
| 203 | u8 sum = 0; | ||
| 204 | |||
| 205 | if (!buffer || !length) { | ||
| 206 | return (0); | ||
| 207 | } | ||
| 208 | |||
| 209 | for (i = 0; i < length; i++) { | ||
| 210 | sum = (u8) (sum + ((u8 *) buffer)[i]); | ||
| 211 | } | ||
| 212 | return (sum); | ||
| 213 | } | ||
| 214 | |||
| 215 | /******************************************************************************* | ||
| 216 | * | ||
| 217 | * FUNCTION: acpi_tb_generate_checksum | ||
| 218 | * | ||
| 219 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | ||
| 220 | * standard ACPI header) | ||
| 221 | * | ||
| 222 | * RETURN: 8 bit checksum of buffer | ||
| 223 | * | ||
| 224 | * DESCRIPTION: Computes an 8 bit checksum of the table. | ||
| 225 | * | ||
| 226 | ******************************************************************************/ | ||
| 227 | |||
| 228 | u8 acpi_tb_generate_checksum(struct acpi_table_header * table) | ||
| 208 | { | 229 | { |
| 209 | u8 checksum; | 230 | u8 checksum; |
| 210 | acpi_status status = AE_OK; | ||
| 211 | 231 | ||
| 212 | ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); | 232 | /* Sum the entire table as-is */ |
| 213 | 233 | ||
| 214 | /* Compute the checksum on the table */ | 234 | checksum = acpi_tb_sum_table(table, table->length); |
| 215 | 235 | ||
| 216 | checksum = | 236 | /* Subtract off the existing checksum value in the table */ |
| 217 | acpi_tb_generate_checksum(table_header, table_header->length); | ||
| 218 | 237 | ||
| 219 | /* Return the appropriate exception */ | 238 | checksum = (u8) (checksum - table->checksum); |
| 220 | 239 | ||
| 221 | if (checksum) { | 240 | /* Compute the final checksum */ |
| 222 | ACPI_WARNING((AE_INFO, | ||
| 223 | "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)", | ||
| 224 | table_header->signature, | ||
| 225 | (u32) table_header->checksum, (u32) checksum)); | ||
| 226 | 241 | ||
| 227 | status = AE_BAD_CHECKSUM; | 242 | checksum = (u8) (0 - checksum); |
| 228 | } | 243 | return (checksum); |
| 229 | return_ACPI_STATUS(status); | ||
| 230 | } | 244 | } |
| 231 | 245 | ||
| 232 | /******************************************************************************* | 246 | /******************************************************************************* |
| 233 | * | 247 | * |
| 234 | * FUNCTION: acpi_tb_generate_checksum | 248 | * FUNCTION: acpi_tb_set_checksum |
| 235 | * | 249 | * |
| 236 | * PARAMETERS: Buffer - Buffer to checksum | 250 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a |
| 237 | * Length - Size of the buffer | 251 | * standard ACPI header) |
| 238 | * | 252 | * |
| 239 | * RETURN: 8 bit checksum of buffer | 253 | * RETURN: None. Sets the table checksum field |
| 240 | * | 254 | * |
| 241 | * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. | 255 | * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the |
| 256 | * checksum into the table header. | ||
| 242 | * | 257 | * |
| 243 | ******************************************************************************/ | 258 | ******************************************************************************/ |
| 244 | 259 | ||
| 245 | u8 acpi_tb_generate_checksum(void *buffer, u32 length) | 260 | void acpi_tb_set_checksum(struct acpi_table_header *table) |
| 246 | { | 261 | { |
| 247 | u8 *end_buffer; | ||
| 248 | u8 *rover; | ||
| 249 | u8 sum = 0; | ||
| 250 | 262 | ||
| 251 | if (buffer && length) { | 263 | table->checksum = acpi_tb_generate_checksum(table); |
| 252 | /* Buffer and Length are valid */ | 264 | } |
| 253 | 265 | ||
| 254 | end_buffer = ACPI_ADD_PTR(u8, buffer, length); | 266 | /******************************************************************************* |
| 267 | * | ||
| 268 | * FUNCTION: acpi_tb_verify_table_checksum | ||
| 269 | * | ||
| 270 | * PARAMETERS: *table_header - ACPI table to verify | ||
| 271 | * | ||
| 272 | * RETURN: 8 bit checksum of table | ||
| 273 | * | ||
| 274 | * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares | ||
| 275 | * it to the existing checksum value. | ||
| 276 | * | ||
| 277 | ******************************************************************************/ | ||
| 255 | 278 | ||
| 256 | for (rover = buffer; rover < end_buffer; rover++) { | 279 | acpi_status |
| 257 | sum = (u8) (sum + *rover); | 280 | acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) |
| 258 | } | 281 | { |
| 282 | u8 checksum; | ||
| 283 | |||
| 284 | ACPI_FUNCTION_TRACE(tb_verify_table_checksum); | ||
| 285 | |||
| 286 | /* Compute the checksum on the table */ | ||
| 287 | |||
| 288 | checksum = acpi_tb_generate_checksum(table_header); | ||
| 289 | |||
| 290 | /* Checksum ok? */ | ||
| 291 | |||
| 292 | if (checksum == table_header->checksum) { | ||
| 293 | return_ACPI_STATUS(AE_OK); | ||
| 259 | } | 294 | } |
| 260 | return (sum); | 295 | |
| 296 | ACPI_WARNING((AE_INFO, | ||
| 297 | "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", | ||
| 298 | table_header->signature, table_header->checksum, | ||
| 299 | checksum)); | ||
| 300 | |||
| 301 | return_ACPI_STATUS(AE_BAD_CHECKSUM); | ||
| 261 | } | 302 | } |
| 262 | 303 | ||
| 263 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 304 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
| @@ -276,12 +317,12 @@ u8 acpi_tb_generate_checksum(void *buffer, u32 length) | |||
| 276 | 317 | ||
| 277 | acpi_status | 318 | acpi_status |
| 278 | acpi_tb_handle_to_object(u16 table_id, | 319 | acpi_tb_handle_to_object(u16 table_id, |
| 279 | struct acpi_table_desc ** return_table_desc) | 320 | struct acpi_table_desc **return_table_desc) |
| 280 | { | 321 | { |
| 281 | u32 i; | 322 | u32 i; |
| 282 | struct acpi_table_desc *table_desc; | 323 | struct acpi_table_desc *table_desc; |
| 283 | 324 | ||
| 284 | ACPI_FUNCTION_NAME("tb_handle_to_object"); | 325 | ACPI_FUNCTION_NAME(tb_handle_to_object); |
| 285 | 326 | ||
| 286 | for (i = 0; i < ACPI_TABLE_MAX; i++) { | 327 | for (i = 0; i < ACPI_TABLE_MAX; i++) { |
| 287 | table_desc = acpi_gbl_table_lists[i].next; | 328 | table_desc = acpi_gbl_table_lists[i].next; |
| @@ -295,7 +336,7 @@ acpi_tb_handle_to_object(u16 table_id, | |||
| 295 | } | 336 | } |
| 296 | } | 337 | } |
| 297 | 338 | ||
| 298 | ACPI_ERROR((AE_INFO, "table_id=%X does not exist", table_id)); | 339 | ACPI_ERROR((AE_INFO, "TableId=%X does not exist", table_id)); |
| 299 | return (AE_BAD_PARAMETER); | 340 | return (AE_BAD_PARAMETER); |
| 300 | } | 341 | } |
| 301 | #endif | 342 | #endif |
