aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources/rscalc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/resources/rscalc.c')
-rw-r--r--drivers/acpi/resources/rscalc.c253
1 files changed, 112 insertions, 141 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index c29d3a447278..eca7439ee9da 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -299,13 +299,14 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
299 299
300 /* Point to the next object */ 300 /* Point to the next object */
301 301
302 resource = ACPI_PTR_ADD(struct acpi_resource, 302 resource =
303 resource, resource->length); 303 ACPI_PTR_ADD(struct acpi_resource, resource,
304 resource->length);
304 } 305 }
305 306
306 /* Did not find an END_TAG descriptor */ 307 /* Did not find an end_tag resource descriptor */
307 308
308 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); 309 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
309} 310}
310 311
311/******************************************************************************* 312/*******************************************************************************
@@ -328,185 +329,155 @@ acpi_status
328acpi_rs_get_list_length(u8 * aml_buffer, 329acpi_rs_get_list_length(u8 * aml_buffer,
329 u32 aml_buffer_length, acpi_size * size_needed) 330 u32 aml_buffer_length, acpi_size * size_needed)
330{ 331{
332 acpi_status status;
333 u8 *end_aml;
331 u8 *buffer; 334 u8 *buffer;
332 struct acpi_resource_info *resource_info;
333 u32 buffer_size = 0; 335 u32 buffer_size = 0;
334 u32 bytes_parsed = 0;
335 u8 resource_type;
336 u16 temp16; 336 u16 temp16;
337 u16 resource_length; 337 u16 resource_length;
338 u16 header_length;
339 u32 extra_struct_bytes; 338 u32 extra_struct_bytes;
339 u8 resource_index;
340 u8 minimum_aml_resource_length;
340 341
341 ACPI_FUNCTION_TRACE("rs_get_list_length"); 342 ACPI_FUNCTION_TRACE("rs_get_list_length");
342 343
343 while (bytes_parsed < aml_buffer_length) { 344 end_aml = aml_buffer + aml_buffer_length;
344 /* The next byte in the stream is the resource descriptor type */
345 345
346 resource_type = acpi_ut_get_resource_type(aml_buffer); 346 /* Walk the list of AML resource descriptors */
347 347
348 /* Get the base stream size and structure sizes for the descriptor */ 348 while (aml_buffer < end_aml) {
349 /* Validate the Resource Type and Resource Length */
349 350
350 resource_info = acpi_rs_get_resource_info(resource_type); 351 status = acpi_ut_validate_resource(aml_buffer, &resource_index);
351 if (!resource_info) { 352 if (ACPI_FAILURE(status)) {
352 return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); 353 return_ACPI_STATUS(status);
353 } 354 }
354 355
355 /* Get the Length field from the input resource descriptor */ 356 /* Get the resource length and base (minimum) AML size */
356 357
357 resource_length = acpi_ut_get_resource_length(aml_buffer); 358 resource_length = acpi_ut_get_resource_length(aml_buffer);
359 minimum_aml_resource_length =
360 acpi_gbl_resource_aml_sizes[resource_index];
358 361
359 /* Augment the size for descriptors with optional fields */ 362 /*
360 363 * Augment the size for descriptors with optional
364 * and/or variable length fields
365 */
361 extra_struct_bytes = 0; 366 extra_struct_bytes = 0;
367 buffer =
368 aml_buffer + acpi_ut_get_resource_header_length(aml_buffer);
362 369
363 if (!(resource_type & ACPI_RESOURCE_NAME_LARGE)) { 370 switch (acpi_ut_get_resource_type(aml_buffer)) {
371 case ACPI_RESOURCE_NAME_IRQ:
364 /* 372 /*
365 * Small resource descriptors 373 * IRQ Resource:
374 * Get the number of bits set in the 16-bit IRQ mask
366 */ 375 */
367 header_length = 376 ACPI_MOVE_16_TO_16(&temp16, buffer);
368 sizeof(struct aml_resource_small_header); 377 extra_struct_bytes =
369 buffer = aml_buffer + header_length; 378 acpi_rs_count_set_bits(temp16) * sizeof(u32);
370 379 break;
371 switch (resource_type) {
372 case ACPI_RESOURCE_NAME_IRQ:
373 /*
374 * IRQ Resource:
375 * Get the number of bits set in the IRQ word
376 */
377 ACPI_MOVE_16_TO_16(&temp16, buffer);
378 extra_struct_bytes =
379 (acpi_rs_count_set_bits(temp16) *
380 sizeof(u32));
381 break;
382
383 case ACPI_RESOURCE_NAME_DMA:
384 /*
385 * DMA Resource:
386 * Get the number of bits set in the DMA channels byte
387 */
388 ACPI_MOVE_16_TO_16(&temp16, buffer);
389 extra_struct_bytes =
390 (acpi_rs_count_set_bits(temp16) *
391 sizeof(u32));
392 break;
393
394 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
395 /*
396 * Vendor Specific Resource:
397 * Ensure a 32-bit boundary for the structure
398 */
399 extra_struct_bytes =
400 ACPI_ROUND_UP_to_32_bITS(resource_length);
401 break;
402 380
403 case ACPI_RESOURCE_NAME_END_TAG: 381 case ACPI_RESOURCE_NAME_DMA:
404 /* 382 /*
405 * End Tag: 383 * DMA Resource:
406 * Terminate the loop now 384 * Get the number of bits set in the 8-bit DMA mask
407 */ 385 */
408 aml_buffer_length = bytes_parsed; 386 extra_struct_bytes =
409 break; 387 acpi_rs_count_set_bits(*buffer) * sizeof(u32);
388 break;
410 389
411 default: 390 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
412 break;
413 }
414 } else {
415 /* 391 /*
416 * Large resource descriptors 392 * Vendor Resource:
393 * Ensure a 32-bit boundary for the structure
417 */ 394 */
418 header_length = 395 extra_struct_bytes =
419 sizeof(struct aml_resource_large_header); 396 ACPI_ROUND_UP_to_32_bITS(resource_length) -
420 buffer = aml_buffer + header_length; 397 resource_length;
398 break;
421 399
422 switch (resource_type) { 400 case ACPI_RESOURCE_NAME_END_TAG:
423 case ACPI_RESOURCE_NAME_VENDOR_LARGE: 401 /*
424 /* 402 * End Tag: This is the normal exit
425 * Vendor Defined Resource: 403 */
426 * Add vendor data and ensure a 32-bit boundary for the structure 404 *size_needed = buffer_size;
427 */ 405 return_ACPI_STATUS(AE_OK);
428 extra_struct_bytes =
429 ACPI_ROUND_UP_to_32_bITS(resource_length);
430 break;
431 406
432 case ACPI_RESOURCE_NAME_ADDRESS32: 407 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
433 case ACPI_RESOURCE_NAME_ADDRESS16: 408 /*
434 /* 409 * Vendor Resource:
435 * 32-Bit or 16-bit Address Resource: 410 * Add vendor data and ensure a 32-bit boundary for the structure
436 * Add the size of any optional data (resource_source) 411 */
437 */ 412 extra_struct_bytes =
438 extra_struct_bytes = 413 ACPI_ROUND_UP_to_32_bITS(resource_length) -
439 acpi_rs_stream_option_length 414 resource_length;
440 (resource_length, 415 break;
441 resource_info->
442 minimum_aml_resource_length);
443 break;
444
445 case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
446 /*
447 * Extended IRQ:
448 * Point past the interrupt_vector_flags to get the
449 * interrupt_table_length.
450 */
451 buffer++;
452 416
453 /* 417 case ACPI_RESOURCE_NAME_ADDRESS32:
454 * Add 4 bytes for each additional interrupt. Note: at least one 418 case ACPI_RESOURCE_NAME_ADDRESS16:
455 * interrupt is required and is included in the minimum 419 /*
456 * descriptor size 420 * 32-Bit or 16-bit Address Resource:
457 */ 421 * Add the size of any optional data (resource_source)
458 extra_struct_bytes = 422 */
459 ((*buffer - 1) * sizeof(u32)); 423 extra_struct_bytes =
424 acpi_rs_stream_option_length(resource_length,
425 minimum_aml_resource_length);
426 break;
460 427
461 /* Add the size of any optional data (resource_source) */ 428 case ACPI_RESOURCE_NAME_EXTENDED_IRQ:
429 /*
430 * Extended IRQ:
431 * Point past the interrupt_vector_flags to get the
432 * interrupt_table_length.
433 */
434 buffer++;
435
436 extra_struct_bytes =
437 /*
438 * Add 4 bytes for each additional interrupt. Note: at
439 * least one interrupt is required and is included in
440 * the minimum descriptor size
441 */
442 ((*buffer - 1) * sizeof(u32)) +
443 /* Add the size of any optional data (resource_source) */
444 acpi_rs_stream_option_length(resource_length -
445 extra_struct_bytes,
446 minimum_aml_resource_length);
447 break;
462 448
463 extra_struct_bytes += 449 case ACPI_RESOURCE_NAME_ADDRESS64:
464 acpi_rs_stream_option_length(resource_length 450 /*
465 - 451 * 64-Bit Address Resource:
466 extra_struct_bytes, 452 * Add the size of any optional data (resource_source)
467 resource_info-> 453 * Ensure a 64-bit boundary for the structure
468 minimum_aml_resource_length); 454 */
469 break; 455 extra_struct_bytes =
456 ACPI_ROUND_UP_to_64_bITS
457 (acpi_rs_stream_option_length
458 (resource_length, minimum_aml_resource_length));
459 break;
470 460
471 case ACPI_RESOURCE_NAME_ADDRESS64: 461 default:
472 /* 462 break;
473 * 64-Bit Address Resource:
474 * Add the size of any optional data (resource_source)
475 * Ensure a 64-bit boundary for the structure
476 */
477 extra_struct_bytes =
478 ACPI_ROUND_UP_to_64_bITS
479 (acpi_rs_stream_option_length
480 (resource_length,
481 resource_info->
482 minimum_aml_resource_length));
483 break;
484
485 default:
486 break;
487 }
488 } 463 }
489 464
490 /* Update the required buffer size for the internal descriptor structs */ 465 /* Update the required buffer size for the internal descriptor structs */
491 466
492 temp16 = 467 temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] +
493 (u16) (resource_info->minimum_internal_struct_length + 468 extra_struct_bytes);
494 extra_struct_bytes);
495 buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); 469 buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16);
496 470
497 /* 471 /*
498 * Update byte count and point to the next resource within the stream 472 * Point to the next resource within the stream
499 * using the size of the header plus the length contained in the header 473 * using the size of the header plus the length contained in the header
500 */ 474 */
501 temp16 = (u16) (header_length + resource_length); 475 aml_buffer += acpi_ut_get_descriptor_length(aml_buffer);
502 bytes_parsed += temp16;
503 aml_buffer += temp16;
504 } 476 }
505 477
506 /* This is the data the caller needs */ 478 /* Did not find an end_tag resource descriptor */
507 479
508 *size_needed = buffer_size; 480 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
509 return_ACPI_STATUS(AE_OK);
510} 481}
511 482
512/******************************************************************************* 483/*******************************************************************************