aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-12-06 18:06:55 -0500
committerDan Williams <dan.j.williams@intel.com>2016-12-06 19:30:37 -0500
commitd6eb270c57fef35798525004ddf2ac5dcdadd43b (patch)
tree5ffbbc6b4585a5df44dc7d5b9017188469252684
parent82aa37cf09867c5e2c0326649d570e5b25c1189a (diff)
acpi, nfit: fix bus vs dimm confusion in xlat_status
Given dimms and bus commands share the same command number space we need to be careful that we are translating status in the correct context. Otherwise we can, for example, fail an ND_CMD_GET_CONFIG_SIZE command because max_xfer is zero. It fails because that condition erroneously correlates with the 'cleared == 0' failure of ND_CMD_CLEAR_ERROR. Cc: <stable@vger.kernel.org> Fixes: aef253382266 ("libnvdimm, nfit: centralize command status translation") Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/acpi/nfit/core.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 4b8b4f520d76..09d3db322ee8 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
94 return to_acpi_device(acpi_desc->dev); 94 return to_acpi_device(acpi_desc->dev);
95} 95}
96 96
97static int xlat_status(void *buf, unsigned int cmd, u32 status) 97static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
98{ 98{
99 struct nd_cmd_clear_error *clear_err; 99 struct nd_cmd_clear_error *clear_err;
100 struct nd_cmd_ars_status *ars_status; 100 struct nd_cmd_ars_status *ars_status;
@@ -175,6 +175,16 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
175 return 0; 175 return 0;
176} 176}
177 177
178static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
179 u32 status)
180{
181 if (!nvdimm)
182 return xlat_bus_status(buf, cmd, status);
183 if (status)
184 return -EIO;
185 return 0;
186}
187
178static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 188static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
179 struct nvdimm *nvdimm, unsigned int cmd, void *buf, 189 struct nvdimm *nvdimm, unsigned int cmd, void *buf,
180 unsigned int buf_len, int *cmd_rc) 190 unsigned int buf_len, int *cmd_rc)
@@ -335,7 +345,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
335 */ 345 */
336 rc = buf_len - offset - in_buf.buffer.length; 346 rc = buf_len - offset - in_buf.buffer.length;
337 if (cmd_rc) 347 if (cmd_rc)
338 *cmd_rc = xlat_status(buf, cmd, fw_status); 348 *cmd_rc = xlat_status(nvdimm, buf, cmd,
349 fw_status);
339 } else { 350 } else {
340 dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n", 351 dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
341 __func__, dimm_name, cmd_name, buf_len, 352 __func__, dimm_name, cmd_name, buf_len,
@@ -345,7 +356,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
345 } else { 356 } else {
346 rc = 0; 357 rc = 0;
347 if (cmd_rc) 358 if (cmd_rc)
348 *cmd_rc = xlat_status(buf, cmd, fw_status); 359 *cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
349 } 360 }
350 361
351 out: 362 out: