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>
This commit is contained in:
parent
549f46044e
commit
9aa6169f47
2 changed files with 34 additions and 44 deletions
|
@ -210,9 +210,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|
||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
u32 length;
|
u32 length;
|
||||||
u32 required_length;
|
|
||||||
void *buffer;
|
void *buffer;
|
||||||
void *new_buffer;
|
|
||||||
union acpi_operand_object *buffer_desc;
|
union acpi_operand_object *buffer_desc;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
|
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,
|
||||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We must have a buffer that is at least as long as the field
|
|
||||||
* we are writing to. This is because individual fields are
|
|
||||||
* indivisible and partial writes are not supported -- as per
|
|
||||||
* the ACPI specification.
|
|
||||||
*/
|
|
||||||
new_buffer = NULL;
|
|
||||||
required_length =
|
|
||||||
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
|
|
||||||
|
|
||||||
if (length < required_length) {
|
|
||||||
|
|
||||||
/* We need to create a new buffer */
|
|
||||||
|
|
||||||
new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
|
|
||||||
if (!new_buffer) {
|
|
||||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy the original data to the new buffer, starting
|
|
||||||
* at Byte zero. All unused (upper) bytes of the
|
|
||||||
* buffer will be 0.
|
|
||||||
*/
|
|
||||||
ACPI_MEMCPY((char *)new_buffer, (char *)buffer, length);
|
|
||||||
buffer = new_buffer;
|
|
||||||
length = required_length;
|
|
||||||
}
|
|
||||||
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
|
||||||
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
|
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
|
||||||
source_desc,
|
source_desc,
|
||||||
|
@ -366,11 +335,5 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|
||||||
status = acpi_ex_insert_into_field(obj_desc, buffer, length);
|
status = acpi_ex_insert_into_field(obj_desc, buffer, length);
|
||||||
acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
|
acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
|
||||||
|
|
||||||
/* Free temporary buffer if we used one */
|
|
||||||
|
|
||||||
if (new_buffer) {
|
|
||||||
ACPI_FREE(new_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
|
@ -806,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||||
u32 datum_count;
|
u32 datum_count;
|
||||||
u32 field_datum_count;
|
u32 field_datum_count;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
u32 required_length;
|
||||||
|
void *new_buffer;
|
||||||
|
|
||||||
ACPI_FUNCTION_TRACE(ex_insert_into_field);
|
ACPI_FUNCTION_TRACE(ex_insert_into_field);
|
||||||
|
|
||||||
/* Validate input buffer */
|
/* Validate input buffer */
|
||||||
|
|
||||||
if (buffer_length <
|
new_buffer = NULL;
|
||||||
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) {
|
required_length =
|
||||||
ACPI_ERROR((AE_INFO,
|
ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length);
|
||||||
"Field size %X (bits) is too large for buffer (%X)",
|
/*
|
||||||
obj_desc->common_field.bit_length, buffer_length));
|
* We must have a buffer that is at least as long as the field
|
||||||
|
* we are writing to. This is because individual fields are
|
||||||
|
* indivisible and partial writes are not supported -- as per
|
||||||
|
* the ACPI specification.
|
||||||
|
*/
|
||||||
|
if (buffer_length < required_length) {
|
||||||
|
|
||||||
return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
|
/* We need to create a new buffer */
|
||||||
|
|
||||||
|
new_buffer = ACPI_ALLOCATE_ZEROED(required_length);
|
||||||
|
if (!new_buffer) {
|
||||||
|
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the original data to the new buffer, starting
|
||||||
|
* at Byte zero. All unused (upper) bytes of the
|
||||||
|
* buffer will be 0.
|
||||||
|
*/
|
||||||
|
ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length);
|
||||||
|
buffer = new_buffer;
|
||||||
|
buffer_length = required_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -867,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||||
merged_datum,
|
merged_datum,
|
||||||
field_offset);
|
field_offset);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
return_ACPI_STATUS(status);
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
field_offset += obj_desc->common_field.access_byte_width;
|
field_offset += obj_desc->common_field.access_byte_width;
|
||||||
|
@ -925,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
|
||||||
mask, merged_datum,
|
mask, merged_datum,
|
||||||
field_offset);
|
field_offset);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Free temporary buffer if we used one */
|
||||||
|
|
||||||
|
if (new_buffer) {
|
||||||
|
ACPI_FREE(new_buffer);
|
||||||
|
}
|
||||||
return_ACPI_STATUS(status);
|
return_ACPI_STATUS(status);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue