All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Williams <dan.j.williams@intel.com>
To: linux-nvdimm@lists.01.org
Cc: vishal.l.verma@intel.com
Subject: [ndctl PATCH 24/36] ndctl/dimm: Rework dimm command status reporting
Date: Sat, 29 Feb 2020 12:22:12 -0800	[thread overview]
Message-ID: <158300773196.2141307.16404460619761697075.stgit@dwillia2-desk3.amr.corp.intel.com> (raw)
In-Reply-To: <158300760415.2141307.14060353322051900501.stgit@dwillia2-desk3.amr.corp.intel.com>

The build currently spews many errors of the form:

hyperv.c: In function ‘alloc_hyperv_cmd’:
hyperv.c:61:25: warning: taking address of packed member of ‘struct nd_hyperv_health_info’ may result in an unaligned pointer value [-Waddress-of-packed-member]
   61 |  cmd->firmware_status = &hyperv->u.health_info.status;

Move the status reporting from passing an unaligned pointer to a new
->get_firmware_status() operation.

Link: https://github.com/pmem/ndctl/issues/131
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/lib/ars.c       |   28 +++++++++++++++++++------
 ndctl/lib/hpe1.c      |   17 +++++++++++----
 ndctl/lib/hyperv.c    |    7 +++++-
 ndctl/lib/intel.c     |   56 +++++++++++++++++++++++++++++++++++--------------
 ndctl/lib/libndctl.c  |   39 ++++++++++++++++++++++++++--------
 ndctl/lib/msft.c      |    8 +++++--
 ndctl/lib/nfit.c      |   36 +++++++++++++++++++++-----------
 ndctl/lib/private.h   |    7 ++++--
 ndctl/libndctl-nfit.h |   11 ++++++++++
 9 files changed, 157 insertions(+), 52 deletions(-)

diff --git a/ndctl/lib/ars.c b/ndctl/lib/ars.c
index d91a99d00d10..44871b2afde2 100644
--- a/ndctl/lib/ars.c
+++ b/ndctl/lib/ars.c
@@ -15,6 +15,22 @@
 #include <ndctl/libndctl.h>
 #include "private.h"
 
