diff --git a/libnvme/src/nvme/ioctl.h b/libnvme/src/nvme/ioctl.h index 9f27307584..f52e404c91 100644 --- a/libnvme/src/nvme/ioctl.h +++ b/libnvme/src/nvme/ioctl.h @@ -52,7 +52,7 @@ /** * struct nvme_passthru_cmd - nvme passthrough command structure * @opcode: Operation code, see &enum nvme_io_opcodes and &enum nvme_admin_opcodes - * @flags: Not supported: intended for command flags (eg: SGL, FUSE) + * @flags: Supported only for NVMe-MI * @rsvd1: Reserved for future use * @nsid: Namespace Identifier, or Fabrics type * @cdw2: Command Dword 2 (no spec defined use) @@ -440,6 +440,8 @@ enum nvme_cmd_dword_fields { NVME_COPY_CDW15_LBAT_MASK = 0xffff, NVME_COPY_CDW15_LBATM_SHIFT = 16, NVME_COPY_CDW15_LBATM_MASK = 0xffff, + NVME_MI_ADMIN_CFLAGS_ISH_SHIFT = 2, + NVME_MI_ADMIN_CFLAGS_ISH_MASK = 0x1, }; #define NVME_FIELD_ENCODE(value, shift, mask) \ @@ -7082,4 +7084,20 @@ nvme_get_features_simple(struct nvme_transport_handle *hdl, __u8 fid, *result = cmd.result; return err; } + +/** + * nvme_init_mi_cmd_flags() - Initialize command flags for NVMe-MI + * @cmd: Passthru command to use + * @ish: Ignore Shutdown (for NVMe-MI command) + * + * Initializes the passthru command flags + */ +static inline void +nvme_init_mi_cmd_flags(struct nvme_passthru_cmd *cmd, bool ish) +{ + cmd->flags = NVME_FIELD_ENCODE(ish, + NVME_MI_ADMIN_CFLAGS_ISH_SHIFT, + NVME_MI_ADMIN_CFLAGS_ISH_MASK); +} + #endif /* _LIBNVME_IOCTL_H */ diff --git a/libnvme/src/nvme/linux.c b/libnvme/src/nvme/linux.c index 2c80512a78..ec52f0d94b 100644 --- a/libnvme/src/nvme/linux.c +++ b/libnvme/src/nvme/linux.c @@ -229,13 +229,17 @@ bool nvme_transport_handle_is_mi(struct nvme_transport_handle *hdl) return hdl->type == NVME_TRANSPORT_HANDLE_TYPE_MI; } -int nvme_fw_download_seq(struct nvme_transport_handle *hdl, __u32 size, - __u32 xfer, __u32 offset, void *buf) +int nvme_fw_download_seq(struct nvme_transport_handle *hdl, bool ish, + __u32 size, __u32 xfer, __u32 offset, void *buf) { struct nvme_passthru_cmd cmd; void *data = buf; int err = 0; + if (ish && nvme_transport_handle_is_mi(hdl)) { + nvme_init_mi_cmd_flags(&cmd, ish); + } + while (size > 0) { err = nvme_init_fw_download(&cmd, data, MIN(xfer, size), offset); if (err) @@ -525,13 +529,16 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct return 0; } -static int nvme_ns_attachment(struct nvme_transport_handle *hdl, __u32 nsid, - __u16 num_ctrls, __u16 *ctrlist, bool attach) +static int nvme_ns_attachment(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach) { struct nvme_ctrl_list cntlist = { 0 }; struct nvme_passthru_cmd cmd; nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist); + if (ish && nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + if (attach) nvme_init_ns_attach_ctrls(&cmd, nsid, &cntlist); else @@ -540,16 +547,16 @@ static int nvme_ns_attachment(struct nvme_transport_handle *hdl, __u32 nsid, return nvme_submit_admin_passthru(hdl, &cmd); } -int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, - __u16 num_ctrls, __u16 *ctrlist) +int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) { - return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, true); + return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, true); } -int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, - __u16 num_ctrls, __u16 *ctrlist) +int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid, __u16 num_ctrls, __u16 *ctrlist) { - return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, false); + return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, false); } size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl, diff --git a/libnvme/src/nvme/linux.h b/libnvme/src/nvme/linux.h index 45c2e6da07..10e2205034 100644 --- a/libnvme/src/nvme/linux.h +++ b/libnvme/src/nvme/linux.h @@ -24,6 +24,7 @@ /** * nvme_fw_download_seq() - Firmware download sequence * @hdl: Transport handle + * @ish: Ignore Shutdown (for NVMe-MI command) * @size: Total size of the firmware image to transfer * @xfer: Maximum size to send with each partial transfer * @offset: Starting offset to send with this firmware download @@ -32,8 +33,8 @@ * Return: 0 on success, the nvme command status if a response was * received (see &enum nvme_status_field) or a negative error otherwise. */ -int nvme_fw_download_seq(struct nvme_transport_handle *hdl, __u32 size, __u32 xfer, __u32 offset, - void *buf); +int nvme_fw_download_seq(struct nvme_transport_handle *hdl, bool ish, + __u32 size, __u32 xfer, __u32 offset, void *buf); /** * nvme_set_etdas() - Set the Extended Telemetry Data Area 4 Supported bit @@ -193,6 +194,7 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct /** * nvme_namespace_attach_ctrls() - Attach namespace to controller(s) * @hdl: Transport handle + * @ish: Ignore Shutdown (for NVMe-MI command) * @nsid: Namespace ID to attach * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the attach action @@ -200,11 +202,13 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct * Return: 0 on success, the nvme command status if a response was * received (see &enum nvme_status_field) or a negative error otherwise. */ -int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); +int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); /** * nvme_namespace_detach_ctrls() - Detach namespace from controller(s) * @hdl: Transport handle + * @ish: Ignore Shutdown (for NVMe-MI command) * @nsid: Namespace ID to detach * @num_ctrls: Number of controllers in ctrlist * @ctrlist: List of controller IDs to perform the detach action @@ -212,7 +216,8 @@ int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, _ * Return: 0 on success, the nvme command status if a response was * received (see &enum nvme_status_field) or a negative error otherwise. */ -int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); +int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid, __u16 num_ctrls, __u16 *ctrlist); /** * nvme_open() - Open an nvme controller or namespace device diff --git a/libnvme/src/nvme/mi.c b/libnvme/src/nvme/mi.c index 215471e2e7..4c74922f99 100644 --- a/libnvme/src/nvme/mi.c +++ b/libnvme/src/nvme/mi.c @@ -896,6 +896,7 @@ int nvme_mi_admin_admin_passthru(struct nvme_transport_handle *hdl, } nvme_mi_admin_init_req(hdl->ep, &req, &req_hdr, hdl->id, cmd->opcode); + req_hdr.flags = cmd->flags; req_hdr.cdw1 = cpu_to_le32(cmd->nsid); req_hdr.cdw2 = cpu_to_le32(cmd->cdw2); req_hdr.cdw3 = cpu_to_le32(cmd->cdw3); @@ -909,7 +910,7 @@ int nvme_mi_admin_admin_passthru(struct nvme_transport_handle *hdl, if (cmd->data_len != 0) { req_hdr.dlen = cpu_to_le32(cmd->data_len); /* Bit 0 set to 1 means DLEN contains a value */ - req_hdr.flags = 0x1; + req_hdr.flags |= 0x1; } if (has_write_data) { diff --git a/nvme.c b/nvme.c index f55a0b5953..56271e3688 100644 --- a/nvme.c +++ b/nvme.c @@ -258,6 +258,7 @@ static const char *nssd = "NSSD=0x64 register offset"; static const char *pmrctl = "PMRCTL=0xe04 register offset"; static const char *pmrmscl = "PMRMSCL=0xe14 register offset"; static const char *pmrmscu = "PMRMSCU=0xe18 register offset"; +static const char *ish = "Ignore Shutdown (for NVMe-MI command)"; struct nvme_config nvme_cfg = { .output_format = "normal", @@ -2305,6 +2306,7 @@ static int get_log(int argc, char **argv, struct command *acmd, struct plugin *p nvme_print_flags_t flags; struct config { + bool ish; __u32 namespace_id; __u8 log_id; __u32 log_len; @@ -2321,6 +2323,7 @@ static int get_log(int argc, char **argv, struct command *acmd, struct plugin *p }; struct config cfg = { + .ish = false, .namespace_id = NVME_NSID_ALL, .log_id = 0xff, .log_len = 0, @@ -2383,6 +2386,7 @@ static int get_log(int argc, char **argv, struct command *acmd, struct plugin *p }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), OPT_BYTE("log-id", 'i', &cfg.log_id, log_id, log_name), OPT_UINT("log-len", 'l', &cfg.log_len, log_len), @@ -2452,6 +2456,12 @@ static int get_log(int argc, char **argv, struct command *acmd, struct plugin *p }; nvme_init_get_log(&cmd, cfg.namespace_id, cfg.log_id, cfg.csi, log, cfg.log_len); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } cmd.cdw10 |= NVME_FIELD_ENCODE(cfg.lsp, NVME_LOG_CDW10_LSP_SHIFT, NVME_LOG_CDW10_LSP_MASK); @@ -2945,14 +2955,17 @@ static int delete_ns(int argc, char **argv, struct command *acmd, struct plugin int err; struct config { + bool ish; __u32 namespace_id; }; struct config cfg = { + .ish = false, .namespace_id = 0, }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id)); err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); @@ -2974,6 +2987,12 @@ static int delete_ns(int argc, char **argv, struct command *acmd, struct plugin } nvme_init_ns_mgmt_delete(&cmd, cfg.namespace_id); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); ns_mgmt_show_status(hdl, err, acmd->name, cfg.namespace_id); @@ -2995,18 +3014,21 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s const char *cont = "optional comma-sep controller id list"; struct config { + bool ish; __u32 nsid; char *cntlist; }; struct config cfg = { + .ish = false, .nsid = 0, .cntlist = "", }; NVME_ARGS(opts, - OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id), - OPT_LIST("controllers", 'c', &cfg.cntlist, cont)); + OPT_FLAG("ish", 'I', &cfg.ish, ish), + OPT_UINT("namespace-id", 'n', &cfg.nsid, namespace_id), + OPT_LIST("controllers", 'c', &cfg.cntlist, cont)); err = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (err) @@ -3059,6 +3081,12 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s else nvme_init_ns_detach_ctrls(&cmd, cfg.nsid, cntlist); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); ns_mgmt_show_status(hdl, err, acmd->name, cfg.nsid); @@ -3210,6 +3238,7 @@ static int create_ns(int argc, char **argv, struct command *acmd, struct plugin __u32 nsid; struct config { + bool ish; __u64 nsze; __u64 ncap; __u8 flbas; @@ -3232,6 +3261,7 @@ static int create_ns(int argc, char **argv, struct command *acmd, struct plugin }; struct config cfg = { + .ish = false, .nsze = 0, .ncap = 0, .flbas = 0xff, @@ -3254,6 +3284,7 @@ static int create_ns(int argc, char **argv, struct command *acmd, struct plugin }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_SUFFIX("nsze", 's', &cfg.nsze, nsze), OPT_SUFFIX("ncap", 'c', &cfg.ncap, ncap), OPT_BYTE("flbas", 'f', &cfg.flbas, flbas), @@ -3417,6 +3448,12 @@ static int create_ns(int argc, char **argv, struct command *acmd, struct plugin data->phndl[i] = cpu_to_le16(phndl[i]); nvme_init_ns_mgmt_create(&cmd, cfg.csi, data); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); nsid = cmd.result; ns_mgmt_show_status(hdl, err, acmd->name, nsid); @@ -4581,12 +4618,19 @@ static int wait_self_test(struct nvme_transport_handle *hdl) return 0; } -static void abort_self_test(struct nvme_transport_handle *hdl, __u32 nsid) +static void abort_self_test(struct nvme_transport_handle *hdl, bool ish, + __u32 nsid) { struct nvme_passthru_cmd cmd; int err; nvme_init_dev_self_test(&cmd, nsid, NVME_DST_STC_ABORT); + if (ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("Device self-test", err); @@ -4619,18 +4663,21 @@ static int device_self_test(int argc, char **argv, struct command *acmd, struct int err; struct config { + bool ish; __u32 namespace_id; __u8 stc; bool wait; }; struct config cfg = { + .ish = false, .namespace_id = NVME_NSID_ALL, .stc = NVME_ST_CODE_RESERVED, .wait = false, }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), OPT_BYTE("self-test-code", 's', &cfg.stc, self_test_code), OPT_FLAG("wait", 'w', &cfg.wait, wait)); @@ -4671,6 +4718,12 @@ static int device_self_test(int argc, char **argv, struct command *acmd, struct } nvme_init_dev_self_test(&cmd, cfg.namespace_id, cfg.stc); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("Device self-test", err); @@ -4691,7 +4744,7 @@ static int device_self_test(int argc, char **argv, struct command *acmd, struct check_abort: if (err == -EINTR) - abort_self_test(hdl, cfg.namespace_id); + abort_self_test(hdl, cfg.ish, cfg.namespace_id); return err; } @@ -4978,7 +5031,7 @@ static int get_feature(int argc, char **argv, struct command *acmd, * be aborted. */ static int fw_download_single(struct nvme_transport_handle *hdl, void *fw_buf, - unsigned int fw_len, uint32_t offset, + bool ish, unsigned int fw_len, uint32_t offset, uint32_t len, bool progress, bool ignore_ovr) { const unsigned int max_retries = 3; @@ -4991,6 +5044,9 @@ static int fw_download_single(struct nvme_transport_handle *hdl, void *fw_buf, offset, fw_len, (int)(100 * offset / fw_len)); } + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + for (try = 0; try < max_retries; try++) { if (try > 0) { fprintf(stderr, "retrying offset %x (%u/%u)\n", @@ -5090,6 +5146,7 @@ static int fw_download(int argc, char **argv, struct command *acmd, struct plugi struct config { char *fw; + bool ish; __u32 xfer; __u32 offset; bool progress; @@ -5098,6 +5155,7 @@ static int fw_download(int argc, char **argv, struct command *acmd, struct plugi struct config cfg = { .fw = "", + .ish = false, .xfer = 0, .offset = 0, .progress = false, @@ -5106,6 +5164,7 @@ static int fw_download(int argc, char **argv, struct command *acmd, struct plugi NVME_ARGS(opts, OPT_FILE("fw", 'f', &cfg.fw, fw), + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("xfer", 'x', &cfg.xfer, xfer), OPT_UINT("offset", 'O', &cfg.offset, offset), OPT_FLAG("progress", 'p', &cfg.progress, progress), @@ -5169,10 +5228,14 @@ static int fw_download(int argc, char **argv, struct command *acmd, struct plugi return err; } + if (cfg.ish && !nvme_transport_handle_is_mi(hdl)) { + printf("ISH is supported only for NVMe-MI\n"); + } + for (pos = 0; pos < fw_size; pos += cfg.xfer) { cfg.xfer = min(cfg.xfer, fw_size - pos); - err = fw_download_single(hdl, fw_buf + pos, fw_size, + err = fw_download_single(hdl, fw_buf + pos, cfg.ish, fw_size, cfg.offset + pos, cfg.xfer, cfg.progress, cfg.ignore_ovr); if (err) @@ -5282,18 +5345,21 @@ static int fw_commit(int argc, char **argv, struct command *acmd, struct plugin nvme_print_flags_t flags; struct config { + bool ish; __u8 slot; __u8 action; __u8 bpid; }; struct config cfg = { + .ish = false, .slot = 0, .action = 0, .bpid = 0, }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_BYTE("slot", 's', &cfg.slot, slot), OPT_BYTE("action", 'a', &cfg.action, action), OPT_BYTE("bpid", 'b', &cfg.bpid, bpid)); @@ -5322,6 +5388,12 @@ static int fw_commit(int argc, char **argv, struct command *acmd, struct plugin } nvme_init_fw_commit(&cmd, cfg.slot, cfg.action, cfg.bpid); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { fw_commit_err(err, cfg.action, cfg.slot, cfg.bpid); @@ -5451,6 +5523,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plug int err; struct config { + bool ish; bool no_dealloc; bool oipbp; __u8 owpass; @@ -5461,6 +5534,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plug }; struct config cfg = { + .ish = false, .no_dealloc = false, .oipbp = false, .owpass = 0, @@ -5480,6 +5554,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plug }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_FLAG("no-dealloc", 'd', &cfg.no_dealloc, no_dealloc_desc), OPT_FLAG("oipbp", 'i', &cfg.oipbp, oipbp_desc), OPT_BYTE("owpass", 'n', &cfg.owpass, owpass_desc), @@ -5533,7 +5608,13 @@ static int sanitize_cmd(int argc, char **argv, struct command *acmd, struct plug } nvme_init_sanitize_nvm(&cmd, cfg.sanact, cfg.ause, cfg.owpass, - cfg.oipbp, cfg.no_dealloc, cfg.emvs, cfg.ovrpat); + cfg.oipbp, cfg.no_dealloc, cfg.emvs, cfg.ovrpat); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("sanitize", err); @@ -5562,12 +5643,14 @@ static int sanitize_ns_cmd(int argc, char **argv, struct command *acmd, int err; struct config { + bool ish; bool ause; __u8 sanact; bool emvs; }; struct config cfg = { + .ish = false, .ause = false, .sanact = 0, .emvs = false, @@ -5583,6 +5666,7 @@ static int sanitize_ns_cmd(int argc, char **argv, struct command *acmd, }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_FLAG("ause", 'u', &cfg.ause, ause_desc), OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact), OPT_FLAG("emvs", 'e', &cfg.emvs, emvs_desc)); @@ -5620,6 +5704,12 @@ static int sanitize_ns_cmd(int argc, char **argv, struct command *acmd, } nvme_init_sanitize_ns(&cmd, cfg.sanact, cfg.ause, cfg.emvs); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_admin_cmd_err("sanitize ns", &cmd, err); @@ -6496,6 +6586,7 @@ static int format_cmd(int argc, char **argv, struct command *acmd, struct plugin int err, i; struct config { + bool ish; __u32 namespace_id; __u8 lbaf; __u8 ses; @@ -6508,6 +6599,7 @@ static int format_cmd(int argc, char **argv, struct command *acmd, struct plugin }; struct config cfg = { + .ish = false, .namespace_id = 0, .lbaf = 0xff, .ses = 0, @@ -6523,6 +6615,7 @@ static int format_cmd(int argc, char **argv, struct command *acmd, struct plugin timeout_ms = nvme_cfg.timeout; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id_desired), OPT_BYTE("lbaf", 'l', &cfg.lbaf, lbaf), OPT_BYTE("ses", 's', &cfg.ses, ses), @@ -6678,6 +6771,12 @@ static int format_cmd(int argc, char **argv, struct command *acmd, struct plugin nvme_init_format_nvm(&cmd, cfg.namespace_id, cfg.lbaf, cfg.mset, cfg.pi, cfg.pil, cfg.ses); cmd.timeout_ms = timeout_ms; + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("format", err); @@ -6899,6 +6998,7 @@ static int sec_send(int argc, char **argv, struct command *acmd, struct plugin * nvme_print_flags_t flags; struct config { + bool ish; __u32 namespace_id; char *file; __u8 nssf; @@ -6908,6 +7008,7 @@ static int sec_send(int argc, char **argv, struct command *acmd, struct plugin * }; struct config cfg = { + .ish = false, .namespace_id = 0, .file = "", .nssf = 0, @@ -6917,6 +7018,7 @@ static int sec_send(int argc, char **argv, struct command *acmd, struct plugin * }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), OPT_FILE("file", 'f', &cfg.file, file), OPT_BYTE("nssf", 'N', &cfg.nssf, nssf), @@ -6973,7 +7075,13 @@ static int sec_send(int argc, char **argv, struct command *acmd, struct plugin * } nvme_init_security_send(&cmd, cfg.namespace_id, cfg.nssf, cfg.spsp, - cfg.secp, cfg.tl, sec_buf, cfg.tl); + cfg.secp, cfg.tl, sec_buf, cfg.tl); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("security-send", err); @@ -8664,6 +8772,7 @@ static int sec_recv(int argc, char **argv, struct command *acmd, struct plugin * int err; struct config { + bool ish; __u32 namespace_id; __u32 size; __u8 nssf; @@ -8674,6 +8783,7 @@ static int sec_recv(int argc, char **argv, struct command *acmd, struct plugin * }; struct config cfg = { + .ish = false, .namespace_id = 0, .size = 0, .nssf = 0, @@ -8684,6 +8794,7 @@ static int sec_recv(int argc, char **argv, struct command *acmd, struct plugin * }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), OPT_UINT("size", 'x', &cfg.size, size), OPT_BYTE("nssf", 'N', &cfg.nssf, nssf), @@ -8708,6 +8819,13 @@ static int sec_recv(int argc, char **argv, struct command *acmd, struct plugin * return -ENOMEM; } + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } + nvme_init_security_receive(&cmd, cfg.namespace_id, cfg.nssf, cfg.spsp, cfg.secp, cfg.al, sec_buf, cfg.size); err = nvme_submit_admin_passthru(hdl, &cmd); @@ -8747,6 +8865,7 @@ static int get_lba_status(int argc, char **argv, struct command *acmd, int err; struct config { + bool ish; __u32 namespace_id; __u64 slba; __u32 mndw; @@ -8755,6 +8874,7 @@ static int get_lba_status(int argc, char **argv, struct command *acmd, }; struct config cfg = { + .ish = false, .namespace_id = 0, .slba = 0, .mndw = 0, @@ -8763,6 +8883,7 @@ static int get_lba_status(int argc, char **argv, struct command *acmd, }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_desired), OPT_SUFFIX("start-lba", 's', &cfg.slba, slba), OPT_UINT("max-dw", 'm', &cfg.mndw, mndw), @@ -8791,6 +8912,12 @@ static int get_lba_status(int argc, char **argv, struct command *acmd, nvme_init_get_lba_status(&cmd, cfg.namespace_id, cfg.slba, cfg.mndw, cfg.atype, cfg.rl, buf); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("get lba status", err); @@ -8822,6 +8949,7 @@ static int capacity_mgmt(int argc, char **argv, struct command *acmd, struct plu nvme_print_flags_t flags; struct config { + bool ish; __u8 operation; __u16 element_id; __u32 dw11; @@ -8829,6 +8957,7 @@ static int capacity_mgmt(int argc, char **argv, struct command *acmd, struct plu }; struct config cfg = { + .ish = false, .operation = 0xff, .element_id = 0xffff, .dw11 = 0, @@ -8836,6 +8965,7 @@ static int capacity_mgmt(int argc, char **argv, struct command *acmd, struct plu }; NVME_ARGS(opts, + OPT_FLAG("ish", 'I', &cfg.ish, ish), OPT_BYTE("operation", 'O', &cfg.operation, operation), OPT_SHRT("element-id", 'i', &cfg.element_id, element_id), OPT_UINT("cap-lower", 'l', &cfg.dw11, cap_lower), @@ -8859,6 +8989,12 @@ static int capacity_mgmt(int argc, char **argv, struct command *acmd, struct plu nvme_init_capacity_mgmt(&cmd, cfg.operation, cfg.element_id, (__u64)cfg.dw12 << 32 | cfg.dw11); + if (cfg.ish) { + if (nvme_transport_handle_is_mi(hdl)) + nvme_init_mi_cmd_flags(&cmd, ish); + else + printf("ISH is supported only for NVMe-MI\n"); + } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { nvme_show_err("capacity management", err);