diff options
Diffstat (limited to 'drivers/acpi/resources/rscalc.c')
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 108 |
1 files changed, 53 insertions, 55 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 4038dbfa63a0..cf87b0230026 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -78,6 +78,7 @@ static u8 acpi_rs_count_set_bits(u16 bit_field) | |||
78 | ACPI_FUNCTION_ENTRY(); | 78 | ACPI_FUNCTION_ENTRY(); |
79 | 79 | ||
80 | for (bits_set = 0; bit_field; bits_set++) { | 80 | for (bits_set = 0; bit_field; bits_set++) { |
81 | |||
81 | /* Zero the least significant bit that is set */ | 82 | /* Zero the least significant bit that is set */ |
82 | 83 | ||
83 | bit_field &= (bit_field - 1); | 84 | bit_field &= (bit_field - 1); |
@@ -154,15 +155,18 @@ acpi_rs_stream_option_length(u32 resource_length, | |||
154 | * length, minus one byte for the resource_source_index itself. | 155 | * length, minus one byte for the resource_source_index itself. |
155 | */ | 156 | */ |
156 | if (resource_length > minimum_aml_resource_length) { | 157 | if (resource_length > minimum_aml_resource_length) { |
158 | |||
157 | /* Compute the length of the optional string */ | 159 | /* Compute the length of the optional string */ |
158 | 160 | ||
159 | string_length = | 161 | string_length = |
160 | resource_length - minimum_aml_resource_length - 1; | 162 | resource_length - minimum_aml_resource_length - 1; |
161 | } | 163 | } |
162 | 164 | ||
163 | /* Round up length to 32 bits for internal structure alignment */ | 165 | /* |
164 | 166 | * Round the length up to a multiple of the native word in order to | |
165 | return (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)); | ||
166 | } | 170 | } |
167 | 171 | ||
168 | /******************************************************************************* | 172 | /******************************************************************************* |
@@ -186,11 +190,12 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) | |||
186 | acpi_size aml_size_needed = 0; | 190 | acpi_size aml_size_needed = 0; |
187 | acpi_rs_length total_size; | 191 | acpi_rs_length total_size; |
188 | 192 | ||
189 | ACPI_FUNCTION_TRACE("rs_get_aml_length"); | 193 | ACPI_FUNCTION_TRACE(rs_get_aml_length); |
190 | 194 | ||
191 | /* Traverse entire list of internal resource descriptors */ | 195 | /* Traverse entire list of internal resource descriptors */ |
192 | 196 | ||
193 | while (resource) { | 197 | while (resource) { |
198 | |||
194 | /* Validate the descriptor type */ | 199 | /* Validate the descriptor type */ |
195 | 200 | ||
196 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | 201 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { |
@@ -214,6 +219,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) | |||
214 | * is a Large Resource data type. | 219 | * is a Large Resource data type. |
215 | */ | 220 | */ |
216 | if (resource->data.vendor.byte_length > 7) { | 221 | if (resource->data.vendor.byte_length > 7) { |
222 | |||
217 | /* Base size of a Large resource descriptor */ | 223 | /* Base size of a Large resource descriptor */ |
218 | 224 | ||
219 | total_size = | 225 | total_size = |
@@ -332,20 +338,22 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
332 | acpi_status status; | 338 | acpi_status status; |
333 | u8 *end_aml; | 339 | u8 *end_aml; |
334 | u8 *buffer; | 340 | u8 *buffer; |
335 | u32 buffer_size = 0; | 341 | u32 buffer_size; |
336 | u16 temp16; | 342 | u16 temp16; |
337 | u16 resource_length; | 343 | u16 resource_length; |
338 | u32 extra_struct_bytes; | 344 | u32 extra_struct_bytes; |
339 | u8 resource_index; | 345 | u8 resource_index; |
340 | u8 minimum_aml_resource_length; | 346 | u8 minimum_aml_resource_length; |
341 | 347 | ||
342 | ACPI_FUNCTION_TRACE("rs_get_list_length"); | 348 | ACPI_FUNCTION_TRACE(rs_get_list_length); |
343 | 349 | ||
350 | *size_needed = 0; | ||
344 | end_aml = aml_buffer + aml_buffer_length; | 351 | end_aml = aml_buffer + aml_buffer_length; |
345 | 352 | ||
346 | /* Walk the list of AML resource descriptors */ | 353 | /* Walk the list of AML resource descriptors */ |
347 | 354 | ||
348 | while (aml_buffer < end_aml) { | 355 | while (aml_buffer < end_aml) { |
356 | |||
349 | /* Validate the Resource Type and Resource Length */ | 357 | /* Validate the Resource Type and Resource Length */ |
350 | 358 | ||
351 | status = acpi_ut_validate_resource(aml_buffer, &resource_index); | 359 | status = acpi_ut_validate_resource(aml_buffer, &resource_index); |
@@ -386,35 +394,28 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
386 | break; | 394 | break; |
387 | 395 | ||
388 | case ACPI_RESOURCE_NAME_VENDOR_SMALL: | 396 | case ACPI_RESOURCE_NAME_VENDOR_SMALL: |
397 | case ACPI_RESOURCE_NAME_VENDOR_LARGE: | ||
389 | /* | 398 | /* |
390 | * Vendor Resource: | 399 | * Vendor Resource: |
391 | * Ensure a 32-bit boundary for the structure | 400 | * Get the number of vendor data bytes |
392 | */ | 401 | */ |
393 | extra_struct_bytes = | 402 | extra_struct_bytes = resource_length; |
394 | ACPI_ROUND_UP_to_32_bITS(resource_length); | ||
395 | break; | 403 | break; |
396 | 404 | ||
397 | case ACPI_RESOURCE_NAME_END_TAG: | 405 | case ACPI_RESOURCE_NAME_END_TAG: |
398 | /* | 406 | /* |
399 | * 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 | ||
400 | */ | 409 | */ |
401 | *size_needed = buffer_size + ACPI_RS_SIZE_MIN; | 410 | *size_needed += ACPI_RS_SIZE_MIN; |
402 | return_ACPI_STATUS(AE_OK); | 411 | return_ACPI_STATUS(AE_OK); |
403 | 412 | ||
404 | case ACPI_RESOURCE_NAME_VENDOR_LARGE: | ||
405 | /* | ||
406 | * Vendor Resource: | ||
407 | * Add vendor data and ensure a 32-bit boundary for the structure | ||
408 | */ | ||
409 | extra_struct_bytes = | ||
410 | ACPI_ROUND_UP_to_32_bITS(resource_length); | ||
411 | break; | ||
412 | |||
413 | case ACPI_RESOURCE_NAME_ADDRESS32: | 413 | case ACPI_RESOURCE_NAME_ADDRESS32: |
414 | case ACPI_RESOURCE_NAME_ADDRESS16: | 414 | case ACPI_RESOURCE_NAME_ADDRESS16: |
415 | case ACPI_RESOURCE_NAME_ADDRESS64: | ||
415 | /* | 416 | /* |
416 | * 32-Bit or 16-bit Address Resource: | 417 | * Address Resource: |
417 | * Add the size of any optional data (resource_source) | 418 | * Add the size of the optional resource_source |
418 | */ | 419 | */ |
419 | extra_struct_bytes = | 420 | extra_struct_bytes = |
420 | acpi_rs_stream_option_length(resource_length, | 421 | acpi_rs_stream_option_length(resource_length, |
@@ -423,50 +424,46 @@ acpi_rs_get_list_length(u8 * aml_buffer, | |||
423 | 424 | ||
424 | case ACPI_RESOURCE_NAME_EXTENDED_IRQ: | 425 | case ACPI_RESOURCE_NAME_EXTENDED_IRQ: |
425 | /* | 426 | /* |
426 | * Extended IRQ: | 427 | * Extended IRQ Resource: |
427 | * Point past the interrupt_vector_flags to get the | 428 | * Using the interrupt_table_length, add 4 bytes for each additional |
428 | * 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) | ||
429 | */ | 431 | */ |
430 | buffer++; | 432 | extra_struct_bytes = (buffer[1] - 1) * sizeof(u32); |
431 | 433 | ||
432 | extra_struct_bytes = | 434 | /* Add the size of the optional resource_source */ |
433 | /* | 435 | |
434 | * Add 4 bytes for each additional interrupt. Note: at | 436 | extra_struct_bytes += |
435 | * least one interrupt is required and is included in | ||
436 | * the minimum descriptor size | ||
437 | */ | ||
438 | ((*buffer - 1) * sizeof(u32)) + | ||
439 | /* Add the size of any optional data (resource_source) */ | ||
440 | acpi_rs_stream_option_length(resource_length - | 437 | acpi_rs_stream_option_length(resource_length - |
441 | extra_struct_bytes, | 438 | extra_struct_bytes, |
442 | minimum_aml_resource_length); | 439 | minimum_aml_resource_length); |
443 | break; | 440 | break; |
444 | 441 | ||
445 | case ACPI_RESOURCE_NAME_ADDRESS64: | ||
446 | /* | ||
447 | * 64-Bit Address Resource: | ||
448 | * Add the size of any optional data (resource_source) | ||
449 | * Ensure a 64-bit boundary for the structure | ||
450 | */ | ||
451 | extra_struct_bytes = | ||
452 | ACPI_ROUND_UP_to_64_bITS | ||
453 | (acpi_rs_stream_option_length | ||
454 | (resource_length, minimum_aml_resource_length)); | ||
455 | break; | ||
456 | |||
457 | default: | 442 | default: |
458 | break; | 443 | break; |
459 | } | 444 | } |
460 | 445 | ||
461 | /* 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 = (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(buffer_size); | ||
462 | 455 | ||
463 | temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + | 456 | *size_needed += buffer_size; |
464 | extra_struct_bytes); | 457 | |
465 | buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16); | 458 | ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, |
459 | "Type %.2X, AmlLength %.2X InternalLength %.2X\n", | ||
460 | acpi_ut_get_resource_type(aml_buffer), | ||
461 | acpi_ut_get_descriptor_length(aml_buffer), | ||
462 | buffer_size)); | ||
466 | 463 | ||
467 | /* | 464 | /* |
468 | * Point to the next resource within the stream | 465 | * Point to the next resource within the AML stream using the length |
469 | * using the size of the header plus the length contained in the header | 466 | * contained in the resource descriptor header |
470 | */ | 467 | */ |
471 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); | 468 | aml_buffer += acpi_ut_get_descriptor_length(aml_buffer); |
472 | } | 469 | } |
@@ -506,7 +503,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
506 | u8 name_found; | 503 | u8 name_found; |
507 | u32 table_index; | 504 | u32 table_index; |
508 | 505 | ||
509 | ACPI_FUNCTION_TRACE("rs_get_pci_routing_table_length"); | 506 | ACPI_FUNCTION_TRACE(rs_get_pci_routing_table_length); |
510 | 507 | ||
511 | number_of_elements = package_object->package.count; | 508 | number_of_elements = package_object->package.count; |
512 | 509 | ||
@@ -523,6 +520,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
523 | top_object_list = package_object->package.elements; | 520 | top_object_list = package_object->package.elements; |
524 | 521 | ||
525 | for (index = 0; index < number_of_elements; index++) { | 522 | for (index = 0; index < number_of_elements; index++) { |
523 | |||
526 | /* Dereference the sub-package */ | 524 | /* Dereference the sub-package */ |
527 | 525 | ||
528 | package_element = *top_object_list; | 526 | package_element = *top_object_list; |
@@ -581,7 +579,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
581 | 579 | ||
582 | /* Round up the size since each element must be aligned */ | 580 | /* Round up the size since each element must be aligned */ |
583 | 581 | ||
584 | temp_size_needed = ACPI_ROUND_UP_to_64_bITS(temp_size_needed); | 582 | temp_size_needed = ACPI_ROUND_UP_TO_64BIT(temp_size_needed); |
585 | 583 | ||
586 | /* Point to the next union acpi_operand_object */ | 584 | /* Point to the next union acpi_operand_object */ |
587 | 585 | ||
@@ -589,7 +587,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
589 | } | 587 | } |
590 | 588 | ||
591 | /* | 589 | /* |
592 | * 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 |
593 | * NULL terminator | 591 | * NULL terminator |
594 | */ | 592 | */ |
595 | *buffer_size_needed = | 593 | *buffer_size_needed = |