]> git.hungrycats.org Git - linux/commitdiff
acpi, nfit: fix bus vs dimm confusion in xlat_status
authorDan Williams <dan.j.williams@intel.com>
Tue, 6 Dec 2016 23:06:55 +0000 (15:06 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Dec 2016 16:50:35 +0000 (08:50 -0800)
commit d6eb270c57fef35798525004ddf2ac5dcdadd43b upstream.

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.

Fixes: aef253382266 ("libnvdimm, nfit: centralize command status translation")
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/acpi/nfit/core.c

index 46c01ab020cc9d4029f778928de1685e255874ee..93e0d8333a2077a868feda829aeae3b3063f4f14 100644 (file)
@@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
        return to_acpi_device(acpi_desc->dev);
 }
 
-static int xlat_status(void *buf, unsigned int cmd, u32 status)
+static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
 {
        struct nd_cmd_clear_error *clear_err;
        struct nd_cmd_ars_status *ars_status;
@@ -175,6 +175,16 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
        return 0;
 }
 
+static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
+               u32 status)
+{
+       if (!nvdimm)
+               return xlat_bus_status(buf, cmd, status);
+       if (status)
+               return -EIO;
+       return 0;
+}
+
 static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
                struct nvdimm *nvdimm, unsigned int cmd, void *buf,
                unsigned int buf_len, int *cmd_rc)
@@ -335,7 +345,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
                         */
                        rc = buf_len - offset - in_buf.buffer.length;
                        if (cmd_rc)
-                               *cmd_rc = xlat_status(buf, cmd, fw_status);
+                               *cmd_rc = xlat_status(nvdimm, buf, cmd,
+                                               fw_status);
                } else {
                        dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
                                        __func__, dimm_name, cmd_name, buf_len,
@@ -345,7 +356,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
        } else {
                rc = 0;
                if (cmd_rc)
-                       *cmd_rc = xlat_status(buf, cmd, fw_status);
+                       *cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
        }
 
  out: