diff mbox

[v2] ACPICA: acpi_read: update return_value atomically

Message ID 20130731192837.8393.78635.stgit@bhelgaas-glaptop (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Bjorn Helgaas July 31, 2013, 7:28 p.m. UTC
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@google.com>
---
 drivers/acpi/acpica/hwxface.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)


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

Patch

diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index 5ee7a81..3cf7b86 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -119,9 +119,10 @@  ACPI_EXPORT_SYMBOL(acpi_reset)
  ******************************************************************************/
 acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 {
-	u32 value;
+	u32 word;
 	u32 width;
 	u64 address;
+	u64 value;
 	acpi_status status;
 
 	ACPI_FUNCTION_NAME(acpi_read);
@@ -137,10 +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;
+	word = 0;
 
 	/*
 	 * Two address spaces supported: Memory or IO. PCI_Config is
@@ -161,32 +160,33 @@  acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
 		}
 
 		status = acpi_hw_read_port((acpi_io_address)
-					   address, &value, width);
+					   address, &word, width);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
-		*return_value = value;
+		value = word;
 
 		if (reg->bit_width == 64) {
 
 			/* Read the top 32 bits */
 
 			status = acpi_hw_read_port((acpi_io_address)
-						   (address + 4), &value, 32);
+						   (address + 4), &word, 32);
 			if (ACPI_FAILURE(status)) {
 				return (status);
 			}
-			*return_value |= ((u64)value << 32);
+			value |= ((u64)word << 32);
 		}
 	}
 
+	*return_value = 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,
+			  ACPI_FORMAT_UINT64(value), reg->bit_width,
 			  ACPI_FORMAT_UINT64(address),
 			  acpi_ut_get_region_name(reg->space_id)));
 
-	return (status);
+	return (AE_OK);
 }
 
 ACPI_EXPORT_SYMBOL(acpi_read)