diff options
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
-rw-r--r-- | drivers/acpi/executer/exfldio.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 051053f7cccb..40f0bee6faa5 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c | |||
@@ -727,11 +727,23 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
727 | return_ACPI_STATUS(status); | 727 | return_ACPI_STATUS(status); |
728 | } | 728 | } |
729 | 729 | ||
730 | /* Merge with previous datum if necessary */ | 730 | /* |
731 | 731 | * Merge with previous datum if necessary. | |
732 | merged_datum |= raw_datum << | 732 | * |
733 | (obj_desc->common_field.access_bit_width - | 733 | * Note: Before the shift, check if the shift value will be larger than |
734 | obj_desc->common_field.start_field_bit_offset); | 734 | * the integer size. If so, there is no need to perform the operation. |
735 | * This avoids the differences in behavior between different compilers | ||
736 | * concerning shift values larger than the target data width. | ||
737 | */ | ||
738 | if ((obj_desc->common_field.access_bit_width - | ||
739 | obj_desc->common_field.start_field_bit_offset) < | ||
740 | ACPI_INTEGER_BIT_SIZE) { | ||
741 | merged_datum |= | ||
742 | raw_datum << (obj_desc->common_field. | ||
743 | access_bit_width - | ||
744 | obj_desc->common_field. | ||
745 | start_field_bit_offset); | ||
746 | } | ||
735 | 747 | ||
736 | if (i == datum_count) { | 748 | if (i == datum_count) { |
737 | break; | 749 | break; |
@@ -808,13 +820,23 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
808 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); | 820 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); |
809 | } | 821 | } |
810 | 822 | ||
811 | /* Compute the number of datums (access width data items) */ | 823 | /* |
824 | * Create the bitmasks used for bit insertion. | ||
825 | * Note: This if/else is used to bypass compiler differences with the | ||
826 | * shift operator | ||
827 | */ | ||
828 | if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { | ||
829 | width_mask = ACPI_INTEGER_MAX; | ||
830 | } else { | ||
831 | width_mask = | ||
832 | ACPI_MASK_BITS_ABOVE(obj_desc->common_field. | ||
833 | access_bit_width); | ||
834 | } | ||
812 | 835 | ||
813 | width_mask = | 836 | mask = width_mask & |
814 | ACPI_MASK_BITS_ABOVE(obj_desc->common_field.access_bit_width); | 837 | ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); |
815 | mask = | 838 | |
816 | width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field. | 839 | /* Compute the number of datums (access width data items) */ |
817 | start_field_bit_offset); | ||
818 | 840 | ||
819 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 841 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
820 | obj_desc->common_field.access_bit_width); | 842 | obj_desc->common_field.access_bit_width); |
@@ -848,12 +870,29 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
848 | return_ACPI_STATUS(status); | 870 | return_ACPI_STATUS(status); |
849 | } | 871 | } |
850 | 872 | ||
851 | /* Start new output datum by merging with previous input datum */ | ||
852 | |||
853 | field_offset += obj_desc->common_field.access_byte_width; | 873 | field_offset += obj_desc->common_field.access_byte_width; |
854 | merged_datum = raw_datum >> | 874 | |
855 | (obj_desc->common_field.access_bit_width - | 875 | /* |
856 | obj_desc->common_field.start_field_bit_offset); | 876 | * Start new output datum by merging with previous input datum |
877 | * if necessary. | ||
878 | * | ||
879 | * Note: Before the shift, check if the shift value will be larger than | ||
880 | * the integer size. If so, there is no need to perform the operation. | ||
881 | * This avoids the differences in behavior between different compilers | ||
882 | * concerning shift values larger than the target data width. | ||
883 | */ | ||
884 | if ((obj_desc->common_field.access_bit_width - | ||
885 | obj_desc->common_field.start_field_bit_offset) < | ||
886 | ACPI_INTEGER_BIT_SIZE) { | ||
887 | merged_datum = | ||
888 | raw_datum >> (obj_desc->common_field. | ||
889 | access_bit_width - | ||
890 | obj_desc->common_field. | ||
891 | start_field_bit_offset); | ||
892 | } else { | ||
893 | merged_datum = 0; | ||
894 | } | ||
895 | |||
857 | mask = width_mask; | 896 | mask = width_mask; |
858 | 897 | ||
859 | if (i == datum_count) { | 898 | if (i == datum_count) { |