aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2013-09-22 21:51:22 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-09-23 19:46:23 -0400
commitc3faedcdb41a2fedbec8ca8f8612d67b012b44a2 (patch)
treed287953ff51e44e7f3be93d42f9d7d825b69a5ad /drivers/acpi/acpica
parentf28eb9f5009abdc74d4052ae05c01795e254a6fc (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.c26
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 ******************************************************************************/
120acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) 120acpi_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
192ACPI_EXPORT_SYMBOL(acpi_read) 194ACPI_EXPORT_SYMBOL(acpi_read)