+static u32 get_ars_command_status(struct ndctl_cmd *cmd)
+{
+	switch (cmd->type) {
+	case ND_CMD_ARS_CAP:
+		return cmd->ars_cap->status;
+	case ND_CMD_ARS_START:
+		return cmd->ars_start->status;
+	case ND_CMD_ARS_STATUS:
+		return cmd->ars_status->status;
+	case ND_CMD_CLEAR_ERROR:
+		return cmd->clear_err->status;
+	}
+
+	return -1U;
+}
+
 NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_cap(struct ndctl_bus *bus,
 		unsigned long long address, unsigned long long len)
 {
@@ -35,9 +51,9 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_cap(struct ndctl_bus *bus,
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_ARS_CAP;
+	cmd->get_firmware_status = get_ars_command_status;
 	cmd->size = size;
 	cmd->status = 1;
-	cmd->firmware_status = &cmd->ars_cap->status;
 	cmd->ars_cap->address = address;
 	cmd->ars_cap->length = len;
 
@@ -55,7 +71,7 @@ static bool __validate_ars_cap(struct ndctl_cmd *ars_cap)
 {
 	if (ars_cap->type != ND_CMD_ARS_CAP || ars_cap->status != 0)
 		return false;
-	if ((*ars_cap->firmware_status & ARS_STATUS_MASK) != 0)
+	if ((ars_cap->get_firmware_status(ars_cap) & ARS_STATUS_MASK) != 0)
 		return false;
 	return validate_clear_error(ars_cap);
 }
@@ -84,7 +100,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_start(struct ndctl_cmd *ars
 	if (!validate_ars_cap(ctx, ars_cap))
 		return NULL;
 
-	if (!(*ars_cap->firmware_status >> ARS_EXT_STATUS_SHIFT & type)) {
+	if (!(ars_cap->get_firmware_status(ars_cap) >> ARS_EXT_STATUS_SHIFT & type)) {
 		dbg(ctx, "ars_cap does not show requested type as supported\n");
 		return NULL;
 	}
@@ -97,9 +113,9 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_start(struct ndctl_cmd *ars
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_ARS_START;
+	cmd->get_firmware_status = get_ars_command_status;
 	cmd->size = size;
 	cmd->status = 1;
-	cmd->firmware_status = &cmd->ars_start->status;
 	cmd->ars_start->address = ars_cap->ars_cap->address;
 	cmd->ars_start->length = ars_cap->ars_cap->length;
 	cmd->ars_start->type = type;
@@ -145,9 +161,9 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_ars_status(struct ndctl_cmd *ar
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_ARS_STATUS;
+	cmd->get_firmware_status = get_ars_command_status;
 	cmd->size = size;
 	cmd->status = 1;
-	cmd->firmware_status = &cmd->ars_status->status;
 	cmd->ars_status->out_length = ars_cap_cmd->max_ars_out;
 
 	return cmd;
@@ -325,9 +341,9 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_clear_error(
 	ndctl_cmd_ref(clear_err);
 	clear_err->bus = bus;
 	clear_err->type = ND_CMD_CLEAR_ERROR;
+	clear_err->get_firmware_status = get_ars_command_status;
 	clear_err->size = size;
 	clear_err->status = 1;
-	clear_err->firmware_status = &clear_err->clear_err->status;
 	clear_err->clear_err->address = address;
 	clear_err->clear_err->length = len;
 
diff --git a/ndctl/lib/hpe1.c b/ndctl/lib/hpe1.c
index b26120e1d3e0..b5ee02608d31 100644
--- a/ndctl/lib/hpe1.c
+++ b/ndctl/lib/hpe1.c
@@ -23,6 +23,17 @@
 #define CMD_HPE1_SMART(_c) (CMD_HPE1(_c)->u.smart.data)
 #define CMD_HPE1_SMART_THRESH(_c) (CMD_HPE1(_c)->u.thresh.data)
 
+static u32 hpe1_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	switch (cmd->hpe1->gen.nd_command) {
+	case NDN_HPE1_CMD_SMART:
+		return cmd->hpe1->u.smart.status;
+	case NDN_HPE1_CMD_SMART_THRESHOLD:
+		return cmd->hpe1->u.thresh.status;
+	}
+	return -1U;
+}
+
 static struct ndctl_cmd *hpe1_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 {
 	struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
@@ -60,6 +71,7 @@ static struct ndctl_cmd *hpe1_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 	hpe1->gen.nd_size_in = offsetof(struct ndn_hpe1_smart, status);
 	hpe1->gen.nd_size_out = sizeof(hpe1->u.smart);
 	hpe1->u.smart.status = 3;
+	cmd->get_firmware_status = hpe1_get_firmware_status;
 
 	hpe1->u.smart.in_valid_flags = 0;
 	hpe1->u.smart.in_valid_flags |= NDN_HPE1_SMART_HEALTH_VALID;
@@ -70,8 +82,6 @@ static struct ndctl_cmd *hpe1_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 	hpe1->u.smart.in_valid_flags |= NDN_HPE1_SMART_SHUTDOWN_VALID;
 	hpe1->u.smart.in_valid_flags |= NDN_HPE1_SMART_VENDOR_VALID;
 
-	cmd->firmware_status = &hpe1->u.smart.status;
-
 	return cmd;
 }
 
@@ -285,8 +295,7 @@ static struct ndctl_cmd *hpe1_dimm_cmd_new_smart_threshold(struct ndctl_dimm *di
 	hpe1->gen.nd_size_in = offsetof(struct ndn_hpe1_smart_threshold, status);
 	hpe1->gen.nd_size_out = sizeof(hpe1->u.smart);
 	hpe1->u.thresh.status = 3;
-
-	cmd->firmware_status = &hpe1->u.thresh.status;
+	cmd->get_firmware_status = hpe1_get_firmware_status;
 
 	return cmd;
 }
diff --git a/ndctl/lib/hyperv.c b/ndctl/lib/hyperv.c
index 9b4fe122af2c..ba1b12111804 100644
--- a/ndctl/lib/hyperv.c
+++ b/ndctl/lib/hyperv.c
@@ -9,6 +9,11 @@
 #include "private.h"
 #include "hyperv.h"
 
+static u32 hyperv_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	return cmd->hyperv->u.status;
+}
+
 static bool hyperv_cmd_is_supported(struct ndctl_dimm *dimm, int cmd)
 {
 	/*
@@ -50,6 +55,7 @@ static struct ndctl_cmd *alloc_hyperv_cmd(struct ndctl_dimm *dimm,
 
 	cmd->dimm = dimm;
 	cmd->type = ND_CMD_CALL;
+	cmd->get_firmware_status = hyperv_get_firmware_status;
 	cmd->size = size;
 	cmd->status = 1;
 
@@ -58,7 +64,6 @@ static struct ndctl_cmd *alloc_hyperv_cmd(struct ndctl_dimm *dimm,
 	hyperv->gen.nd_command = command;
 	hyperv->gen.nd_size_out = sizeof(hyperv->u.health_info);
 
-	cmd->firmware_status = &hyperv->u.health_info.status;
 	return cmd;
 }
 
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index d684bac03fec..ebcefd8b5ad2 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -16,13 +16,49 @@
 #include <ndctl/libndctl.h>
 #include "private.h"
 
+static unsigned int intel_cmd_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	struct nd_pkg_intel *intel = cmd->intel;
+
+	switch (intel->gen.nd_command) {
+	case ND_INTEL_SMART:
+		return intel->smart.status;
+	case ND_INTEL_SMART_THRESHOLD:
+		return intel->thresh.status;
+	case ND_INTEL_SMART_SET_THRESHOLD:
+		return intel->set_thresh.status;
+	case ND_INTEL_SMART_INJECT:
+		return intel->inject.status;
+	case ND_INTEL_FW_GET_INFO:
+		return intel->info.status;
+	case ND_INTEL_FW_START_UPDATE:
+		return intel->start.status;
+	case ND_INTEL_FW_SEND_DATA: {
+		    struct nd_intel_fw_send_data *send = &intel->send;
+		    u32 status;
+
+		    /* the last dword after the payload is reserved for status */
+		    memcpy(&status, ((void *) send) + sizeof(*send) + send->length,
+				    sizeof(status));
+		    return status;
+	}
+	case ND_INTEL_FW_FINISH_UPDATE:
+		return intel->finish.status;
+	case ND_INTEL_FW_FINISH_STATUS_QUERY:
+		return intel->fquery.status;
+	case ND_INTEL_ENABLE_LSS_STATUS:
+		return intel->lss.status;
+	}
+	return -1U;
+}
+
 static int intel_cmd_xlat_firmware_status(struct ndctl_cmd *cmd)
 {
 	struct nd_pkg_intel *pkg = cmd->intel;
 	unsigned int status, ext_status;
 
-	status = (*cmd->firmware_status) & ND_INTEL_STATUS_MASK;
-	ext_status = (*cmd->firmware_status) & ND_INTEL_STATUS_EXTEND_MASK;
+	status = cmd->get_firmware_status(cmd) & ND_INTEL_STATUS_MASK;
+	ext_status = cmd->get_firmware_status(cmd) & ND_INTEL_STATUS_EXTEND_MASK;
 
 	/* Common statuses */
 	switch (status) {
@@ -91,6 +127,7 @@ static struct ndctl_cmd *alloc_intel_cmd(struct ndctl_dimm *dimm,
 	cmd->type = ND_CMD_CALL;
 	cmd->size = size;
 	cmd->status = 1;
+	cmd->get_firmware_status = intel_cmd_get_firmware_status;
 
 	*(cmd->intel) = (struct nd_pkg_intel) {
 		.gen = {
@@ -114,7 +151,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 			0, sizeof(cmd->intel->smart));
 	if (!cmd)
 		return NULL;
-	cmd->firmware_status = &cmd->intel->smart.status;
 
 	return cmd;
 }
@@ -269,7 +305,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_smart_threshold(
 			0, sizeof(cmd->intel->thresh));
 	if (!cmd)
 		return NULL;
-	cmd->firmware_status = &cmd->intel->thresh.status;
 
 	return cmd;
 }
@@ -299,7 +334,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_smart_set_threshold(
 	set_thresh->spares = thresh->spares;
 	set_thresh->media_temperature = thresh->media_temperature;
 	set_thresh->ctrl_temperature = thresh->ctrl_temperature;
-	cmd->firmware_status = &set_thresh->status;
 
 	return cmd;
 }
@@ -360,7 +394,6 @@ static struct ndctl_cmd *intel_new_smart_inject(struct ndctl_dimm *dimm)
 			offsetof(struct nd_intel_smart_inject, status), 4);
 	if (!cmd)
 		return NULL;
-	cmd->firmware_status = &cmd->intel->inject.status;
 
 	return cmd;
 }
@@ -468,7 +501,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_fw_get_info(struct ndctl_dimm *dimm)
 	if (!cmd)
 		return NULL;
 
-	cmd->firmware_status = &cmd->intel->info.status;
 	return cmd;
 }
 
@@ -540,7 +572,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_fw_start(struct ndctl_dimm *dimm)
 	if (!cmd)
 		return NULL;
 
-	cmd->firmware_status = &cmd->intel->start.status;
 	return cmd;
 }
 
@@ -583,9 +614,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_fw_send(struct ndctl_cmd *start,
 	cmd->intel->send.offset = offset;
 	cmd->intel->send.length = len;
 	memcpy(cmd->intel->send.data, data, len);
-	/* the last dword is reserved for status */
-	cmd->firmware_status =
-		(unsigned int *)(&cmd->intel->send.data[0] + len);
 	return cmd;
 }
 
@@ -602,7 +630,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_fw_finish(struct ndctl_cmd *start)
 
 	cmd->intel->finish.context = start->intel->start.context;
 	cmd->intel->finish.ctrl_flags = 0;
-	cmd->firmware_status = &cmd->intel->finish.status;
 	return cmd;
 }
 
@@ -619,7 +646,6 @@ static struct ndctl_cmd *intel_dimm_cmd_new_fw_abort(struct ndctl_cmd *start)
 
 	cmd->intel->finish.context = start->intel->start.context;
 	cmd->intel->finish.ctrl_flags = 1;
-	cmd->firmware_status = &cmd->intel->finish.status;
 	return cmd;
 }
 
@@ -636,7 +662,6 @@ intel_dimm_cmd_new_fw_finish_query(struct ndctl_cmd *start)
 		return NULL;
 
 	cmd->intel->fquery.context = start->intel->start.context;
-	cmd->firmware_status = &cmd->intel->fquery.status;
 	return cmd;
 }
 
@@ -704,7 +729,7 @@ intel_cmd_fw_xlat_extend_firmware_status(struct ndctl_cmd *cmd,
 static enum ND_FW_STATUS
 intel_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd)
 {
-	unsigned int status = *cmd->firmware_status;
+	unsigned int status = intel_cmd_get_firmware_status(cmd);
 
 	switch (status & ND_INTEL_STATUS_MASK) {
 	case ND_INTEL_STATUS_SUCCESS:
@@ -742,7 +767,6 @@ intel_dimm_cmd_new_lss(struct ndctl_dimm *dimm)
 		return NULL;
 
 	cmd->intel->lss.enable = 1;
-	cmd->firmware_status = &cmd->intel->lss.status;
 	return cmd;
 }
 
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 9ad1b7091dc0..97fd98545440 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -2506,6 +2506,23 @@ static struct nd_cmd_vendor_tail *to_vendor_tail(struct ndctl_cmd *cmd)
 	return tail;
 }
 
