[PATCH 1/2] ACPICA: acpi_read: update return value atomically

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Accumulate the entire 64-bit value before updating the return_value.
Previously, it was possible to update the low 32 bits, then return
failure if reading the upper 32 bits failed, leaving a half-updated
return_value.

Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx>
---
 drivers/acpi/acpica/hwxface.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index c2793a8..12b5c57 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -123,6 +123,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 	u32 value;
 	u32 width;
 	u64 address;
+	u64 complete_value;
 	acpi_status status;
 
 	ACPI_FUNCTION_NAME(acpi_read);
@@ -146,6 +147,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 	/* Initialize entire 64-bit return value to zero */
 
 	*return_value = 0;
+	complete_value = 0;
 	value = 0;
 
 	/*
@@ -158,7 +160,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
-		*return_value = value;
+		complete_value = value;
 
 		if (reg->bit_width == 64) {
 
@@ -169,7 +171,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
-			*return_value |= ((u64)value << 32);
+			complete_value |= ((u64)value << 32);
 		}
 	} else {		/* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
 
@@ -178,7 +180,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
-		*return_value = value;
+		complete_value = value;
 
 		if (reg->bit_width == 64) {
 
@@ -189,10 +191,11 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
-			*return_value |= ((u64)value << 32);
+			complete_value |= ((u64)value << 32);
 		}
 	}
 
+	*return_value = complete_value;
 	ACPI_DEBUG_PRINT((ACPI_DB_IO,
 			  "Read:  %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
 			  ACPI_FORMAT_UINT64(*return_value), reg->bit_width,

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux