Skip to content

Commit 5be98d6

Browse files
sc108-leeigaw
authored andcommitted
mi: Add ISH bit (admin command cflags)
Add ish bit for mi admin commands that access media Spec NVM-Express-Management-Interface-Specification -Revision-2.1-2025.08.01-Ratified Figure 136: NVMe Admin Command Request Description Command Flags (CFLGS): Bit 2 : Ignore Shutdown (ISH) This bit shall have no effect on the value of the CSTS.SHST field. (193 page from spec) If an NVMe Admin Command does not require access to media, then the ISH bit shall have no effect on the processing of that NVMe Admin Command. spec NVM-Express-Base-Specification-Revision-2.3-2025.08.01-Ratified Figure 84: Admin Commands Permitted to Return a Status Code of Admin Command Media Not Ready From Figure 84, we can assume that below Admin commands access media Capacity Management, Device Self-test, Firmware Commit, Firmware Image Download, Get LBA Status, Get Log Page, Namespace Attachment, Namespace Management, Format NVM, Sanitize, Sanitize Namespace, Security Receive, Security Send, Vendor Specific Signed-off-by: Steven Seungcheol Lee <[email protected]> Reported-by: Hojin Ahn <[email protected]>
1 parent 0cfa413 commit 5be98d6

5 files changed

Lines changed: 191 additions & 24 deletions

File tree

libnvme/src/nvme/ioctl.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
/**
5353
* struct nvme_passthru_cmd - nvme passthrough command structure
5454
* @opcode: Operation code, see &enum nvme_io_opcodes and &enum nvme_admin_opcodes
55-
* @flags: Not supported: intended for command flags (eg: SGL, FUSE)
55+
* @flags: Supported only for NVMe-MI
5656
* @rsvd1: Reserved for future use
5757
* @nsid: Namespace Identifier, or Fabrics type
5858
* @cdw2: Command Dword 2 (no spec defined use)
@@ -440,6 +440,8 @@ enum nvme_cmd_dword_fields {
440440
NVME_COPY_CDW15_LBAT_MASK = 0xffff,
441441
NVME_COPY_CDW15_LBATM_SHIFT = 16,
442442
NVME_COPY_CDW15_LBATM_MASK = 0xffff,
443+
NVME_MI_ADMIN_CFLAGS_ISH_SHIFT = 2,
444+
NVME_MI_ADMIN_CFLAGS_ISH_MASK = 0x1,
443445
};
444446

445447
#define NVME_FIELD_ENCODE(value, shift, mask) \
@@ -7082,4 +7084,20 @@ nvme_get_features_simple(struct nvme_transport_handle *hdl, __u8 fid,
70827084
*result = cmd.result;
70837085
return err;
70847086
}
7087+
7088+
/**
7089+
* nvme_init_mi_cmd_flags() - Initialize command flags for NVMe-MI
7090+
* @cmd: Passthru command to use
7091+
* @ish: Ignore Shutdown (for NVMe-MI command)
7092+
*
7093+
* Initializes the passthru command flags
7094+
*/
7095+
static inline void
7096+
nvme_init_mi_cmd_flags(struct nvme_passthru_cmd *cmd, bool ish)
7097+
{
7098+
cmd->flags = NVME_FIELD_ENCODE(ish,
7099+
NVME_MI_ADMIN_CFLAGS_ISH_SHIFT,
7100+
NVME_MI_ADMIN_CFLAGS_ISH_MASK);
7101+
}
7102+
70857103
#endif /* _LIBNVME_IOCTL_H */

libnvme/src/nvme/linux.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -229,13 +229,17 @@ bool nvme_transport_handle_is_mi(struct nvme_transport_handle *hdl)
229229
return hdl->type == NVME_TRANSPORT_HANDLE_TYPE_MI;
230230
}
231231