+static u32 cmd_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	switch (cmd->type) {
+	case ND_CMD_VENDOR:
+		return to_vendor_tail(cmd)->status;
+	case ND_CMD_GET_CONFIG_SIZE:
+		return cmd->get_size->status;
+	case ND_CMD_GET_CONFIG_DATA:
+		return cmd->get_data->status;
+	case ND_CMD_SET_CONFIG_DATA:
+		return *(u32 *) (cmd->cmd_buf
+				+ sizeof(struct nd_cmd_set_config_hdr)
+				+ cmd->iter.max_xfer);
+	}
+	return -1U;
+}
+
 NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_vendor_specific(
 		struct ndctl_dimm *dimm, unsigned int opcode, size_t input_size,
 		size_t output_size)
@@ -2535,7 +2552,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_vendor_specific(
 	cmd->status = 1;
 	cmd->vendor->opcode = opcode;
 	cmd->vendor->in_length = input_size;
-	cmd->firmware_status = &to_vendor_tail(cmd)->status;
+	cmd->get_firmware_status = cmd_get_firmware_status;
 	to_vendor_tail(cmd)->out_length = output_size;
 
 	return cmd;
@@ -2600,7 +2617,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_size(struct ndctl_dimm *di
 	cmd->type = ND_CMD_GET_CONFIG_SIZE;
 	cmd->size = size;
 	cmd->status = 1;
-	cmd->firmware_status = &cmd->get_size->status;
+	cmd->get_firmware_status = cmd_get_firmware_status;
 
 	return cmd;
 }
@@ -2641,7 +2658,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg
 	cmd->status = 1;
 	cmd->get_data->in_offset = 0;
 	cmd->get_data->in_length = cfg_size->get_size->max_xfer;
-	cmd->firmware_status = &cmd->get_data->status;
+	cmd->get_firmware_status = cmd_get_firmware_status;
 	cmd->iter.init_offset = 0;
 	cmd->iter.offset = &cmd->get_data->in_offset;
 	cmd->iter.xfer = &cmd->get_data->in_length;
@@ -2728,8 +2745,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cf
 	cmd->status = 1;
 	cmd->set_data->in_offset = cfg_read->iter.init_offset;
 	cmd->set_data->in_length = cfg_read->iter.max_xfer;
-	cmd->firmware_status = (u32 *) (cmd->cmd_buf
-		+ sizeof(struct nd_cmd_set_config_hdr) + cfg_read->iter.max_xfer);
+	cmd->get_firmware_status = cmd_get_firmware_status;
 	cmd->iter.init_offset = cfg_read->iter.init_offset;
 	cmd->iter.offset = &cmd->set_data->in_offset;
 	cmd->iter.xfer = &cmd->set_data->in_length;
@@ -2936,7 +2952,7 @@ static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 		dbg(ctx, "bus: %d dimm: %#x cmd: %s%s%s status: %d fw: %d (%s)\n",
 				bus->id, dimm ? ndctl_dimm_get_handle(dimm) : 0,
 				name, sub_name ? ":" : "", sub_name ? sub_name : "",
-				rc, *(cmd->firmware_status), rc < 0 ?
+				rc, cmd->get_firmware_status(cmd), rc < 0 ?
 				strerror(errno) : "success");
 		if (rc < 0)
 			return -errno;
@@ -2960,7 +2976,7 @@ static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 		if (iter->dir == READ)
 			memcpy(iter->total_buf + offset, iter->data,
 					*(cmd->iter.xfer) - rc);
-		if (*(cmd->firmware_status) || rc) {
+		if (cmd->get_firmware_status(cmd) || rc) {
 			rc = offset + *(cmd->iter.xfer) - rc;
 			break;
 		}
@@ -2970,7 +2986,7 @@ static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 			bus->id, dimm ? ndctl_dimm_get_handle(dimm) : 0,
 			name, sub_name ? ":" : "", sub_name ? sub_name : "",
 			iter->total_xfer, iter->max_xfer, rc,
-			*(cmd->firmware_status),
+			cmd->get_firmware_status(cmd),
 			rc < 0 ? strerror(errno) : "success");
 
 	return rc;
@@ -2986,6 +3002,11 @@ NDCTL_EXPORT int ndctl_cmd_submit(struct ndctl_cmd *cmd)
 	struct ndctl_bus *bus = cmd_to_bus(cmd);
 	struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus);
 
