Skip to content

Commit c56413e

Browse files
committed
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 a57c1b3 commit c56413e

12 files changed

Lines changed: 221 additions & 111 deletions

File tree

libnvme/examples/mi-mctp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ int do_security_info(nvme_mi_ep_t ep, int argc, char **argv)
565565
return -1;
566566
}
567567

568-
nvme_init_security_receive(&cmd, 0, 0, 0, 0, 0, data, data_len);
568+
nvme_init_security_receive(&cmd, false, 0, 0, 0, 0, 0, data, data_len);
569569
rc = nvme_submit_admin_passthru(hdl, &cmd);
570570
if (rc) {
571571
warnx("can't perform Security Receive command: rc %d", rc);

libnvme/src/nvme/ioctl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,10 @@ int nvme_submit_admin_passthru(struct nvme_transport_handle *hdl,
188188
{
189189
switch (hdl->type) {
190190
case NVME_TRANSPORT_HANDLE_TYPE_DIRECT:
191+
cmd->flags = 0; /*
192+
* Not supported: intended for command flags
193+
* (eg: SGL, FUSE)
194+
*/
191195
if (hdl->ioctl64)
192196
return nvme_submit_passthru64(hdl,
193197
NVME_IOCTL_ADMIN64_CMD, cmd);

libnvme/src/nvme/ioctl.h

Lines changed: 83 additions & 27 deletions
Large diffs are not rendered by default.

libnvme/src/nvme/linux.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -229,15 +229,15 @@ 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

239239
while (size > 0) {
240-
err = nvme_init_fw_download(&cmd, data, MIN(xfer, size), offset);
240+
err = nvme_init_fw_download(&cmd, ish, data, MIN(xfer, size), offset);
241241
if (err)
242242
break;
243243
err = nvme_submit_admin_passthru(hdl, &cmd);
@@ -525,31 +525,31 @@ int nvme_get_lba_status_log(struct nvme_transport_handle *hdl, bool rae, struct
525525
return 0;
526526
}
527527

528-
static int nvme_ns_attachment(struct nvme_transport_handle *hdl, __u32 nsid,
529-
__u16 num_ctrls, __u16 *ctrlist, bool attach)
528+
static int nvme_ns_attachment(struct nvme_transport_handle *hdl, bool ish,
529+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist, bool attach)
530530
{
531531
struct nvme_ctrl_list cntlist = { 0 };
532532
struct nvme_passthru_cmd cmd;
533533

534534
nvme_init_ctrl_list(&cntlist, num_ctrls, ctrlist);
535535
if (attach)
536-
nvme_init_ns_attach_ctrls(&cmd, nsid, &cntlist);
536+
nvme_init_ns_attach_ctrls(&cmd, ish, nsid, &cntlist);
537537
else
538-
nvme_init_ns_detach_ctrls(&cmd, nsid, &cntlist);
538+
nvme_init_ns_detach_ctrls(&cmd, ish, nsid, &cntlist);
539539

540540
return nvme_submit_admin_passthru(hdl, &cmd);
541541
}
542542

543-
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid,
544-
__u16 num_ctrls, __u16 *ctrlist)
543+
int nvme_namespace_attach_ctrls(struct nvme_transport_handle *hdl, bool ish,
544+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist)
545545
{
546-
return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, true);
546+
return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, true);
547547
}
548548

549-
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid,
550-
__u16 num_ctrls, __u16 *ctrlist)
549+
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish,
550+
__u32 nsid, __u16 num_ctrls, __u16 *ctrlist)
551551
{
552-
return nvme_ns_attachment(hdl, nsid, num_ctrls, ctrlist, false);
552+
return nvme_ns_attachment(hdl, ish, nsid, num_ctrls, ctrlist, false);
553553
}
554554

555555
size_t nvme_get_ana_log_len_from_id_ctrl(const struct nvme_id_ctrl *id_ctrl,

libnvme/src/nvme/linux.h

Lines changed: 7 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, __u32 size, __u32 xfer,
37+
__u32 offset, void *buf);
3738

3839
/**
3940
* nvme_set_etdas() - Set the Extended Telemetry Data Area 4 Supported bit
@@ -193,26 +194,28 @@ 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, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
204206

205207
/**
206208
* nvme_namespace_detach_ctrls() - Detach namespace from controller(s)
207209
* @hdl: Transport handle
210+
* @ish: Ignore Shutdown (for NVMe-MI command)
208211
* @nsid: Namespace ID to detach
209212
* @num_ctrls: Number of controllers in ctrlist
210213
* @ctrlist: List of controller IDs to perform the detach action
211214
*
212215
* Return: 0 on success, the nvme command status if a response was
213216
* received (see &enum nvme_status_field) or a negative error otherwise.
214217
*/
215-
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
218+
int nvme_namespace_detach_ctrls(struct nvme_transport_handle *hdl, bool ish, __u32 nsid, __u16 num_ctrls, __u16 *ctrlist);
216219

