Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9aa6169f authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

ACPICA: Fixed a problem with Index Fields where the Index register was...


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: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarAlexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 549f4604
Loading
Loading
Loading
Loading
+0 −37
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+34 −7
Original line number Original line Diff line number Diff line
@@ -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);
}
}