+	if (!cmd->get_firmware_status) {
+		err(ctx, "missing status retrieval\n");
+		return -EINVAL;
+	}
+
 	if (ioctl_cmd == 0) {
 		rc = -EINVAL;
 		goto out;
@@ -3054,7 +3075,7 @@ NDCTL_EXPORT int ndctl_cmd_get_status(struct ndctl_cmd *cmd)
 
 NDCTL_EXPORT unsigned int ndctl_cmd_get_firmware_status(struct ndctl_cmd *cmd)
 {
-	return *(cmd->firmware_status);
+	return cmd->get_firmware_status(cmd);
 }
 
 NDCTL_EXPORT const char *ndctl_region_get_devname(struct ndctl_region *region)
diff --git a/ndctl/lib/msft.c b/ndctl/lib/msft.c
index 19453cd86143..c060b1f2609e 100644
--- a/ndctl/lib/msft.c
+++ b/ndctl/lib/msft.c
@@ -22,6 +22,11 @@
 #define CMD_MSFT(_c) ((_c)->msft)
 #define CMD_MSFT_SMART(_c) (CMD_MSFT(_c)->u.smart.data)
 
+static u32 msft_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	return cmd->msft->u.smart.status;
+}
+
 static struct ndctl_cmd *msft_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 {
 	struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
@@ -58,8 +63,7 @@ static struct ndctl_cmd *msft_dimm_cmd_new_smart(struct ndctl_dimm *dimm)
 	msft->gen.nd_size_in = offsetof(struct ndn_msft_smart, status);
 	msft->gen.nd_size_out = sizeof(msft->u.smart);
 	msft->u.smart.status = 0;
-
-	cmd->firmware_status = &msft->u.smart.status;
+	cmd->get_firmware_status = msft_get_firmware_status;
 
 	return cmd;
 }
