diff options
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
| -rw-r--r-- | drivers/acpi/executer/exfldio.c | 67 |
1 files changed, 44 insertions, 23 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index bd1af35f7fcf..051053f7cccb 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
| @@ -87,7 +87,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
| 87 | acpi_status status = AE_OK; | 87 | acpi_status status = AE_OK; |
| 88 | union acpi_operand_object *rgn_desc; | 88 | union acpi_operand_object *rgn_desc; |
| 89 | 89 | ||
| 90 | ACPI_FUNCTION_TRACE_U32("ex_setup_region", field_datum_byte_offset); | 90 | ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset); |
| 91 | 91 | ||
| 92 | rgn_desc = obj_desc->common_field.region_obj; | 92 | rgn_desc = obj_desc->common_field.region_obj; |
| 93 | 93 | ||
| @@ -112,7 +112,18 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | /* Exit if Address/Length have been disallowed by the host OS */ | ||
| 116 | |||
| 117 | if (rgn_desc->common.flags & AOPOBJ_INVALID) { | ||
| 118 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | ||
| 119 | } | ||
| 120 | |||
| 121 | /* | ||
| 122 | * Exit now for SMBus address space, it has a non-linear address space | ||
| 123 | * and the request cannot be directly validated | ||
| 124 | */ | ||
| 115 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { | 125 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { |
| 126 | |||
| 116 | /* SMBus has a non-linear address space */ | 127 | /* SMBus has a non-linear address space */ |
| 117 | 128 | ||
| 118 | return_ACPI_STATUS(AE_OK); | 129 | return_ACPI_STATUS(AE_OK); |
| @@ -134,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
| 134 | * length of one field datum (access width) must fit within the region. | 145 | * length of one field datum (access width) must fit within the region. |
| 135 | * (Region length is specified in bytes) | 146 | * (Region length is specified in bytes) |
| 136 | */ | 147 | */ |
| 137 | if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + | 148 | if (rgn_desc->region.length < |
| 138 | field_datum_byte_offset + | 149 | (obj_desc->common_field.base_byte_offset + |
| 139 | obj_desc->common_field. | 150 | field_datum_byte_offset + |
| 140 | access_byte_width)) { | 151 | obj_desc->common_field.access_byte_width)) { |
| 141 | if (acpi_gbl_enable_interpreter_slack) { | 152 | if (acpi_gbl_enable_interpreter_slack) { |
| 142 | /* | 153 | /* |
| 143 | * Slack mode only: We will go ahead and allow access to this | 154 | * Slack mode only: We will go ahead and allow access to this |
| @@ -217,7 +228,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
| 217 | union acpi_operand_object *rgn_desc; | 228 | union acpi_operand_object *rgn_desc; |
| 218 | acpi_physical_address address; | 229 | acpi_physical_address address; |
| 219 | 230 | ||
| 220 | ACPI_FUNCTION_TRACE("ex_access_region"); | 231 | ACPI_FUNCTION_TRACE(ex_access_region); |
| 221 | 232 | ||
| 222 | /* | 233 | /* |
| 223 | * Ensure that the region operands are fully evaluated and verify | 234 | * Ensure that the region operands are fully evaluated and verify |
| @@ -246,7 +257,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, | |||
| 246 | } | 257 | } |
| 247 | 258 | ||
| 248 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, | 259 | ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, |
| 249 | " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", | 260 | " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n", |
| 250 | acpi_ut_get_region_name(rgn_desc->region. | 261 | acpi_ut_get_region_name(rgn_desc->region. |
| 251 | space_id), | 262 | space_id), |
| 252 | rgn_desc->region.space_id, | 263 | rgn_desc->region.space_id, |
| @@ -352,7 +363,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | |||
| 352 | acpi_status status; | 363 | acpi_status status; |
| 353 | acpi_integer local_value; | 364 | acpi_integer local_value; |
| 354 | 365 | ||
| 355 | ACPI_FUNCTION_TRACE_U32("ex_field_datum_io", field_datum_byte_offset); | 366 | ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset); |
| 356 | 367 | ||
| 357 | if (read_write == ACPI_READ) { | 368 | if (read_write == ACPI_READ) { |
| 358 | if (!value) { | 369 | if (!value) { |
| @@ -487,10 +498,11 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc, | |||
| 487 | } | 498 | } |
| 488 | 499 | ||
| 489 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 500 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
| 490 | "I/O to Data Register: value_ptr %p\n", | 501 | "I/O to Data Register: ValuePtr %p\n", |
| 491 | value)); | 502 | value)); |
| 492 | 503 | ||
| 493 | if (read_write == ACPI_READ) { | 504 | if (read_write == ACPI_READ) { |
| 505 | |||
| 494 | /* Read the datum from the data_register */ | 506 | /* Read the datum from the data_register */ |
| 495 | 507 | ||
| 496 | status = | 508 | status = |
| @@ -559,7 +571,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, | |||
| 559 | acpi_integer merged_value; | 571 | acpi_integer merged_value; |
| 560 | acpi_integer current_value; | 572 | acpi_integer current_value; |
| 561 | 573 | ||
| 562 | ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask); | 574 | ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask); |
| 563 | 575 | ||
| 564 | /* Start with the new bits */ | 576 | /* Start with the new bits */ |
| 565 | 577 | ||
| @@ -568,6 +580,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, | |||
| 568 | /* If the mask is all ones, we don't need to worry about the update rule */ | 580 | /* If the mask is all ones, we don't need to worry about the update rule */ |
| 569 | 581 | ||
| 570 | if (mask != ACPI_INTEGER_MAX) { | 582 | if (mask != ACPI_INTEGER_MAX) { |
| 583 | |||
| 571 | /* Decode the update rule */ | 584 | /* Decode the update rule */ |
| 572 | 585 | ||
| 573 | switch (obj_desc->common_field. | 586 | switch (obj_desc->common_field. |
| @@ -614,7 +627,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, | |||
| 614 | default: | 627 | default: |
| 615 | 628 | ||
| 616 | ACPI_ERROR((AE_INFO, | 629 | ACPI_ERROR((AE_INFO, |
| 617 | "Unknown update_rule value: %X", | 630 | "Unknown UpdateRule value: %X", |
| 618 | (obj_desc->common_field. | 631 | (obj_desc->common_field. |
| 619 | field_flags & | 632 | field_flags & |
| 620 | AML_FIELD_UPDATE_RULE_MASK))); | 633 | AML_FIELD_UPDATE_RULE_MASK))); |
| @@ -623,7 +636,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc, | |||
| 623 | } | 636 | } |
| 624 | 637 | ||
| 625 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 638 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
| 626 | "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", | 639 | "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n", |
| 627 | ACPI_FORMAT_UINT64(mask), | 640 | ACPI_FORMAT_UINT64(mask), |
| 628 | field_datum_byte_offset, | 641 | field_datum_byte_offset, |
| 629 | obj_desc->common_field.access_byte_width, | 642 | obj_desc->common_field.access_byte_width, |
| @@ -666,7 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
| 666 | u32 field_datum_count; | 679 | u32 field_datum_count; |
| 667 | u32 i; | 680 | u32 i; |
| 668 | 681 | ||
| 669 | ACPI_FUNCTION_TRACE("ex_extract_from_field"); | 682 | ACPI_FUNCTION_TRACE(ex_extract_from_field); |
| 670 | 683 | ||
| 671 | /* Validate target buffer and clear it */ | 684 | /* Validate target buffer and clear it */ |
| 672 | 685 | ||
| @@ -704,6 +717,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
| 704 | /* Read the rest of the field */ | 717 | /* Read the rest of the field */ |
| 705 | 718 | ||
| 706 | for (i = 1; i < field_datum_count; i++) { | 719 | for (i = 1; i < field_datum_count; i++) { |
| 720 | |||
| 707 | /* Get next input datum from the field */ | 721 | /* Get next input datum from the field */ |
| 708 | 722 | ||
| 709 | field_offset += obj_desc->common_field.access_byte_width; | 723 | field_offset += obj_desc->common_field.access_byte_width; |
| @@ -771,6 +785,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
| 771 | { | 785 | { |
| 772 | acpi_status status; | 786 | acpi_status status; |
| 773 | acpi_integer mask; | 787 | acpi_integer mask; |
| 788 | acpi_integer width_mask; | ||
| 774 | acpi_integer merged_datum; | 789 | acpi_integer merged_datum; |
| 775 | acpi_integer raw_datum = 0; | 790 | acpi_integer raw_datum = 0; |
| 776 | u32 field_offset = 0; | 791 | u32 field_offset = 0; |
| @@ -780,7 +795,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
| 780 | u32 field_datum_count; | 795 | u32 field_datum_count; |
| 781 | u32 i; | 796 | u32 i; |
| 782 | 797 | ||
| 783 | ACPI_FUNCTION_TRACE("ex_insert_into_field"); | 798 | ACPI_FUNCTION_TRACE(ex_insert_into_field); |
| 784 | 799 | ||
| 785 | /* Validate input buffer */ | 800 | /* Validate input buffer */ |
| 786 | 801 | ||
| @@ -795,15 +810,20 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
| 795 | 810 | ||
| 796 | /* Compute the number of datums (access width data items) */ | 811 | /* Compute the number of datums (access width data items) */ |
| 797 | 812 | ||
| 813 | width_mask = | ||
| 814 | ACPI_MASK_BITS_ABOVE(obj_desc->common_field.access_bit_width); | ||
| 798 | mask = | 815 | mask = |
| 799 | ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); | 816 | width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field. |
| 800 | datum_count = | 817 | start_field_bit_offset); |
| 801 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 818 | |
| 802 | obj_desc->common_field.access_bit_width); | 819 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
| 803 | field_datum_count = | 820 | obj_desc->common_field.access_bit_width); |
| 804 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 821 | |
| 805 | obj_desc->common_field.start_field_bit_offset, | 822 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
| 806 | obj_desc->common_field.access_bit_width); | 823 | obj_desc->common_field. |
| 824 | start_field_bit_offset, | ||
| 825 | obj_desc->common_field. | ||
| 826 | access_bit_width); | ||
| 807 | 827 | ||
| 808 | /* Get initial Datum from the input buffer */ | 828 | /* Get initial Datum from the input buffer */ |
| 809 | 829 | ||
| @@ -817,6 +837,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
| 817 | /* Write the entire field */ | 837 | /* Write the entire field */ |
| 818 | 838 | ||
| 819 | for (i = 1; i < field_datum_count; i++) { | 839 | for (i = 1; i < field_datum_count; i++) { |
| 840 | |||
| 820 | /* Write merged datum to the target field */ | 841 | /* Write merged datum to the target field */ |
| 821 | 842 | ||
| 822 | merged_datum &= mask; | 843 | merged_datum &= mask; |
| @@ -833,7 +854,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
| 833 | merged_datum = raw_datum >> | 854 | merged_datum = raw_datum >> |
| 834 | (obj_desc->common_field.access_bit_width - | 855 | (obj_desc->common_field.access_bit_width - |
| 835 | obj_desc->common_field.start_field_bit_offset); | 856 | obj_desc->common_field.start_field_bit_offset); |
| 836 | mask = ACPI_INTEGER_MAX; | 857 | mask = width_mask; |
| 837 | 858 | ||
| 838 | if (i == datum_count) { | 859 | if (i == datum_count) { |
| 839 | break; | 860 | break; |
