@@ -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);
@@ -141,6 +142,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg)
*return_value = 0;
value = 0;
+ word = 0;
/*
* Two address spaces supported: Memory or IO. PCI_Config is
@@ -161,28 +163,29 @@ 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)));
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 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 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