diff --git a/ndctl/lib/nfit.c b/ndctl/lib/nfit.c
index b10edb1943e8..f9fbe73f7446 100644
--- a/ndctl/lib/nfit.c
+++ b/ndctl/lib/nfit.c
@@ -15,6 +15,24 @@
 #include "private.h"
 #include <ndctl/libndctl-nfit.h>
 
+static u32 bus_get_firmware_status(struct ndctl_cmd *cmd)
+{
+	struct nd_cmd_bus *cmd_bus = cmd->cmd_bus;
+
+	switch (cmd_bus->gen.nd_command) {
+	case NFIT_CMD_TRANSLATE_SPA:
+		return cmd_bus->xlat_spa.status;
+	case NFIT_CMD_ARS_INJECT_SET:
+		return cmd_bus->err_inj.status;
+	case NFIT_CMD_ARS_INJECT_CLEAR:
+		return cmd_bus->err_inj_clr.status;
+	case NFIT_CMD_ARS_INJECT_GET:
+		return cmd_bus->err_inj_stat.status;
+	}
+
+	return -1U;
+}
+
 /**
  * ndctl_bus_is_nfit_cmd_supported - ask nfit command is supported on @bus.
  * @bus: ndctl_bus instance
@@ -54,15 +72,15 @@ static struct ndctl_cmd *ndctl_bus_cmd_new_translate_spa(struct ndctl_bus *bus)
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_CALL;
+	cmd->get_firmware_status = bus_get_firmware_status;
 	cmd->size = size;
 	cmd->status = 1;
-	pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0];
+	pkg = &cmd->cmd_bus->gen;
 	pkg->nd_command = NFIT_CMD_TRANSLATE_SPA;
 	pkg->nd_size_in = sizeof(unsigned long long);
 	pkg->nd_size_out = spa_length;
 	pkg->nd_fw_size = spa_length;
-	translate_spa = (struct nd_cmd_translate_spa *)&pkg->nd_payload[0];
-	cmd->firmware_status = &translate_spa->status;
+	translate_spa = &cmd->cmd_bus->xlat_spa;
 	translate_spa->translate_length = spa_length;
 
 	return cmd;
@@ -146,7 +164,6 @@ int ndctl_bus_nfit_translate_spa(struct ndctl_bus *bus,
 
 struct ndctl_cmd *ndctl_bus_cmd_new_err_inj(struct ndctl_bus *bus)
 {
-	struct nd_cmd_ars_err_inj *err_inj;
 	size_t size, cmd_length;
 	struct nd_cmd_pkg *pkg;
 	struct ndctl_cmd *cmd;
@@ -160,6 +177,7 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj(struct ndctl_bus *bus)
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_CALL;
+	cmd->get_firmware_status = bus_get_firmware_status;
 	cmd->size = size;
 	cmd->status = 1;
 	pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0];
@@ -167,15 +185,12 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj(struct ndctl_bus *bus)
 	pkg->nd_size_in = offsetof(struct nd_cmd_ars_err_inj, status);
 	pkg->nd_size_out = cmd_length - pkg->nd_size_in;
 	pkg->nd_fw_size = pkg->nd_size_out;
-	err_inj = (struct nd_cmd_ars_err_inj *)&pkg->nd_payload[0];
-	cmd->firmware_status = &err_inj->status;
 
 	return cmd;
 }
 
 struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_clr(struct ndctl_bus *bus)
 {
-	struct nd_cmd_ars_err_inj_clr *err_inj_clr;
 	size_t size, cmd_length;
 	struct nd_cmd_pkg *pkg;
 	struct ndctl_cmd *cmd;
@@ -189,6 +204,7 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_clr(struct ndctl_bus *bus)
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_CALL;
+	cmd->get_firmware_status = bus_get_firmware_status;
 	cmd->size = size;
 	cmd->status = 1;
 	pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0];
@@ -196,8 +212,6 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_clr(struct ndctl_bus *bus)
 	pkg->nd_size_in = offsetof(struct nd_cmd_ars_err_inj_clr, status);
 	pkg->nd_size_out = cmd_length - pkg->nd_size_in;
 	pkg->nd_fw_size = pkg->nd_size_out;
-	err_inj_clr = (struct nd_cmd_ars_err_inj_clr *)&pkg->nd_payload[0];
-	cmd->firmware_status = &err_inj_clr->status;
 
 	return cmd;
 }
@@ -205,7 +219,6 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_clr(struct ndctl_bus *bus)
 struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_stat(struct ndctl_bus *bus,
 	u32 buf_size)
 {
-	struct nd_cmd_ars_err_inj_stat *err_inj_stat;
 	size_t size, cmd_length;
 	struct nd_cmd_pkg *pkg;
 	struct ndctl_cmd *cmd;
@@ -220,6 +233,7 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_stat(struct ndctl_bus *bus,
 	cmd->bus = bus;
 	ndctl_cmd_ref(cmd);
 	cmd->type = ND_CMD_CALL;
+	cmd->get_firmware_status = bus_get_firmware_status;
 	cmd->size = size;
 	cmd->status = 1;
 	pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0];
@@ -227,8 +241,6 @@ struct ndctl_cmd *ndctl_bus_cmd_new_err_inj_stat(struct ndctl_bus *bus,
 	pkg->nd_size_in = 0;
 	pkg->nd_size_out = cmd_length + buf_size;
 	pkg->nd_fw_size = pkg->nd_size_out;
-	err_inj_stat = (struct nd_cmd_ars_err_inj_stat *)&pkg->nd_payload[0];
-	cmd->firmware_status = &err_inj_stat->status;
 
 	return cmd;
 }
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 16bf8f953828..3c121bd00437 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -32,6 +32,7 @@
 #include "hpe1.h"
 #include "msft.h"
 #include "hyperv.h"
+#include "libndctl-nfit.h"
 
 struct nvdimm_data {
 	struct ndctl_cmd *cmd_read;
@@ -233,7 +234,7 @@ struct ndctl_namespace {
  * @type: cmd number
  * @size: total size of the ndctl_cmd allocation
  * @status: negative if failed, 0 if success, > 0 if never submitted
- * @firmware_status: NFIT command output status code
+ * @get_firmware_status: per command firmware status field retrieval
  * @iter: iterator for multi-xfer commands
  * @source: source cmd of an inherited iter.total_buf
  *
@@ -250,7 +251,7 @@ struct ndctl_cmd {
 	int type;
 	int size;
 	int status;
-	u32 *firmware_status;
+	u32 (*get_firmware_status)(struct ndctl_cmd *cmd);
 	struct ndctl_cmd_iter {
 		u32 init_offset;
 		u32 *offset;
@@ -268,6 +269,7 @@ struct ndctl_cmd {
 		struct nd_cmd_ars_status ars_status[0];
 		struct nd_cmd_clear_error clear_err[0];
 		struct nd_cmd_pkg pkg[0];
+		struct nd_cmd_bus cmd_bus[0];
 		struct ndn_pkg_hpe1 hpe1[0];
 		struct ndn_pkg_msft msft[0];
 		struct nd_pkg_hyperv hyperv[0];
@@ -341,6 +343,7 @@ struct ndctl_dimm_ops {
 	struct ndctl_cmd *(*new_ack_shutdown_count)(struct ndctl_dimm *);
 	int (*fw_update_supported)(struct ndctl_dimm *);
 	int (*xlat_firmware_status)(struct ndctl_cmd *);
+	u32 (*get_firmware_status)(struct ndctl_cmd *);
 };
 
 extern struct ndctl_dimm_ops * const intel_dimm_ops;
diff --git a/ndctl/libndctl-nfit.h b/ndctl/libndctl-nfit.h
index d5335c23d28b..8c4f72dfa7ec 100644
--- a/ndctl/libndctl-nfit.h
+++ b/ndctl/libndctl-nfit.h
@@ -17,6 +17,7 @@
 #define __LIBNDCTL_NFIT_H__
 
 #include <linux/types.h>
+#include <ndctl/ndctl.h>
 
 /*
  * libndctl-nfit.h : definitions for NFIT related commands/functions.
@@ -87,6 +88,16 @@ struct nd_cmd_ars_err_inj_stat {
 	} __attribute__((packed)) record[0];
 } __attribute__((packed));
 
+struct nd_cmd_bus {
+	struct nd_cmd_pkg gen;
+	union {
+		struct nd_cmd_ars_err_inj_stat err_inj_stat;
+		struct nd_cmd_ars_err_inj_clr err_inj_clr;
+		struct nd_cmd_ars_err_inj err_inj;
+		struct nd_cmd_translate_spa xlat_spa;
+	};
+};
+
 int ndctl_bus_is_nfit_cmd_supported(struct ndctl_bus *bus, int cmd);
 
 #endif /* __LIBNDCTL_NFIT_H__ */
