aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/executer/exfield.c37
-rw-r--r--drivers/acpi/executer/exfldio.c41
2 files changed, 34 insertions, 44 deletions
diff --git a/drivers/acpi/executer/exfield.c b/drivers/acpi/executer/exfield.c
index da772cb91d7f..aef8db82570a 100644
--- a/drivers/acpi/executer/exfield.c
+++ b/drivers/acpi/executer/exfield.c
@@ -210,9 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
210{ 210{
211 acpi_status status; 211 acpi_status status;
212 u32 length; 212 u32 length;
213 u32 required_length;
214 void *buffer; 213 void *buffer;
215 void *new_buffer;
216 union acpi_operand_object *buffer_desc; 214 union acpi_operand_object *buffer_desc;
217 215
218 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); 216 ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
@@ -312,35 +310,6 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
312 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 310 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
313 } 311 }
314 312
315 /*
316 * We must have a buffer that is at least as long as the field
317 * we are writing to. This is because individual fields are
318 * indivisible and partial writes are not supported -- as per
319 * the ACPI specification.
320 */
321 new_buffer = NULL;
322 required_length =
323 ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
324
325 if (length < required_length) {
326
327 /* We need to create a new buffer */
328
329 new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
330 if (!new_buffer) {
331 return_ACPI_STATUS(AE_NO_MEMORY);
332 }
333
334 /*
335 * Copy the original data to the new buffer, starting
336 * at Byte zero. All unused (upper) bytes of the
337 * buffer will be 0.
338 */
339 ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length);
340 buffer = new_buffer;
341 length = required_length;
342 }
343
344 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 313 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
345 "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n", 314 "FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
346 source_desc, 315 source_desc,
@@ -366,11 +335,5 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
366 status = acpi_ex_insert_into_field(obj_desc, buffer, length); 335 status = acpi_ex_insert_into_field(obj_desc, buffer, length);
367 acpi_ex_release_global_lock(obj_desc->common_field.field_flags); 336 acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
368 337
369 /* Free temporary buffer if we used one */
370
371 if (new_buffer) {
372 ACPI_FREE(new_buffer);
373 }
374
375 return_ACPI_STATUS(status); 338 return_ACPI_STATUS(status);
376} 339}
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}