aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exfldio.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2008-04-10 11:06:41 -0400
committerLen Brown <len.brown@intel.com>2008-04-22 14:29:28 -0400
commit9aa6169f471771324b476a90d9392daa06d63a2d (patch)
tree56b435edcccebf6c2803799b91350c50598d8fe9 /drivers/acpi/executer/exfldio.c
parent549f46044e1e207a2cbfdfb3f9a0d3fd5fd4105e (diff)
ACPICA: Fixed a problem with Index Fields where the Index register was incorrectly limited to a maximum of 32 bits
Now any size may be used. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
-rw-r--r--drivers/acpi/executer/exfldio.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index 1ece1c3fc375..ae402949c357 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -806,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
806 u32 datum_count; 806 u32 datum_count;
807 u32 field_datum_count; 807 u32 field_datum_count;
808 u32 i; 808 u32 i;
809 u32 required_length;
810 void *new_buffer;
809 811
810 ACPI_FUNCTION_TRACE(ex_insert_into_field); 812 ACPI_FUNCTION_TRACE(ex_insert_into_field);
811 813
812 /* Validate input buffer */ 814 /* Validate input buffer */
813 815
814 if (buffer_length < 816 new_buffer = NULL;
815 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { 817 required_length =
816 ACPI_ERROR((AE_INFO, 818 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
817 "Field size %X (bits) is too large for buffer (%X)", 819 /*
818 obj_desc->common_field.bit_length, buffer_length)); 820 * We must have a buffer that is at least as long as the field
821 * we are writing to. This is because individual fields are
822 * indivisible and partial writes are not supported -- as per
823 * the ACPI specification.
824 */
825 if (buffer_length < required_length) {
819 826
820 return_ACPI_STATUS(AE_BUFFER_OVERFLOW); 827 /* We need to create a new buffer */
828
829 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
830 if (!new_buffer) {
831 return_ACPI_STATUS(AE_NO_MEMORY);
832 }
833
834 /*
835 * Copy the original data to the new buffer, starting
836 * at Byte zero. All unused (upper) bytes of the
837 * buffer will be 0.
838 */
839 ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
840 buffer = new_buffer;
841 buffer_length = required_length;
821 } 842 }
822 843
823 /* 844 /*
@@ -867,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
867 merged_datum, 888 merged_datum,
868 field_offset); 889 field_offset);
869 if (ACPI_FAILURE(status)) { 890 if (ACPI_FAILURE(status)) {
870 return_ACPI_STATUS(status); 891 goto exit;
871 } 892 }
872 893
873 field_offset += obj_desc->common_field.access_byte_width; 894 field_offset += obj_desc->common_field.access_byte_width;
@@ -925,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
925 mask, merged_datum, 946 mask, merged_datum,
926 field_offset); 947 field_offset);
927 948
949 exit:
950 /* Free temporary buffer if we used one */
951
952 if (new_buffer) {
953 ACPI_FREE(new_buffer);
954 }
928 return_ACPI_STATUS(status); 955 return_ACPI_STATUS(status);
929} 956}