@@ -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;
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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)
@@ -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;
}
@@ -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;
}
@@ -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;
@@ -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__ */
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(-)