diff options
author | Bob Moore <robert.moore@intel.com> | 2006-02-17 00:00:00 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-04-01 01:23:23 -0500 |
commit | ea936b78f46cbe089a4ac363e1682dee7d427096 (patch) | |
tree | c444b65c3d02b05934497caefcdcbbe675a00bdf /drivers/acpi/resources/rscalc.c | |
parent | 52fc0b026e99b5d5d585095148d997d5634bbc25 (diff) |
ACPI: ACPICA 20060217
Implemented a change to the IndexField support to match
the behavior of the Microsoft AML interpreter. The value
written to the Index register is now a byte offset,
no longer an index based upon the width of the Data
register. This should fix IndexField problems seen on
some machines where the Data register is not exactly one
byte wide. The ACPI specification will be clarified on
this point.
Fixed a problem where several resource descriptor
types could overrun the internal descriptor buffer due
to size miscalculation: VendorShort, VendorLong, and
Interrupt. This was noticed on IA64 machines, but could
affect all platforms.
Fixed a problem where individual resource descriptors were
misaligned within the internal buffer, causing alignment
faults on IA64 platforms.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources/rscalc.c')
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 100 |
1 files changed, 45 insertions, 55 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 223bdc493269..8e406d992f3b 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -162,9 +162,11 @@ acpi_rs_stream_option_length(u32 resource_length, | |||
162 | resource_length - minimum_aml_resource_length - 1; | 162 | resource_length - minimum_aml_resource_length - 1; |
163 | } | 163 | } |
164 | 164 | ||
165 | /* Round up length to 32 bits for internal structure alignment */ | 165 | /* |
166 | 166 | * Round the length up to a multiple of the native word in order to | |
167 | return ((u32) ACPI_ROUND_UP_to_32_bITS(string_length)); | 167 | * guarantee that the entire resource descriptor is native word aligned |
168 | */ | ||
169 | return ((u32) ACPI_ROUND_UP_TO_NATIVE_WORD(string_length)); | ||
168 | } | 170 | } |
169 | 171 | ||
170 | /******************************************************************************* | 172 | /******************************************************************************* |
@@ -336,7 +338,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
336 | acpi_status status; | 338 | acpi_status status; |
337 | u8 *end_aml; | 339 | u8 *end_aml; |
338 | u8 *buffer; | 340 | u8 *buffer; |
339 | u32 buffer_size = 0; | 341 | u32 buffer_size; |
340 | u16 temp16; | 342 | u16 temp16; |
341 | u16 resource_length; | 343 | u16 resource_length; |
342 | u32 extra_struct_bytes; | 344 | u32 extra_struct_bytes; |
@@ -345,6 +347,7 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
345 | 347 | ||
346 | ACPI_FUNCTION_TRACE("rs_get_list_length"); | 348 | ACPI_FUNCTION_TRACE("rs_get_list_length"); |
347 | 349 | ||
350 | *size_needed = 0; | ||
348 | end_aml = aml_buffer + aml_buffer_length; | 351 | end_aml = aml_buffer + aml_buffer_length; |
349 | 352 | ||
350 | /* Walk the list of AML resource descriptors */ | 353 | /* Walk the list of AML resource descriptors */ |
@@ -391,37 +394,28 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
391 | break; | 394 | break; |
392 | 395 | ||
393 | case ACPI_RESOURCE_NAME_VENDOR_SMALL: | 396 | case ACPI_RESOURCE_NAME_VENDOR_SMALL: |
397 | case ACPI_RESOURCE_NAME_VENDOR_LARGE: | ||
394 | /* | 398 | /* |
395 | * Vendor Resource: | 399 | * Vendor Resource: |
396 | * Ensure a 32-bit boundary for the structure | 400 | * Get the number of vendor data bytes |
397 | */ | 401 | */ |
398 | extra_struct_bytes = (u32) | 402 | extra_struct_bytes = resource_length; |
399 | ACPI_ROUND_UP_to_32_bITS(resource_length) - | ||
400 | resource_length; | ||
401 | break; | 403 | break; |
402 | 404 | ||
403 | case ACPI_RESOURCE_NAME_END_TAG: | 405 | case ACPI_RESOURCE_NAME_END_TAG: |
404 | /* | 406 | /* |
405 | * End Tag: This is the normal exit, add size of end_tag | 407 | * End Tag: |
408 | * This is the normal exit, add size of end_tag | ||
406 | */ | 409 | */ |
407 | *size_needed = buffer_size + ACPI_RS_SIZE_MIN; | 410 | *size_needed += ACPI_RS_SIZE_MIN; |
408 | return_ACPI_STATUS(AE_OK); | 411 | return_ACPI_STATUS(AE_OK); |
409 | 412 | ||
410 | case ACPI_RESOURCE_NAME_VENDOR_LARGE: | ||
411 | /* | ||
412 | * Vendor Resource: | ||
413 | * Add vendor data and ensure a 32-bit boundary for the structure | ||
414 | */ | ||
415 | extra_struct_bytes = (u32) | ||
416 | ACPI_ROUND_UP_to_32_bITS(resource_length) - | ||
417 | resource_length; | ||
418 | break; | ||
419 | |||
420 | case ACPI_RESOURCE_NAME_ADDRESS32: | 413 | case ACPI_RESOURCE_NAME_ADDRESS32: |
421 | case ACPI_RESOURCE_NAME_ADDRESS16: | 414 | case ACPI_RESOURCE_NAME_ADDRESS16: |
415 | case ACPI_RESOURCE_NAME_ADDRESS64: | ||
422 | /* | 416 | /* |
423 | * 32-Bit or 16-bit Address Resource: | 417 | * Address Resource: |
424 | * Add the size of any optional data (resource_source) | 418 | * Add the size of the optional resource_source |
425 | */ | 419 | */ |
426 | extra_struct_bytes = | 420 | extra_struct_bytes = |
427 | acpi_rs_stream_option_length(resource_length, | 421 | acpi_rs_stream_option_length(resource_length, |
@@ -430,50 +424,46 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
430 | 424 | ||
431 | case ACPI_RESOURCE_NAME_EXTENDED_IRQ: | 425 | case ACPI_RESOURCE_NAME_EXTENDED_IRQ: |
432 | /* | 426 | /* |
433 | * Extended IRQ: | 427 | * Extended IRQ Resource: |
434 | * Point past the interrupt_vector_flags to get the | 428 | * Using the interrupt_table_length, add 4 bytes for each additional |
435 | * interrupt_table_length. | 429 | * interrupt. Note: at least one interrupt is required and is |
430 | * included in the minimum descriptor size (reason for the -1) | ||
436 | */ | 431 | */ |
437 | buffer++; | 432 | extra_struct_bytes = (buffer[1] - 1) * sizeof(u32); |
438 | 433 | ||
439 | extra_struct_bytes = (u32) | 434 | /* Add the size of the optional resource_source */ |
440 | /* | 435 | |
441 | * Add 4 bytes for each additional interrupt. Note: at | 436 | extra_struct_bytes += |
442 | * least one interrupt is required and is included in | ||
443 | * the minimum descriptor size | ||
444 | */ | ||
445 | ((*buffer - 1) * sizeof(u32)) + | ||
446 | /* Add the size of any optional data (resource_source) */ | ||
447 | acpi_rs_stream_option_length(resource_length - | 437 | acpi_rs_stream_option_length(resource_length - |
448 | extra_struct_bytes, | 438 | extra_struct_bytes, |
449 | minimum_aml_resource_length); | 439 | minimum_aml_resource_length); |
450 | break; | 440 | break; |
451 | 441 | ||
452 | case ACPI_RESOURCE_NAME_ADDRESS64: | ||
453 | /* | ||
454 | * 64-Bit Address Resource: | ||
455 | * Add the size of any optional data (resource_source) | ||
456 | * Ensure a 64-bit boundary for the structure | ||
457 | */ | ||
458 | extra_struct_bytes = (u32) | ||
459 | ACPI_ROUND_UP_to_64_bITS | ||
460 | (acpi_rs_stream_option_length | ||
461 | (resource_length, minimum_aml_resource_length)); | ||
462 | break; | ||
463 | |||
464 | default: | 442 | default: |
465 | break; | 443 | break; |
466 | } | 444 | } |
467 | 445 | ||
468 | /* Update the required buffer size for the internal descriptor structs */ | 446 | /* |
447 | * Update the required buffer size for the internal descriptor structs | ||
448 | * | ||
449 | * Important: Round the size up for the appropriate alignment. This | ||
450 | * is a requirement on IA64. | ||
451 | */ | ||
452 | buffer_size = acpi_gbl_resource_struct_sizes[resource_index] + | ||
453 | extra_struct_bytes; | ||
454 | buffer_size = ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size); | ||
455 | |||
456 | *size_needed += buffer_size; | ||
469 | 457 | ||
470 | temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + | 458 | ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, |
471 | extra_struct_bytes); | 459 | "Type %.2X, Aml %.2X internal %.2X\n", |
472 | buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); | 460 | acpi_ut_get_resource_type(aml_buffer), |
461 | acpi_ut_get_descriptor_length(aml_buffer), | ||
462 | buffer_size)); | ||
473 | 463 | ||
474 | /* | 464 | /* |
475 | * Point to the next resource within the stream | 465 | * Point to the next resource within the AML stream using the length |
476 | * using the size of the header plus the length contained in the header | 466 | * contained in the resource descriptor header |
477 | */ | 467 | */ |
478 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); | 468 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); |
479 | } | 469 | } |
@@ -589,7 +579,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
589 | 579 | ||
590 | /* Round up the size since each element must be aligned */ | 580 | /* Round up the size since each element must be aligned */ |
591 | 581 | ||
592 | temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed); | 582 | temp_size_needed = ACPI_ROUND_UP_to_64_bIT(temp_size_needed); |
593 | 583 | ||
594 | /* Point to the next union acpi_operand_object */ | 584 | /* Point to the next union acpi_operand_object */ |
595 | 585 | ||
@@ -597,7 +587,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
597 | } | 587 | } |
598 | 588 | ||
599 | /* | 589 | /* |
600 | * Adding an extra element to the end of the list, essentially a | 590 | * Add an extra element to the end of the list, essentially a |
601 | * NULL terminator | 591 | * NULL terminator |
602 | */ | 592 | */ |
603 | *buffer_size_needed = | 593 | *buffer_size_needed = |