diff options
author | Bob Moore <robert.moore@intel.com> | 2010-08-05 21:09:33 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2010-10-01 01:46:32 -0400 |
commit | 09387b43153953006471dbb06ece6bf779d10937 (patch) | |
tree | 109d294ec27e0719dfb3ea5a2cd79f6811edd3be /drivers/acpi/acpica/exfldio.c | |
parent | c5f0231ee6b0441e4c45f461f2b6652b10195494 (diff) |
ACPICA: Revert "Revert "Enable multi-byte EC transfers
This reverts commit f23b9c7(http://git.moblin.org/cgit.cgi/acpica/commit/?id=f23b9c7)
The problem with this change was determined to be a problem with
the FreeBSD host OSL (OS services layer), not with this patch
itself. Therefore, re-introducing this change into the main ACPICA
code. See ACPICA bugzilla 863.
http://www.acpica.org/bugzilla/show_bug.cgi?id=863
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/exfldio.c')
-rw-r--r-- | drivers/acpi/acpica/exfldio.c | 75 |
1 files changed, 50 insertions, 25 deletions
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 047217303a4b..38293fd3e088 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c | |||
@@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
119 | } | 119 | } |
120 | 120 | ||
121 | /* | 121 | /* |
122 | * Exit now for SMBus or IPMI address space, it has a non-linear address space | 122 | * Exit now for SMBus or IPMI address space, it has a non-linear |
123 | * and the request cannot be directly validated | 123 | * address space and the request cannot be directly validated |
124 | */ | 124 | */ |
125 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || | 125 | if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || |
126 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { | 126 | rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { |
@@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, | |||
147 | * (Region length is specified in bytes) | 147 | * (Region length is specified in bytes) |
148 | */ | 148 | */ |
149 | if (rgn_desc->region.length < | 149 | if (rgn_desc->region.length < |
150 | (obj_desc->common_field.base_byte_offset + | 150 | (obj_desc->common_field.base_byte_offset + field_datum_byte_offset + |
151 | field_datum_byte_offset + | ||
152 | obj_desc->common_field.access_byte_width)) { | 151 | obj_desc->common_field.access_byte_width)) { |
153 | if (acpi_gbl_enable_interpreter_slack) { | 152 | if (acpi_gbl_enable_interpreter_slack) { |
154 | /* | 153 | /* |
@@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
680 | u32 buffer_tail_bits; | 679 | u32 buffer_tail_bits; |
681 | u32 datum_count; | 680 | u32 datum_count; |
682 | u32 field_datum_count; | 681 | u32 field_datum_count; |
682 | u32 access_bit_width; | ||
683 | u32 i; | 683 | u32 i; |
684 | 684 | ||
685 | ACPI_FUNCTION_TRACE(ex_extract_from_field); | 685 | ACPI_FUNCTION_TRACE(ex_extract_from_field); |
@@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
694 | 694 | ||
695 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); | 695 | return_ACPI_STATUS(AE_BUFFER_OVERFLOW); |
696 | } | 696 | } |
697 | |||
697 | ACPI_MEMSET(buffer, 0, buffer_length); | 698 | ACPI_MEMSET(buffer, 0, buffer_length); |
699 | access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); | ||
700 | |||
701 | /* Handle the simple case here */ | ||
702 | |||
703 | if ((obj_desc->common_field.start_field_bit_offset == 0) && | ||
704 | (obj_desc->common_field.bit_length == access_bit_width)) { | ||
705 | status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); | ||
706 | return_ACPI_STATUS(status); | ||
707 | } | ||
708 | |||
709 | /* TBD: Move to common setup code */ | ||
710 | |||
711 | /* Field algorithm is limited to sizeof(u64), truncate if needed */ | ||
712 | |||
713 | if (obj_desc->common_field.access_byte_width > sizeof(u64)) { | ||
714 | obj_desc->common_field.access_byte_width = sizeof(u64); | ||
715 | access_bit_width = sizeof(u64) * 8; | ||
716 | } | ||
698 | 717 | ||
699 | /* Compute the number of datums (access width data items) */ | 718 | /* Compute the number of datums (access width data items) */ |
700 | 719 | ||
701 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 720 | datum_count = |
702 | obj_desc->common_field.access_bit_width); | 721 | ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
722 | access_bit_width); | ||
723 | |||
703 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 724 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
704 | obj_desc->common_field. | 725 | obj_desc->common_field. |
705 | start_field_bit_offset, | 726 | start_field_bit_offset, |
706 | obj_desc->common_field. | ||
707 | access_bit_width); | 727 | access_bit_width); |
708 | 728 | ||
709 | /* Priming read from the field */ | 729 | /* Priming read from the field */ |
@@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
738 | * This avoids the differences in behavior between different compilers | 758 | * This avoids the differences in behavior between different compilers |
739 | * concerning shift values larger than the target data width. | 759 | * concerning shift values larger than the target data width. |
740 | */ | 760 | */ |
741 | if ((obj_desc->common_field.access_bit_width - | 761 | if (access_bit_width - |
742 | obj_desc->common_field.start_field_bit_offset) < | 762 | obj_desc->common_field.start_field_bit_offset < |
743 | ACPI_INTEGER_BIT_SIZE) { | 763 | ACPI_INTEGER_BIT_SIZE) { |
744 | merged_datum |= | 764 | merged_datum |= |
745 | raw_datum << (obj_desc->common_field. | 765 | raw_datum << (access_bit_width - |
746 | access_bit_width - | ||
747 | obj_desc->common_field. | 766 | obj_desc->common_field. |
748 | start_field_bit_offset); | 767 | start_field_bit_offset); |
749 | } | 768 | } |
@@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, | |||
765 | 784 | ||
766 | /* Mask off any extra bits in the last datum */ | 785 | /* Mask off any extra bits in the last datum */ |
767 | 786 | ||
768 | buffer_tail_bits = obj_desc->common_field.bit_length % | 787 | buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width; |
769 | obj_desc->common_field.access_bit_width; | ||
770 | if (buffer_tail_bits) { | 788 | if (buffer_tail_bits) { |
771 | merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); | 789 | merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); |
772 | } | 790 | } |
@@ -798,6 +816,7 @@ acpi_status | |||
798 | acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | 816 | acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, |
799 | void *buffer, u32 buffer_length) | 817 | void *buffer, u32 buffer_length) |
800 | { | 818 | { |
819 | void *new_buffer; | ||
801 | acpi_status status; | 820 | acpi_status status; |
802 | u64 mask; | 821 | u64 mask; |
803 | u64 width_mask; | 822 | u64 width_mask; |
@@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
808 | u32 buffer_tail_bits; | 827 | u32 buffer_tail_bits; |
809 | u32 datum_count; | 828 | u32 datum_count; |
810 | u32 field_datum_count; | 829 | u32 field_datum_count; |
811 | u32 i; | 830 | u32 access_bit_width; |
812 | u32 required_length; | 831 | u32 required_length; |
813 | void *new_buffer; | 832 | u32 i; |
814 | 833 | ||
815 | ACPI_FUNCTION_TRACE(ex_insert_into_field); | 834 | ACPI_FUNCTION_TRACE(ex_insert_into_field); |
816 | 835 | ||
@@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
844 | buffer_length = required_length; | 863 | buffer_length = required_length; |
845 | } | 864 | } |
846 | 865 | ||
866 | /* TBD: Move to common setup code */ | ||
867 | |||
868 | /* Algo is limited to sizeof(u64), so cut the access_byte_width */ | ||
869 | if (obj_desc->common_field.access_byte_width > sizeof(u64)) { | ||
870 | obj_desc->common_field.access_byte_width = sizeof(u64); | ||
871 | } | ||
872 | |||
873 | access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width); | ||
874 | |||
847 | /* | 875 | /* |
848 | * Create the bitmasks used for bit insertion. | 876 | * Create the bitmasks used for bit insertion. |
849 | * Note: This if/else is used to bypass compiler differences with the | 877 | * Note: This if/else is used to bypass compiler differences with the |
850 | * shift operator | 878 | * shift operator |
851 | */ | 879 | */ |
852 | if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) { | 880 | if (access_bit_width == ACPI_INTEGER_BIT_SIZE) { |
853 | width_mask = ACPI_UINT64_MAX; | 881 | width_mask = ACPI_UINT64_MAX; |
854 | } else { | 882 | } else { |
855 | width_mask = | 883 | width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width); |
856 | ACPI_MASK_BITS_ABOVE(obj_desc->common_field. | ||
857 | access_bit_width); | ||
858 | } | 884 | } |
859 | 885 | ||
860 | mask = width_mask & | 886 | mask = width_mask & |
@@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
863 | /* Compute the number of datums (access width data items) */ | 889 | /* Compute the number of datums (access width data items) */ |
864 | 890 | ||
865 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, | 891 | datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, |
866 | obj_desc->common_field.access_bit_width); | 892 | access_bit_width); |
867 | 893 | ||
868 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + | 894 | field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + |
869 | obj_desc->common_field. | 895 | obj_desc->common_field. |
870 | start_field_bit_offset, | 896 | start_field_bit_offset, |
871 | obj_desc->common_field. | ||
872 | access_bit_width); | 897 | access_bit_width); |
873 | 898 | ||
874 | /* Get initial Datum from the input buffer */ | 899 | /* Get initial Datum from the input buffer */ |
@@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
905 | * This avoids the differences in behavior between different compilers | 930 | * This avoids the differences in behavior between different compilers |
906 | * concerning shift values larger than the target data width. | 931 | * concerning shift values larger than the target data width. |
907 | */ | 932 | */ |
908 | if ((obj_desc->common_field.access_bit_width - | 933 | if ((access_bit_width - |
909 | obj_desc->common_field.start_field_bit_offset) < | 934 | obj_desc->common_field.start_field_bit_offset) < |
910 | ACPI_INTEGER_BIT_SIZE) { | 935 | ACPI_INTEGER_BIT_SIZE) { |
911 | merged_datum = | 936 | merged_datum = |
912 | raw_datum >> (obj_desc->common_field. | 937 | raw_datum >> (access_bit_width - |
913 | access_bit_width - | ||
914 | obj_desc->common_field. | 938 | obj_desc->common_field. |
915 | start_field_bit_offset); | 939 | start_field_bit_offset); |
916 | } else { | 940 | } else { |
@@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
929 | ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, | 953 | ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset, |
930 | ACPI_MIN(obj_desc->common_field.access_byte_width, | 954 | ACPI_MIN(obj_desc->common_field.access_byte_width, |
931 | buffer_length - buffer_offset)); | 955 | buffer_length - buffer_offset)); |
956 | |||
932 | merged_datum |= | 957 | merged_datum |= |
933 | raw_datum << obj_desc->common_field.start_field_bit_offset; | 958 | raw_datum << obj_desc->common_field.start_field_bit_offset; |
934 | } | 959 | } |
@@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, | |||
937 | 962 | ||
938 | buffer_tail_bits = (obj_desc->common_field.bit_length + | 963 | buffer_tail_bits = (obj_desc->common_field.bit_length + |
939 | obj_desc->common_field.start_field_bit_offset) % | 964 | obj_desc->common_field.start_field_bit_offset) % |
940 | obj_desc->common_field.access_bit_width; | 965 | access_bit_width; |
941 | if (buffer_tail_bits) { | 966 | if (buffer_tail_bits) { |
942 | mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); | 967 | mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits); |
943 | } | 968 | } |