diff options
Diffstat (limited to 'drivers/acpi/tables/tbutils.c')
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index b463d4b88823..f8d28ae8811d 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -193,73 +193,119 @@ acpi_tb_validate_table_header(struct acpi_table_header *table_header) | |||
193 | 193 | ||
194 | /******************************************************************************* | 194 | /******************************************************************************* |
195 | * | 195 | * |
196 | * FUNCTION: acpi_tb_verify_table_checksum | 196 | * FUNCTION: acpi_tb_sum_table |
197 | * | 197 | * |
198 | * PARAMETERS: *table_header - ACPI table to verify | 198 | * PARAMETERS: Buffer - Buffer to sum |
199 | * Length - Size of the buffer | ||
199 | * | 200 | * |
200 | * RETURN: 8 bit checksum of table | 201 | * RETURN: 8 bit sum of buffer |
201 | * | 202 | * |
202 | * DESCRIPTION: Does an 8 bit checksum of table and returns status. A correct | 203 | * DESCRIPTION: Computes an 8 bit sum of the buffer(length) and returns it. |
203 | * table should have a checksum of 0. | ||
204 | * | 204 | * |
205 | ******************************************************************************/ | 205 | ******************************************************************************/ |
206 | 206 | ||
207 | acpi_status | 207 | u8 acpi_tb_sum_table(void *buffer, u32 length) |
208 | acpi_tb_verify_table_checksum(struct acpi_table_header * table_header) | 208 | { |
209 | acpi_native_uint i; | ||
210 | u8 sum = 0; | ||
211 | |||
212 | if (!buffer || !length) { | ||
213 | return (0); | ||
214 | } | ||
215 | |||
216 | for (i = 0; i < length; i++) { | ||
217 | sum = (u8) (sum + ((u8 *) buffer)[i]); | ||
218 | } | ||
219 | return (sum); | ||
220 | } | ||
221 | |||
222 | /******************************************************************************* | ||
223 | * | ||
224 | * FUNCTION: acpi_tb_generate_checksum | ||
225 | * | ||
226 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a | ||
227 | * standard ACPI header) | ||
228 | * | ||
229 | * RETURN: 8 bit checksum of buffer | ||
230 | * | ||
231 | * DESCRIPTION: Computes an 8 bit checksum of the table. | ||
232 | * | ||
233 | ******************************************************************************/ | ||
234 | |||
235 | u8 acpi_tb_generate_checksum(struct acpi_table_header * table) | ||
209 | { | 236 | { |
210 | u8 checksum; | 237 | u8 checksum; |
211 | acpi_status status = AE_OK; | ||
212 | 238 | ||
213 | ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); | 239 | /* Sum the entire table as-is */ |
214 | 240 | ||
215 | /* Compute the checksum on the table */ | 241 | checksum = acpi_tb_sum_table(table, table->length); |
216 | 242 | ||
217 | checksum = | 243 | /* Subtract off the existing checksum value in the table */ |
218 | acpi_tb_generate_checksum(table_header, table_header->length); | ||
219 | 244 | ||
220 | /* Return the appropriate exception */ | 245 | checksum = (u8) (checksum - table->checksum); |
221 | 246 | ||
222 | if (checksum) { | 247 | /* Compute the final checksum */ |
223 | ACPI_WARNING((AE_INFO, | ||
224 | "Invalid checksum in table [%4.4s] (%02X, sum %02X is not zero)", | ||
225 | table_header->signature, | ||
226 | (u32) table_header->checksum, (u32) checksum)); | ||
227 | 248 | ||
228 | status = AE_BAD_CHECKSUM; | 249 | checksum = (u8) (0 - checksum); |
229 | } | 250 | return (checksum); |
230 | return_ACPI_STATUS(status); | ||
231 | } | 251 | } |
232 | 252 | ||
233 | /******************************************************************************* | 253 | /******************************************************************************* |
234 | * | 254 | * |
235 | * FUNCTION: acpi_tb_generate_checksum | 255 | * FUNCTION: acpi_tb_set_checksum |
236 | * | 256 | * |
237 | * PARAMETERS: Buffer - Buffer to checksum | 257 | * PARAMETERS: Table - Pointer to a valid ACPI table (with a |
238 | * Length - Size of the buffer | 258 | * standard ACPI header) |
239 | * | 259 | * |
240 | * RETURN: 8 bit checksum of buffer | 260 | * RETURN: None. Sets the table checksum field |
241 | * | 261 | * |
242 | * DESCRIPTION: Computes an 8 bit checksum of the buffer(length) and returns it. | 262 | * DESCRIPTION: Computes an 8 bit checksum of the table and inserts the |
263 | * checksum into the table header. | ||
243 | * | 264 | * |
244 | ******************************************************************************/ | 265 | ******************************************************************************/ |
245 | 266 | ||
246 | u8 acpi_tb_generate_checksum(void *buffer, u32 length) | 267 | void acpi_tb_set_checksum(struct acpi_table_header *table) |
247 | { | 268 | { |
248 | u8 *end_buffer; | ||
249 | u8 *rover; | ||
250 | u8 sum = 0; | ||
251 | 269 | ||
252 | if (buffer && length) { | 270 | table->checksum = acpi_tb_generate_checksum(table); |
271 | } | ||
272 | |||
273 | /******************************************************************************* | ||
274 | * | ||
275 | * FUNCTION: acpi_tb_verify_table_checksum | ||
276 | * | ||
277 | * PARAMETERS: *table_header - ACPI table to verify | ||
278 | * | ||
279 | * RETURN: 8 bit checksum of table | ||
280 | * | ||
281 | * DESCRIPTION: Generates an 8 bit checksum of table and returns and compares | ||
282 | * it to the existing checksum value. | ||
283 | * | ||
284 | ******************************************************************************/ | ||
285 | |||
286 | acpi_status | ||
287 | acpi_tb_verify_table_checksum(struct acpi_table_header *table_header) | ||
288 | { | ||
289 | u8 checksum; | ||
290 | |||
291 | ACPI_FUNCTION_TRACE("tb_verify_table_checksum"); | ||
292 | |||
293 | /* Compute the checksum on the table */ | ||
253 | 294 | ||
254 | /* Buffer and Length are valid */ | 295 | checksum = acpi_tb_generate_checksum(table_header); |
255 | 296 | ||
256 | end_buffer = ACPI_ADD_PTR(u8, buffer, length); | 297 | /* Checksum ok? */ |
257 | 298 | ||
258 | for (rover = buffer; rover < end_buffer; rover++) { | 299 | if (checksum == table_header->checksum) { |
259 | sum = (u8) (sum + *rover); | 300 | return_ACPI_STATUS(AE_OK); |
260 | } | ||
261 | } | 301 | } |
262 | return (sum); | 302 | |
303 | ACPI_WARNING((AE_INFO, | ||
304 | "Incorrect checksum in table [%4.4s] - is %2.2X, should be %2.2X", | ||
305 | table_header->signature, table_header->checksum, | ||
306 | checksum)); | ||
307 | |||
308 | return_ACPI_STATUS(AE_BAD_CHECKSUM); | ||
263 | } | 309 | } |
264 | 310 | ||
265 | #ifdef ACPI_OBSOLETE_FUNCTIONS | 311 | #ifdef ACPI_OBSOLETE_FUNCTIONS |
@@ -278,7 +324,7 @@ u8 acpi_tb_generate_checksum(void *buffer, u32 length) | |||
278 | 324 | ||
279 | acpi_status | 325 | acpi_status |
280 | acpi_tb_handle_to_object(u16 table_id, | 326 | acpi_tb_handle_to_object(u16 table_id, |
281 | struct acpi_table_desc ** return_table_desc) | 327 | struct acpi_table_desc **return_table_desc) |
282 | { | 328 | { |
283 | u32 i; | 329 | u32 i; |
284 | struct acpi_table_desc *table_desc; | 330 | struct acpi_table_desc *table_desc; |