_______________________________________________
Linux-nvdimm mailing list -- linux-nvdimm@lists.01.org
To unsubscribe send an email to linux-nvdimm-leave@lists.01.org

  parent reply	other threads:[~2020-02-29 20:38 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-29 20:20 [ndctl PATCH 00/36] Multiple topics / backlog for v68 Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 01/36] ndctl/list: Add 'target_node' to region and namespace verbose listings Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 02/36] ndctl/docs: Fix mailing list sign-up link Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 03/36] ndctl/list: Drop named list objects from verbose listing Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 04/36] daxctl/list: Avoid memory operations without resource data Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 05/36] ndctl/build: Fix distcheck Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 06/36] ndctl/namespace: Fix destroy-namespace accounting relative to seed devices Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 07/36] ndctl/region: Support ndctl_region_{get, set}_align() Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 08/36] ndctl/namespace: Emit better errors on failure Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 09/36] ndctl/namespace: Check for region alignment violations Dan Williams
2020-02-29 20:20 ` [ndctl PATCH 10/36] ndctl/util: Up-level is_power_of_2() and introduce IS_ALIGNED Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 11/36] ndctl/namespace: Validate resource alignment for dax-mode namespaces Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 12/36] ndctl/namespace: Add read-infoblock command Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 13/36] ndctl/test: Update dax-dev to handle multiple e820 ranges Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 14/36] ndctl/namespace: Always zero info-blocks Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 15/36] ndctl/namespace: Disable autorecovery of create-namespace failures Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 16/36] ndctl/build: Fix EXTRA_DIST already defined errors Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 17/36] ndctl/test: Checkout device-mapper + dax operation Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 18/36] ndctl/test: Exercise sub-section sized namespace creation/deletion Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 19/36] ndctl/namespace: Kill off the legacy mode names Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 20/36] ndctl/namespace: Introduce mode-to-name and name-to-mode helpers Dan Williams
2020-02-29 20:21 ` [ndctl PATCH 21/36] ndctl/namespace: Validate namespace size within validate_namespace_options() Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 22/36] ndctl/namespace: Clarify 16M minimum size requirement Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 23/36] ndctl/test: Regression test 'failed to track' Dan Williams
2020-02-29 20:22 ` Dan Williams [this message]
2020-02-29 20:22 ` [ndctl PATCH 25/36] ndctl/dimm: Rework iteration to drop unaligned pointers Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 26/36] ndctl/test: Fix typos / loss of tpm.handle in security test Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 27/36] ndctl/test: Relax dax_pmem_compat requirement Dan Williams
2020-03-03 13:28   ` Jan Kara
2020-03-03 21:05     ` Dan Williams
2020-03-03 22:58   ` [ndctl PATCH v2 1/2] ndctl/test: Cleanup test-vs-production nvdimm module detection Dan Williams
2020-03-04 12:44     ` Jan Kara
2020-03-03 22:58   ` [ndctl PATCH v2 2/2] ndctl/test: Relax dax_pmem_compat requirement Dan Williams
2020-03-04 12:44     ` Jan Kara
2020-02-29 20:22 ` [ndctl PATCH 28/36] ndctl/namespace: Fix namespace-action vs namespace-mode confusion Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 29/36] ndctl/namespace: Update 'pfn' infoblock definition Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 30/36] ndctl/util: Return 0 for NULL arguments to parse_size64() Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 31/36] ndctl/namespace: Fix read-info-block vs read-infoblock Dan Williams
2020-02-29 20:22 ` [ndctl PATCH 32/36] ndctl/namespace: Parse infoblocks from stdin Dan Williams
2020-02-29 20:23 ` [ndctl PATCH 33/36] ndctl/namespace: Add write-infoblock command Dan Williams
2020-02-29 20:23 ` [ndctl PATCH 34/36] ndctl/list: Add option to list configured + disabled namespaces Dan Williams
2020-02-29 20:23 ` [ndctl PATCH 35/36] ndctl/lib/namespace: Fix resource retrieval after size change Dan Williams
2020-02-29 20:23 ` [ndctl PATCH 36/36] ndctl/test: Regression test misaligned namespaces Dan Williams
2020-03-19  4:13 ` [ndctl PATCH 00/36] Multiple topics / backlog for v68 Verma, Vishal L

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=158300773196.2141307.16404460619761697075.stgit@dwillia2-desk3.amr.corp.intel.com \
    --to=dan.j.williams@intel.com \
    --cc=linux-nvdimm@lists.01.org \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.