aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/exfldio.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2010-08-05 21:09:33 -0400
committerLen Brown <len.brown@intel.com>2010-10-01 01:46:32 -0400
commit09387b43153953006471dbb06ece6bf779d10937 (patch)
tree109d294ec27e0719dfb3ea5a2cd79f6811edd3be /drivers/acpi/acpica/exfldio.c
parentc5f0231ee6b0441e4c45f461f2b6652b10195494 (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.c75
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
798acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, 816acpi_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 }