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 |