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

Commit c3faedcd authored by Bjorn Helgaas's avatar Bjorn Helgaas Committed by Rafael J. Wysocki
Browse files

ACPICA: acpi_read: On error, do not modify the return value target location.



If an error happens in the middle of a split 32/32 64-bit I/O
operation, do not modify the target of the return value pointer.
Makes the code consistent with the rest of ACPICA. Bjorn Helgaas.

Signed-off-by: default avatarBjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Reviewed-by: default avatarLen Brown <len.brown@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent f28eb9f5
Loading
Loading
Loading
Loading
+14 −12
Original line number Diff line number Diff line
@@ -119,7 +119,8 @@ ACPI_EXPORT_SYMBOL(acpi_reset)
 ******************************************************************************/
acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
{
	u32 value;
	u32 value_lo;
	u32 value_hi;
	u32 width;
	u64 address;
	acpi_status status;
@@ -137,13 +138,8 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
		return (status);
	}

	/* Initialize entire 64-bit return value to zero */

	*return_value = 0;
	value = 0;

	/*
	 * Two address spaces supported: Memory or IO. PCI_Config is
	 * Two address spaces supported: Memory or I/O. PCI_Config is
	 * not supported here because the GAS structure is insufficient
	 */
	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
@@ -155,29 +151,35 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
		}
	} else {		/* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */

		value_lo = 0;
		value_hi = 0;

		width = reg->bit_width;
		if (width == 64) {
			width = 32;	/* Break into two 32-bit transfers */
		}

		status = acpi_hw_read_port((acpi_io_address)
					   address, &value, width);
					   address, &value_lo, width);
		if (ACPI_FAILURE(status)) {
			return (status);
		}
		*return_value = value;

		if (reg->bit_width == 64) {

			/* Read the top 32 bits */

			status = acpi_hw_read_port((acpi_io_address)
						   (address + 4), &value, 32);
						   (address + 4), &value_hi,
						   32);
			if (ACPI_FAILURE(status)) {
				return (status);
			}
			*return_value |= ((u64)value << 32);
		}

		/* Set the return value only if status is AE_OK */

		*return_value = (value_lo | ((u64)value_hi << 32));
	}

	ACPI_DEBUG_PRINT((ACPI_DB_IO,
@@ -186,7 +188,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
			  ACPI_FORMAT_UINT64(address),
			  acpi_ut_get_region_name(reg->space_id)));

	return (status);
	return (AE_OK);
}

ACPI_EXPORT_SYMBOL(acpi_read)