232-
int nvme_fw_download_seq(struct nvme_transport_handle *hdl, __u32 size,
233-
__u32 xfer, __u32 offset, void *buf)
232+
int nvme_fw_download_seq(struct nvme_transport_handle *hdl, bool ish,
233+
__u32 size, __u32 xfer, __u32 offset, void *buf)
234234
{
235235
struct nvme_passthru_cmd cmd;
236236
void *data = buf;
237237
int err = 0;
238238

239+
if (ish && nvme_transport_handle_is_mi(hdl)) {
240+
nvme_init_mi_cmd_flags(&cmd, ish);
241+
}
242+
239243
while (size > 0) {
240244
err = nvme_init_fw_download(&cmd, data, MIN(xfer, size), offset);
241245
if (err)
@@ -525,13 +529,16 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct
525529
return 0;
526530
}
527531

528-
static int nvme_ns_attachment(struct nvme_transport_handle *hdl, __u32 nsid,
529-
__u16 num_ctrls, __u16 *ctrlist, bool attach)
532+
static int nvme_ns_attachment(struct nvme_transport_handle *hdl, bool ish,
533+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach)
530534
{
531535
struct nvme_ctrl_list cntlist = { 0 };
532536
struct nvme_passthru_cmd cmd;
533537

534538
nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist);
539+
if (ish && nvme_transport_handle_is_mi(hdl))
540+
nvme_init_mi_cmd_flags(&cmd, ish);
541+
535542
if (attach)
536543
nvme_init_ns_attach_ctrls(&cmd, nsid, &cntlist);
537544
else
@@ -540,16 +547,16 @@ static int nvme_ns_attachment(struct nvme_transport_handle *hdl, __u32 nsid,
540547
return nvme_submit_admin_passthru(hdl, &cmd);
541548
}
542549

543-
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid,
544-
__u16 num_ctrls, __u16 *ctrlist)
550+
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, bool ish,
551+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist)
545552
{
546-
return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, true);
553+
return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, true);
547554
}
548555

549-
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid,
550-
__u16 num_ctrls, __u16 *ctrlist)
556+
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish,
557+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist)
551558
{
552-
return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, false);
559+
return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, false);
553560
}
554561

555562
size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,

libnvme/src/nvme/linux.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
/**
2525
* nvme_fw_download_seq() - Firmware download sequence
2626
* @hdl: Transport handle
27+
* @ish: Ignore Shutdown (for NVMe-MI command)
2728
* @size: Total size of the firmware image to transfer
2829
* @xfer: Maximum size to send with each partial transfer
2930
* @offset: Starting offset to send with this firmware download
@@ -32,8 +33,8 @@
3233
* Return: 0 on success, the nvme command status if a response was
3334
* received (see &enum nvme_status_field) or a negative error otherwise.
3435
*/
35-
int nvme_fw_download_seq(struct nvme_transport_handle *hdl, __u32 size, __u32 xfer, __u32 offset,
36-
void *buf);
36+
int nvme_fw_download_seq(struct nvme_transport_handle *hdl, bool ish,
37+
__u32 size, __u32 xfer, __u32 offset, void *buf);
3738

3839
/**
3940
* nvme_set_etdas() - Set the Extended Telemetry Data Area 4 Supported bit
@@ -193,26 +194,30 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct
193194
/**
194195
* nvme_namespace_attach_ctrls() - Attach namespace to controller(s)
195196
* @hdl: Transport handle
197+
* @ish: Ignore Shutdown (for NVMe-MI command)
196198
* @nsid: Namespace ID to attach
197199
* @num_ctrls: Number of controllers in ctrlist
198200
* @ctrlist: List of controller IDs to perform the attach action
199201
*
200202
* Return: 0 on success, the nvme command status if a response was
201203
* received (see &enum nvme_status_field) or a negative error otherwise.
202204
*/
203-
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
205+
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, bool ish,
206+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
204207

205208
/**
206209
* nvme_namespace_detach_ctrls() - Detach namespace from controller(s)
207210
* @hdl: Transport handle
211+
* @ish: Ignore Shutdown (for NVMe-MI command)
208212
* @nsid: Namespace ID to detach
209213
* @num_ctrls: Number of controllers in ctrlist
210214
* @ctrlist: List of controller IDs to perform the detach action
211215
*
212216
* Return: 0 on success, the nvme command status if a response was
213217
* received (see &enum nvme_status_field) or a negative error otherwise.
214218
*/
215-
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
219+
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish,
220+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
216221

217222
/**
218223
* nvme_open() - Open an nvme controller or namespace device

libnvme/src/nvme/mi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,7 @@ int nvme_mi_admin_admin_passthru(struct nvme_transport_handle *hdl,
896896
}
897897

898898
nvme_mi_admin_init_req(hdl->ep, &req, &req_hdr, hdl->id, cmd->opcode);
899+
req_hdr.flags = cmd->flags;
899900
req_hdr.cdw1 = cpu_to_le32(cmd->nsid);
900901
req_hdr.cdw2 = cpu_to_le32(cmd->cdw2);
901902
req_hdr.cdw3 = cpu_to_le32(cmd->cdw3);
@@ -909,7 +910,7 @@ int nvme_mi_admin_admin_passthru(struct nvme_transport_handle *hdl,
909910
if (cmd->data_len != 0) {
910911
req_hdr.dlen = cpu_to_le32(cmd->data_len);
911912
/* Bit 0 set to 1 means DLEN contains a value */
912-
req_hdr.flags = 0x1;
913+
req_hdr.flags |= 0x1;
913914
}
914915

915916
if (has_write_data) {

0 commit comments

Comments
 (0)