diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2013-09-22 21:51:22 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-09-23 19:46:23 -0400 |
commit | c3faedcdb41a2fedbec8ca8f8612d67b012b44a2 (patch) | |
tree | d287953ff51e44e7f3be93d42f9d7d825b69a5ad /drivers/acpi/acpica | |
parent | f28eb9f5009abdc74d4052ae05c01795e254a6fc (diff) |
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: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Reviewed-by: Len Brown <len.brown@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/hwxface.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 5ee7a814cd92..f81fb068d20e 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c | |||
@@ -119,7 +119,8 @@ ACPI_EXPORT_SYMBOL(acpi_reset) | |||
119 | ******************************************************************************/ | 119 | ******************************************************************************/ |
120 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | 120 | acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) |
121 | { | 121 | { |
122 | u32 value; | 122 | u32 value_lo; |
123 | u32 value_hi; | ||
123 | u32 width; | 124 | u32 width; |
124 | u64 address; | 125 | u64 address; |
125 | acpi_status status; | 126 | acpi_status status; |
@@ -137,13 +138,8 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
137 | return (status); | 138 | return (status); |
138 | } | 139 | } |
139 | 140 | ||
140 | /* Initialize entire 64-bit return value to zero */ | ||
141 | |||
142 | *return_value = 0; | ||
143 | value = 0; | ||
144 | |||
145 | /* | 141 | /* |
146 | * Two address spaces supported: Memory or IO. PCI_Config is | 142 | * Two address spaces supported: Memory or I/O. PCI_Config is |
147 | * not supported here because the GAS structure is insufficient | 143 | * not supported here because the GAS structure is insufficient |
148 | */ | 144 | */ |
149 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { | 145 | 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) | |||
155 | } | 151 | } |
156 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ | 152 | } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ |
157 | 153 | ||
154 | value_lo = 0; | ||
155 | value_hi = 0; | ||
156 | |||
158 | width = reg->bit_width; | 157 | width = reg->bit_width; |
159 | if (width == 64) { | 158 | if (width == 64) { |
160 | width = 32; /* Break into two 32-bit transfers */ | 159 | width = 32; /* Break into two 32-bit transfers */ |
161 | } | 160 | } |
162 | 161 | ||
163 | status = acpi_hw_read_port((acpi_io_address) | 162 | status = acpi_hw_read_port((acpi_io_address) |
164 | address, &value, width); | 163 | address, &value_lo, width); |
165 | if (ACPI_FAILURE(status)) { | 164 | if (ACPI_FAILURE(status)) { |
166 | return (status); | 165 | return (status); |
167 | } | 166 | } |
168 | *return_value = value; | ||
169 | 167 | ||
170 | if (reg->bit_width == 64) { | 168 | if (reg->bit_width == 64) { |
171 | 169 | ||
172 | /* Read the top 32 bits */ | 170 | /* Read the top 32 bits */ |
173 | 171 | ||
174 | status = acpi_hw_read_port((acpi_io_address) | 172 | status = acpi_hw_read_port((acpi_io_address) |
175 | (address + 4), &value, 32); | 173 | (address + 4), &value_hi, |
174 | 32); | ||
176 | if (ACPI_FAILURE(status)) { | 175 | if (ACPI_FAILURE(status)) { |
177 | return (status); | 176 | return (status); |
178 | } | 177 | } |
179 | *return_value |= ((u64)value << 32); | ||
180 | } | 178 | } |
179 | |||
180 | /* Set the return value only if status is AE_OK */ | ||
181 | |||
182 | *return_value = (value_lo | ((u64)value_hi << 32)); | ||
181 | } | 183 | } |
182 | 184 | ||
183 | ACPI_DEBUG_PRINT((ACPI_DB_IO, | 185 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
@@ -186,7 +188,7 @@ acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) | |||
186 | ACPI_FORMAT_UINT64(address), | 188 | ACPI_FORMAT_UINT64(address), |
187 | acpi_ut_get_region_name(reg->space_id))); | 189 | acpi_ut_get_region_name(reg->space_id))); |
188 | 190 | ||
189 | return (status); | 191 | return (AE_OK); |
190 | } | 192 | } |
191 | 193 | ||
192 | ACPI_EXPORT_SYMBOL(acpi_read) | 194 | ACPI_EXPORT_SYMBOL(acpi_read) |