217220
/**
218221
* 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) {

libnvme/test/ioctl/misc.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static void test_format_nvm(void)
3434
int err;
3535

3636
set_mock_admin_cmds(&mock_admin_cmd, 1);
37-
nvme_init_format_nvm(&cmd, nsid, lbaf, mset, pi, pil, ses);
37+
nvme_init_format_nvm(&cmd, false, nsid, lbaf, mset, pi, pil, ses);
3838
err = nvme_submit_admin_passthru(test_hdl, &cmd);
3939
end_mock_cmds();
4040
check(err == 0, "returned error %d", err);
@@ -61,7 +61,7 @@ static void test_ns_mgmt(void)
6161

6262
arbitrary(&expected_data, sizeof(expected_data));
6363
set_mock_admin_cmds(&mock_admin_cmd, 1);
64-
nvme_init_ns_mgmt(&cmd, nsid, sel, csi, &data);
64+
nvme_init_ns_mgmt(&cmd, false, nsid, sel, csi, &data);
6565
err = nvme_submit_admin_passthru(test_hdl, &cmd);
6666
end_mock_cmds();
6767
check(err == 0, "returned error %d", err);
@@ -89,7 +89,7 @@ static void test_ns_mgmt_create(void)
8989

9090
arbitrary(&expected_data, sizeof(expected_data));
9191
set_mock_admin_cmds(&mock_admin_cmd, 1);
92-
nvme_init_ns_mgmt_create(&cmd, NVME_CSI_ZNS, &data);
92+
nvme_init_ns_mgmt_create(&cmd, false, NVME_CSI_ZNS, &data);
9393
err = nvme_submit_admin_passthru(test_hdl, &cmd);
9494
end_mock_cmds();
9595
check(err == 0, "returned error %d", err);
@@ -109,7 +109,7 @@ static void test_ns_mgmt_delete(void)
109109
int err;
110110

111111
set_mock_admin_cmds(&mock_admin_cmd, 1);
112-
nvme_init_ns_mgmt_delete(&cmd, TEST_NSID);
112+
nvme_init_ns_mgmt_delete(&cmd, false, TEST_NSID);
113113
err = nvme_submit_admin_passthru(test_hdl, &cmd);
114114
end_mock_cmds();
115115
check(err == 0, "returned error %d", err);
@@ -176,7 +176,7 @@ static void test_ns_attach(void)
176176

177177
arbitrary(&expected_ctrlist, sizeof(expected_ctrlist));
178178
set_mock_admin_cmds(&mock_admin_cmd, 1);
179-
nvme_init_ns_attach(&cmd, nsid, sel, &ctrlist);
179+
nvme_init_ns_attach(&cmd, false, nsid, sel, &ctrlist);
180180
err = nvme_submit_admin_passthru(test_hdl, &cmd);
181181
end_mock_cmds();
182182
check(err == 0, "returned error %d", err);
@@ -200,7 +200,7 @@ static void test_ns_attach_ctrls(void)
200200

201201
arbitrary(&ctrlist, sizeof(ctrlist));
202202
set_mock_admin_cmds(&mock_admin_cmd, 1);
203-
nvme_init_ns_attach_ctrls(&cmd, TEST_NSID, &ctrlist);
203+
nvme_init_ns_attach_ctrls(&cmd, false, TEST_NSID, &ctrlist);
204204
err = nvme_submit_admin_passthru(test_hdl, &cmd);
205205
end_mock_cmds();
206206
check(err == 0, "returned error %d", err);
@@ -221,7 +221,7 @@ static void test_ns_detach_ctrls(void)
221221

222222
arbitrary(&ctrlist, sizeof(ctrlist));
223223
set_mock_admin_cmds(&mock_admin_cmd, 1);
224-
nvme_init_ns_detach_ctrls(&cmd, TEST_NSID, &ctrlist);
224+
nvme_init_ns_detach_ctrls(&cmd, false, TEST_NSID, &ctrlist);
225225
err = nvme_submit_admin_passthru(test_hdl, &cmd);
226226
end_mock_cmds();
227227
check(err == 0, "returned error %d", err);
@@ -245,7 +245,7 @@ static void test_fw_download(void)
245245
arbitrary(&expected_data, sizeof(expected_data));
246246
memcpy(&data, &expected_data, sizeof(expected_data));
247247
set_mock_admin_cmds(&mock_admin_cmd, 1);
248-
err = nvme_init_fw_download(&cmd, data, data_len, offset);
248+
err = nvme_init_fw_download(&cmd, false, data, data_len, offset);
249249
check(err == 0, "download initializing error %d", err);
250250
err = nvme_submit_admin_passthru(test_hdl, &cmd);
251251
end_mock_cmds();
@@ -267,7 +267,7 @@ static void test_fw_commit(void)
267267
int err;
268268

269269
set_mock_admin_cmds(&mock_admin_cmd, 1);
270-
nvme_init_fw_commit(&cmd, slot, action, bpid);
270+
nvme_init_fw_commit(&cmd, false, slot, action, bpid);
271271
err = nvme_submit_admin_passthru(test_hdl, &cmd);
272272
end_mock_cmds();
273273
check(err == 0, "returned error %d", err);
@@ -297,7 +297,7 @@ static void test_security_send(void)
297297
arbitrary(&expected_data, sizeof(expected_data));
298298
memcpy(&data, &expected_data, sizeof(expected_data));
299299
set_mock_admin_cmds(&mock_admin_cmd, 1);
300-
nvme_init_security_send(&cmd, nsid, nssf, spsp, secp, tl,
300+
nvme_init_security_send(&cmd, false, nsid, nssf, spsp, secp, tl,
301301
data, data_len);
302302
err = nvme_submit_admin_passthru(test_hdl, &cmd);
303303
end_mock_cmds();
@@ -326,7 +326,7 @@ static void test_security_receive(void)
326326

327327
arbitrary(&expected_data, sizeof(expected_data));
328328
set_mock_admin_cmds(&mock_admin_cmd, 1);
329-
nvme_init_security_receive(&cmd, TEST_NSID, nssf, spsp, secp, al,
329+
nvme_init_security_receive(&cmd, false, TEST_NSID, nssf, spsp, secp, al,
330330
data, sizeof(data));
331331
err = nvme_submit_admin_passthru(test_hdl, &cmd);
332332
end_mock_cmds();
@@ -368,7 +368,7 @@ static void test_get_lba_status(void)
368368

369369
arbitrary(expected_lbas, lba_status_size);
370370
set_mock_admin_cmds(&mock_admin_cmd, 1);
371-
nvme_init_get_lba_status(&cmd, TEST_NSID, slba, mndw, atype,
371+
nvme_init_get_lba_status(&cmd, false, TEST_NSID, slba, mndw, atype,
372372
rl, lbas);
373373
err = nvme_submit_admin_passthru(test_hdl, &cmd);
374374
end_mock_cmds();
@@ -630,7 +630,7 @@ void test_capacity_mgmt(void)
630630
int err;
631631

632632
set_mock_admin_cmds(&mock_admin_cmd, 1);
633-
nvme_init_capacity_mgmt(&cmd, op, elid, cap);
633+
nvme_init_capacity_mgmt(&cmd, false, op, elid, cap);
634634
err = nvme_submit_admin_passthru(test_hdl, &cmd);
635635
end_mock_cmds();
636636
check(err == 0, "returned error %d", err);
@@ -685,7 +685,7 @@ static void test_sanitize_nvm(void)
685685
int err;
686686

687687
set_mock_admin_cmds(&mock_admin_cmd, 1);
688-
nvme_init_sanitize_nvm(&cmd, sanact, ause, owpass, oipbp, ndas,
688+
nvme_init_sanitize_nvm(&cmd, false, sanact, ause, owpass, oipbp, ndas,
689689
emvs, ovrpat);
690690
err = nvme_submit_admin_passthru(test_hdl, &cmd);
691691
end_mock_cmds();
@@ -706,7 +706,7 @@ static void test_dev_self_test(void)
706706
int err;
707707

708708
set_mock_admin_cmds(&mock_admin_cmd, 1);
709-
nvme_init_dev_self_test(&cmd, TEST_NSID, NVME_DST_STC_ABORT);
709+
nvme_init_dev_self_test(&cmd, false, TEST_NSID, NVME_DST_STC_ABORT);
710710
err = nvme_submit_admin_passthru(test_hdl, &cmd);
711711
end_mock_cmds();
712712
check(err == 0, "returned error %d", err);

0 commit comments

Comments
 (0)