From: Keith Busch Date: Tue, 2 Jun 2020 03:11:41 +0000 (-0700) Subject: zns and ns-types X-Git-Tag: v1.0-rc0~149 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a4c001a47663d0392d2cedfe33a8dec5654fc527;p=users%2Fsagi%2Flibnvme.git zns and ns-types Signed-off-by: Keith Busch --- diff --git a/.gitignore b/.gitignore index ab78bf1a..cbf80394 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ libnvme.pc test/register test/test test/cpp +test/zns examples/display-tree examples/display-columnar diff --git a/src/nvme/ioctl.c b/src/nvme/ioctl.c index 2c3a1216..d2bb0727 100644 --- a/src/nvme/ioctl.c +++ b/src/nvme/ioctl.c @@ -233,6 +233,7 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_NUMDU_SHIFT = 0, NVME_LOG_CDW11_LSI_SHIFT = 16, NVME_LOG_CDW14_UUID_SHIFT = 0, + NVME_LOG_CDW14_CSI_SHIFT = 24, NVME_LOG_CDW10_LID_MASK = 0xff, NVME_LOG_CDW10_LSP_MASK = 0xf, NVME_LOG_CDW10_RAE_MASK = 0x1, @@ -240,14 +241,17 @@ enum nvme_cmd_dword_fields { NVME_LOG_CDW11_NUMDU_MASK = 0xff, NVME_LOG_CDW11_LSI_MASK = 0xff, NVME_LOG_CDW14_UUID_MASK = 0x7f, + NVME_LOG_CDW14_CSI_MASK = 0xff, NVME_IDENTIFY_CDW10_CNS_SHIFT = 0, NVME_IDENTIFY_CDW10_CNTID_SHIFT = 16, NVME_IDENTIFY_CDW11_NVMSETID_SHIFT = 0, NVME_IDENTIFY_CDW14_UUID_SHIFT = 0, + NVME_IDENTIFY_CDW11_CSI_SHIFT = 24, NVME_IDENTIFY_CDW10_CNS_MASK = 0xff, NVME_IDENTIFY_CDW10_CNTID_MASK = 0xffff, NVME_IDENTIFY_CDW11_NVMSETID_MASK = 0xffff, NVME_IDENTIFY_CDW14_UUID_MASK = 0x7f, + NVME_IDENTIFY_CDW11_CSI_MASK = 0xff, NVME_NAMESPACE_ATTACH_CDW10_SEL_SHIFT = 0, NVME_NAMESPACE_ATTACH_CDW10_SEL_MASK = 0xf, NVME_NAMESPACE_MGMT_CDW10_SEL_SHIFT = 0, @@ -292,6 +296,16 @@ enum nvme_cmd_dword_fields { NVME_GET_LBA_STATUS_CDW13_ATYPE_SHIFT = 24, NVME_GET_LBA_STATUS_CDW13_RL_MASK = 0xffff, NVME_GET_LBA_STATUS_CDW13_ATYPE_MASK = 0xff, + NVME_ZNS_MGMT_SEND_SEL_SHIFT = 8, + NVME_ZNS_MGMT_SEND_SEL_MASK = 0x1, + NVME_ZNS_MGMT_SEND_ZSA_SHIFT = 0, + NVME_ZNS_MGMT_SEND_ZSA_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRA_SHIFT = 0, + NVME_ZNS_MGMT_RECV_ZRA_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRASF_SHIFT = 8, + NVME_ZNS_MGMT_RECV_ZRASF_MASK = 0xff, + NVME_ZNS_MGMT_RECV_ZRAS_FEAT_SHIFT = 16, + NVME_ZNS_MGMT_RECV_ZRAS_FEAT_MASK = 0x1, }; enum features { @@ -345,16 +359,19 @@ enum features { NVME_FEATURES_LBAS_LSIPI_SHIFT = 16, NVME_FEATURES_LBAS_LSIRI_MASK = 0xffff, NVME_FEATURES_LBAS_LSIPI_MASK = 0xffff, + NVME_FEATURES_IOCSP_IOCSCI_SHIFT = 0, + NVME_FEATURES_IOCSP_IOCSCI_MASK = 0xff, }; #define DW(value, prefix) ((value) & (prefix ## _MASK)) << prefix ## _SHIFT int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, - __u16 nvmsetid, __u8 uuidx, void *data) + __u16 nvmsetid, __u8 uuidx, __u8 csi, void *data) { __u32 cdw10 = DW(cntid, NVME_IDENTIFY_CDW10_CNTID) | DW(cns, NVME_IDENTIFY_CDW10_CNS); - __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID); + __u32 cdw11 = DW(nvmsetid, NVME_IDENTIFY_CDW11_NVMSETID) | + DW(csi, NVME_IDENTIFY_CDW11_CSI); __u32 cdw14 = DW(uuidx, NVME_IDENTIFY_CDW14_UUID); struct nvme_passthru_cmd cmd = { @@ -373,7 +390,8 @@ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, __u16 cntid, static int __nvme_identify(int fd, __u8 cns, __u32 nsid, void *data) { return nvme_identify(fd, cns, nsid, NVME_CNTLID_NONE, - NVME_NVMSETID_NONE, NVME_UUID_NONE, data); + NVME_NVMSETID_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + data); } int nvme_identify_ctrl(int fd, struct nvme_id_ctrl *id) @@ -413,7 +431,7 @@ int nvme_identify_ctrl_list(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, ctrlist); + NVME_UUID_NONE, NVME_CSI_NVM, ctrlist); } int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, @@ -421,7 +439,7 @@ int nvme_identify_nsid_ctrl_list(int fd, __u32 nsid, __u16 cntid, { return nvme_identify(fd, NVME_IDENTIFY_CNS_NS_CTRL_LIST, nsid, cntid, NVME_NVMSETID_NONE, NVME_UUID_NONE, - ctrlist); + NVME_CSI_NVM, ctrlist); } int nvme_identify_ns_descs(int fd, __u32 nsid, struct nvme_ns_id_desc *descs) @@ -435,7 +453,7 @@ int nvme_identify_nvmset_list(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_id_nvmset_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_NVMSET_LIST, NVME_NSID_NONE, NVME_CNTLID_NONE, nvmsetid, - NVME_UUID_NONE, nvmset); + NVME_UUID_NONE, NVME_CSI_NVM, nvmset); } int nvme_identify_primary_ctrl(int fd, __u16 cntid, @@ -444,7 +462,7 @@ int nvme_identify_primary_ctrl(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_primary_ctrl_cap) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_PRIMARY_CTRL_CAP, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, cap); + NVME_UUID_NONE, NVME_CSI_NVM, cap); } int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, @@ -453,7 +471,7 @@ int nvme_identify_secondary_ctrl_list(int fd, __u16 cntid, BUILD_ASSERT(sizeof(struct nvme_secondary_ctrl_list) == 4096); return nvme_identify(fd, NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST, NVME_NSID_NONE, cntid, NVME_NVMSETID_NONE, - NVME_UUID_NONE, list); + NVME_UUID_NONE, NVME_CSI_NVM, list); } int nvme_identify_ns_granularity(int fd, @@ -471,8 +489,47 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list) list); } +int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, data); +} + +int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data) +{ + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, csi, data); +} + +int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs) +{ + BUILD_ASSERT(sizeof(struct nvme_id_iocs) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_NVM, iocs); +} + +int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_id_ns) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_NS, nsid, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_ZNS, data); +} + +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_id_ctrl) == 4096); + return nvme_identify(fd, NVME_IDENTIFY_CNS_CSI_CTRL, NVME_NSID_NONE, + NVME_CNTLID_NONE, NVME_NVMSETID_NONE, + NVME_UUID_NONE, NVME_CSI_ZNS, data); +} + int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log) + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, + __u32 len, void *log) { __u32 numd = (len >> 2) - 1; __u16 numdu = numd >> 16, numdl = numd & 0xffff; @@ -485,7 +542,8 @@ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, DW(lsi, NVME_LOG_CDW11_LSI); __u32 cdw12 = lpo & 0xffffffff; __u32 cdw13 = lpo >> 32; - __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID); + __u32 cdw14 = DW(uuidx, NVME_LOG_CDW14_UUID) | + DW(csi, NVME_LOG_CDW14_CSI); struct nvme_passthru_cmd cmd = { .opcode = nvme_admin_get_log_page, @@ -506,7 +564,8 @@ static int __nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, bool rae, __u32 len, void *log) { return nvme_get_log(fd, lid, NVME_NSID_ALL, 0, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, NVME_UUID_NONE, rae, len, log); + NVME_LOG_LSI_NONE, NVME_UUID_NONE, NVME_CSI_NVM, + rae, len, log); } int nvme_get_log_error(int fd, unsigned nr_entries, bool rae, @@ -522,7 +581,7 @@ int nvme_get_log_smart(int fd, __u32 nsid, bool rae, struct nvme_smart_log *log) BUILD_ASSERT(sizeof(struct nvme_smart_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_SMART, nsid, 0, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, sizeof(*log), log); + NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), log); } int nvme_get_log_fw_slot(int fd, bool rae, struct nvme_firmware_slot *log) @@ -538,11 +597,14 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log) sizeof(*log), log); } -int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log) +int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, + struct nvme_cmd_effects_log *log) { BUILD_ASSERT(sizeof(struct nvme_cmd_effects_log) == 4096); - return __nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, false, - sizeof(*log), log); + return nvme_get_log(fd, NVME_LOG_LID_CMD_EFFECTS, NVME_NSID_ALL, 0, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, + NVME_UUID_NONE, csi, false, sizeof(*log), + log); } int nvme_get_log_device_self_test(int fd, struct nvme_self_test_log *log) @@ -562,15 +624,16 @@ int nvme_get_log_create_telemetry_host(int fd, struct nvme_telemetry_log *log) BUILD_ASSERT(sizeof(struct nvme_telemetry_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, 0, NVME_LOG_TELEM_HOST_LSP_CREATE, NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, sizeof(*log), log); + false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), + log); } int nvme_get_log_telemetry_host(int fd, __u64 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_HOST, NVME_NSID_NONE, offset, NVME_LOG_TELEM_HOST_LSP_RETAIN, - NVME_LOG_LSI_NONE, - false, NVME_UUID_NONE, len, log); + NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, + NVME_CSI_NVM, len, log); } int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, @@ -578,7 +641,7 @@ int nvme_get_log_telemetry_ctrl(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_TELEMETRY_CTRL, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_endurance_group(int fd, __u16 endgid, @@ -587,7 +650,7 @@ int nvme_get_log_endurance_group(int fd, __u16 endgid, BUILD_ASSERT(sizeof(struct nvme_endurance_group_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GROUP, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, endgid, false, NVME_UUID_NONE, - sizeof(*log), log); + NVME_CSI_NVM, sizeof(*log), log); } int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, @@ -596,7 +659,8 @@ int nvme_get_log_predictable_lat_nvmset(int fd, __u16 nvmsetid, BUILD_ASSERT(sizeof(struct nvme_nvmset_predictable_lat_log) == 512); return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_NVMSET, NVME_NSID_NONE, 0, NVME_LOG_LSP_NONE, nvmsetid, - false, NVME_UUID_NONE, sizeof(*log), log); + false, NVME_UUID_NONE, NVME_CSI_NVM, sizeof(*log), + log); } int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, @@ -604,7 +668,7 @@ int nvme_get_log_predictable_lat_event(int fd, bool rae, __u32 offset, { return nvme_get_log(fd, NVME_LOG_LID_PREDICTABLE_LAT_AGG, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, - rae, NVME_UUID_NONE, len, log); + rae, NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, @@ -612,7 +676,7 @@ int nvme_get_log_ana(int fd, enum nvme_log_ana_lsp lsp, bool rae, __u64 offset, { return nvme_get_log(fd, NVME_LOG_LID_ANA, NVME_NSID_NONE, offset, lsp,NVME_LOG_LSI_NONE, false, NVME_UUID_NONE, - len, log); + NVME_CSI_NVM, len, log); } int nvme_get_log_ana_groups(int fd, bool rae, __u32 len, @@ -627,7 +691,7 @@ int nvme_get_log_lba_status(int fd, bool rae, __u64 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_LBA_STATUS, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, @@ -635,14 +699,15 @@ int nvme_get_log_endurance_grp_evt(int fd, bool rae, __u32 offset, __u32 len, { return nvme_get_log(fd, NVME_LOG_LID_ENDURANCE_GRP_EVT, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, - NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, len, log); + NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE, + NVME_CSI_NVM, len, log); } int nvme_get_log_discovery(int fd, bool rae, __u32 offset, __u32 len, void *log) { return nvme_get_log(fd, NVME_LOG_LID_DISCOVER, NVME_NSID_NONE, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, - NVME_UUID_NONE, len, log); + NVME_UUID_NONE, NVME_CSI_NVM, len, log); } int nvme_get_log_reservation(int fd, bool rae, @@ -661,6 +726,15 @@ int nvme_get_log_sanitize(int fd, bool rae, log); } +int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, + struct nvme_zns_changed_zone_log *log) +{ + BUILD_ASSERT(sizeof(struct nvme_zns_changed_zone_log) == 4096); + return nvme_get_log(fd, NVME_LOG_LID_ZNS_CHANGED_ZONES, nsid, 0, + NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, rae, + NVME_UUID_NONE, NVME_CSI_ZNS, sizeof(*log), log); +} + int nvme_set_features(int fd, __u8 fid, __u32 nsid, __u32 cdw11, __u32 cdw12, bool save, __u8 uuidx, __u32 cdw15, __u32 data_len, void *data, __u32 *result) @@ -915,6 +989,14 @@ int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, save, result); } +int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save) +{ + __u32 value = DW(iocsi, NVME_FEATURES_IOCSP_IOCSCI); + + return __nvme_set_features(fd, NVME_FEAT_FID_IOCS_PROFILE, value, + save, NULL); +} + int nvme_get_features(int fd, enum nvme_features_id fid, __u32 nsid, enum nvme_get_features_sel sel, __u32 cdw11, __u8 uuidx, __u32 data_len, void *data, __u32 *result) @@ -1133,6 +1215,12 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, NVME_UUID_NONE, 0, NULL, result); } +int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, + __u32 *result) +{ + return __nvme_get_features(fd, NVME_FEAT_FID_IOCS_PROFILE, sel, result); +} + int nvme_format_nvm(int fd, __u32 nsid, __u8 lbaf, enum nvme_cmd_format_mset mset, enum nvme_cmd_format_pi pi, enum nvme_cmd_format_pil pil, enum nvme_cmd_format_ses ses, @@ -1713,3 +1801,78 @@ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, return nvme_submit_io_passthru(fd, &cmd, NULL); } + +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, + enum nvme_zns_send_action zsa, __u32 data_len, + void *data) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw13 = DW(!!select_all, NVME_ZNS_MGMT_SEND_SEL) | + DW(zsa, NVME_ZNS_MGMT_SEND_ZSA); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_zns_cmd_mgmt_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw13 = cdw13, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_recv_action zra, __u16 zrasf, + bool zras_feat, __u32 data_len, void *data) +{ + __u32 cdw10 = slba & 0xffffffff; + __u32 cdw11 = slba >> 32; + __u32 cdw12 = (data_len >> 2) - 1; + __u32 cdw13 = DW(zra , NVME_ZNS_MGMT_RECV_ZRA) | + DW(zrasf, NVME_ZNS_MGMT_RECV_ZRASF) | + DW(zras_feat, NVME_ZNS_MGMT_RECV_ZRAS_FEAT); + + struct nvme_passthru_cmd cmd = { + .opcode = nvme_zns_cmd_mgmt_send, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw13 = cdw13, + .addr = (__u64)(uintptr_t)data, + .data_len = data_len, + }; + + return nvme_submit_io_passthru(fd, &cmd, NULL); +} + +int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, + __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, + void *data, __u32 metadata_len, void *metadata, + __u64 *result) +{ + __u32 cdw10 = zslba & 0xffffffff; + __u32 cdw11 = zslba >> 32; + __u32 cdw12 = nlb | (control << 16); + __u32 cdw14 = ilbrt; + __u32 cdw15 = lbat | (lbatm << 16); + + struct nvme_passthru_cmd64 cmd = { + .opcode = nvme_zns_cmd_append, + .nsid = nsid, + .cdw10 = cdw10, + .cdw11 = cdw11, + .cdw12 = cdw12, + .cdw14 = cdw14, + .cdw15 = cdw15, + .metadata = (__u64)(uintptr_t)metadata, + .addr = (__u64)(uintptr_t)data, + .metadata_len = metadata_len, + .data_len = data_len, + }; + + return nvme_submit_io_passthru64(fd, &cmd, result); +} diff --git a/src/nvme/ioctl.h b/src/nvme/ioctl.h index 77ad9a36..d1ebc687 100644 --- a/src/nvme/ioctl.h +++ b/src/nvme/ioctl.h @@ -435,6 +435,8 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_NS_ACTIVE_LIST: * @NVME_IDENTIFY_CNS_NS_DESC_LIST: * @NVME_IDENTIFY_CNS_NVMSET_LIST: + * @NVME_IDENTIFY_CNS_CSI_NS: + * @NVME_IDENTIFY_CNS_CSI_CTRL: * @NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST: * @NVME_IDENTIFY_CNS_ALLOCATED_NS: * @NVME_IDENTIFY_CNS_NS_CTRL_LIST: @@ -443,6 +445,7 @@ enum nvme_admin_opcode { * @NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST: * @NVME_IDENTIFY_CNS_NS_GRANULARITY: * @NVME_IDENTIFY_CNS_UUID_LIST: + * @NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS: */ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS = 0x00, @@ -450,6 +453,8 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_NS_ACTIVE_LIST = 0x02, NVME_IDENTIFY_CNS_NS_DESC_LIST = 0x03, NVME_IDENTIFY_CNS_NVMSET_LIST = 0x04, + NVME_IDENTIFY_CNS_CSI_NS = 0x05, /* XXX: Placeholder until assigned */ + NVME_IDENTIFY_CNS_CSI_CTRL = 0x06, /* XXX: Placeholder until assigned */ NVME_IDENTIFY_CNS_ALLOCATED_NS_LIST = 0x10, NVME_IDENTIFY_CNS_ALLOCATED_NS = 0x11, NVME_IDENTIFY_CNS_NS_CTRL_LIST = 0x12, @@ -458,6 +463,7 @@ enum nvme_identify_cns { NVME_IDENTIFY_CNS_SECONDARY_CTRL_LIST = 0x15, NVME_IDENTIFY_CNS_NS_GRANULARITY = 0x16, NVME_IDENTIFY_CNS_UUID_LIST = 0x17, + NVME_IDENTIFY_CNS_CSI_ALLOCATED_NS = 0x18, /* XXX: Placeholder until assigned */ }; /** @@ -480,6 +486,7 @@ enum nvme_identify_cns { * @NVME_LOG_LID_DISCOVER: * @NVME_LOG_LID_RESERVATION: * @NVME_LOG_LID_SANITIZE: + * @NVME_LOG_LID_ZNS_CHANGED_ZONES: */ enum nvme_cmd_get_log_lid { NVME_LOG_LID_ERROR = 0x01, @@ -500,6 +507,7 @@ enum nvme_cmd_get_log_lid { NVME_LOG_LID_DISCOVER = 0x70, NVME_LOG_LID_RESERVATION = 0x80, NVME_LOG_LID_SANITIZE = 0x81, + NVME_LOG_LID_ZNS_CHANGED_ZONES = 0xbf, }; /** @@ -528,6 +536,7 @@ enum nvme_cmd_get_log_lid { * @NVME_FEAT_FID_HOST_BEHAVIOR: * @NVME_FEAT_FID_SANITIZE: * @NVME_FEAT_FID_ENDURANCE_EVT_CFG: + * @NVME_FEAT_FID_IOCS_PROFILE: * @NVME_FEAT_FID_SW_PROGRESS: * @NVME_FEAT_FID_HOST_ID: * @NVME_FEAT_FID_RESV_MASK: @@ -559,6 +568,7 @@ enum nvme_features_id { NVME_FEAT_FID_HOST_BEHAVIOR = 0x16, NVME_FEAT_FID_SANITIZE = 0x17, NVME_FEAT_FID_ENDURANCE_EVT_CFG = 0x18, + NVME_FEAT_FID_IOCS_PROFILE = 0x19, /* XXX: Placeholder until assigned */ NVME_FEAT_FID_SW_PROGRESS = 0x80, NVME_FEAT_FID_HOST_ID = 0x81, NVME_FEAT_FID_RESV_MASK = 0x82, @@ -767,6 +777,7 @@ enum nvme_virt_mgmt_rt { * @cntid: The Controller Identifier, if applicable * @nvmsetid: The NVMe Set ID if CNS is 04h * @uuidx: UUID Index if controller supports this id selection method + * @csi: Command Set Identifier * @data: User space destination address to transfer the data * * The Identify command returns a data buffer that describes information about @@ -776,7 +787,8 @@ enum nvme_virt_mgmt_rt { * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_identify(int fd, enum nvme_identify_cns cns, __u32 nsid, - __u16 cntid, __u16 nvmsetid, __u8 uuidx, void *data); + __u16 cntid, __u16 nvmsetid, __u8 uuidx, __u8 csi, + void *data); /** * nvme_identify_ctrl() - Retrieves nvme identify controller @@ -1004,6 +1016,63 @@ int nvme_identify_ns_granularity(int fd, struct nvme_id_ns_granularity_list *lis */ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); +/** + * nvme_identify_ns_csi() - + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @csi: Command Set Identifier + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_ns_csi(int fd, __u32 nsid, __u8 csi, void *data); + +/** + * nvme_identify_ctrl_csi() - + * @fd: File descriptor of nvme device + * @csi: Command Set Identifier + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_ctrl_csi(int fd, __u8 csi, void *data); + +/** + * nvme_identify_iocs() - + * @fd: File descriptor of nvme device + * @iocs: User space destination address to transfer the data + * + * Retrieves list of the controller's supported io command set vectors. See + * @struct nvme_id_iocs. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_identify_iocs(int fd, struct nvme_id_iocs *iocs); + +/** + * nvme_zns_identify_ns() - + * @fd: File descriptor of nvme device + * @nsid: Namespace to identify + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_identify_ns(int fd, __u32 nsid, struct nvme_zns_id_ns *data); + +/** + * nvme_zns_identify_ctrl() - + * @fd: File descriptor of nvme device + * @data: User space destination address to transfer the data + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_identify_ctrl(int fd, struct nvme_zns_id_ctrl *data); + /** * nvme_get_log() - NVMe Admin Get Log command * @fd: File descriptor of nvme device @@ -1022,7 +1091,8 @@ int nvme_identify_uuid(int fd, struct nvme_id_uuid_list *list); * &enum nvme_status_field) or -1 with errno set otherwise. */ int nvme_get_log(int fd, enum nvme_cmd_get_log_lid lid, __u32 nsid, __u64 lpo, - __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, __u32 len, void *log); + __u8 lsp, __u16 lsi, bool rae, __u8 uuidx, enum nvme_csi csi, + __u32 len, void *log); /** * nvme_get_log_error() - Retrieve nvme error log @@ -1093,6 +1163,7 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); /** * nvme_get_log_cmd_effects() - Retrieve nvme command effects log * @fd: File descriptor of nvme device + * @csi: Command Set Identifier * @effects_log:User address to store the effects log * * This log page describes the commands that the controller supports and the @@ -1101,7 +1172,8 @@ int nvme_get_log_changed_ns_list(int fd, bool rae, struct nvme_ns_list *log); * Return: The nvme command status if a response was received (see * &enum nvme_status_field) or -1 with errno set otherwise. */ -int nvme_get_log_cmd_effects(int fd, struct nvme_cmd_effects_log *log); +int nvme_get_log_cmd_effects(int fd, enum nvme_csi csi, + struct nvme_cmd_effects_log *log); /** * nvme_get_log_device_self_test() - Retrieve the device self test log @@ -1282,6 +1354,21 @@ int nvme_get_log_reservation(int fd, bool rae, int nvme_get_log_sanitize(int fd, bool rae, struct nvme_sanitize_log_page *log); +/** + * nvme_get_log_zns_changed_zones() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @rae: Retain asynchronous events + * @log: User address to store the changed zone log + * + * The list of zones that have changed state due to an exceptional event. + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_log_zns_changed_zones(int fd, __u32 nsid, bool rae, + struct nvme_zns_changed_zone_log *log); + /** * nvme_set_features() - Set a feature attribute * @fd: File descriptor of nvme device @@ -1680,6 +1767,17 @@ enum nvme_feat_nswpcfg_state { int nvme_set_features_write_protect(int fd, enum nvme_feat_nswpcfg_state state, bool save, __u32 *result); +/** + * nvme_set_features_iocs_profile() - + * @fd: File descriptor of nvme device + * @iocsi: IO Command Set Combination Index + * @save: Save value across power states + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_set_features_iocs_profile(int fd, __u8 iocsi, bool save); + /** * nvme_get_features() - Retrieve a feature attribute * @fd: File descriptor of nvme device @@ -1735,7 +1833,6 @@ int nvme_get_features_power_mgmt(int fd, enum nvme_get_features_sel sel, int nvme_get_features_lba_range(int fd, enum nvme_get_features_sel sel, struct nvme_lba_range_type *data, __u32 *result); - /** * nvme_get_features_temp_thresh() - * @fd: File descriptor of nvme device @@ -2048,6 +2145,17 @@ int nvme_get_features_write_protect(int fd, __u32 nsid, enum nvme_get_features_sel sel, __u32 *result); +/** + * nvme_get_features_iocs_profile() - + * @fd: File descriptor of nvme device + * @sel: Select which type of attribute to return, see &enum nvme_get_features_sel + * @result: The command completion result from CQE dword0 + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel, + __u32 *result); /** * nvme_format_nvm() - Format nvme namespace(s) @@ -2523,6 +2631,9 @@ enum nvme_io_opcode { nvme_cmd_resv_report = 0x0e, nvme_cmd_resv_acquire = 0x11, nvme_cmd_resv_release = 0x15, + nvme_zns_cmd_mgmt_send = 0x79, + nvme_zns_cmd_mgmt_recv = 0x7a, + nvme_zns_cmd_append = 0x7d, }; /** @@ -2542,6 +2653,7 @@ int nvme_flush(int fd, __u32 nsid); * enum nvme_io_control_flags - * @NVME_IO_DTYPE_STREAMS: * @NVME_IO_DEAC: + * @NVME_IO_ZNS_APPEND_PIREMAP: * @NVME_IO_PRINFO_PRCHK_REF: * @NVME_IO_PRINFO_PRCHK_APP: * @NVME_IO_PRINFO_PRCHK_GUARD: @@ -2552,6 +2664,7 @@ int nvme_flush(int fd, __u32 nsid); enum nvme_io_control_flags { NVME_IO_DTYPE_STREAMS = 1 << 4, NVME_IO_DEAC = 1 << 9, + NVME_IO_ZNS_APPEND_PIREMAP = 1 << 9, NVME_IO_PRINFO_PRCHK_REF = 1 << 10, NVME_IO_PRINFO_PRCHK_APP = 1 << 11, NVME_IO_PRINFO_PRCHK_GUARD = 1 << 12, @@ -2928,4 +3041,78 @@ int nvme_resv_release(int fd, __u32 nsid, enum nvme_resv_rtype rtype, */ int nvme_resv_report(int fd, __u32 nsid, bool eds, __u32 len, struct nvme_resv_status *report); + +enum nvme_zns_send_action { + NVME_ZNS_ZSA_CLOSE = 0x1, + NVME_ZNS_ZSA_FINISH = 0x2, + NVME_ZNS_ZSA_OPEN = 0x3, + NVME_ZNS_ZSA_RESET = 0x4, + NVME_ZNS_ZSA_OFFLINE = 0x5, + NVME_ZNS_ZSA_SET_DESC_EXT = 0x10, +}; + +/** + * nvme_zns_mgmt_send() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * @slba: + * @select_all: + * @zsa: + * @data_len: + * @data: + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_mgmt_send(int fd, __u32 nsid, __u64 slba, bool select_all, + enum nvme_zns_send_action zsa, __u32 data_len, + void *data); + +/** + * enum nvme_zns_recv_action - + */ +enum nvme_zns_recv_action { + NVME_ZNS_ZRA_REPORT_ZONES = 0x0, + NVME_ZNS_ZRA_EXTENDED_REPORT_ZONES = 0x1, +}; + +/** + * enum nvme_zns_recv_action_spec - + */ +enum nvme_zns_recv_action_spec { + NVME_ZNS_ZRAS_REPORT_ALL = 0x0, + NVME_ZNS_ZRAS_REPORT_EMPTY = 0x1, + NVME_ZNS_ZRAS_REPORT_IMPL_OPENED = 0x2, + NVME_ZNS_ZRAS_REPORT_EXPL_OPENED = 0x3, + NVME_ZNS_ZRAS_REPORT_CLOSED = 0x4, + NVME_ZNS_ZRAS_REPORT_FULL = 0x5, + NVME_ZNS_ZRAS_REPORT_READ_ONLY = 0x6, + NVME_ZNS_ZRAS_REPORT_OFFLINE = 0x7, +}; + +/** + * nvme_zns_mgmt_recv() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_mgmt_recv(int fd, __u32 nsid, __u64 slba, + enum nvme_zns_recv_action zra, __u16 zrasf, + bool zras_feat, __u32 data_len, void *data); + +/** + * nvme_zns_append() - + * @fd: File descriptor of nvme device + * @nsid: Namespace ID + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_zns_append(int fd, __u32 nsid, __u64 zslba, __u16 nlb, __u16 control, + __u32 ilbrt, __u16 lbat, __u16 lbatm, __u32 data_len, + void *data, __u32 metadata_len, void *metadata, + __u64 *result); + #endif /* _LIBNVME_IOCTL_H */ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 4ef455ea..097d6165 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -70,6 +70,7 @@ struct nvme_ns { uint8_t eui64[8]; uint8_t nguid[16]; uuid_t uuid; + enum nvme_csi csi; }; struct nvme_ctrl { @@ -724,6 +725,11 @@ uint64_t nvme_ns_get_lba_util(nvme_ns_t n) return n->lba_util; } +enum nvme_csi nvme_ns_get_csi(nvme_ns_t n) +{ + return n->csi; +} + const uint8_t *nvme_ns_get_eui64(nvme_ns_t n) { return n->eui64; @@ -849,6 +855,9 @@ static void nvme_ns_parse_descriptors(struct nvme_ns *n, case NVME_NIDT_UUID: memcpy(n->uuid, desc->nid, sizeof(n->uuid)); break; + case NVME_NIDT_CSI: + memcpy(&n->csi, desc->nid, sizeof(n->csi)); + break; } } } diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 40a43f97..dc525974 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -267,6 +267,14 @@ uint64_t nvme_ns_get_lba_count(nvme_ns_t n); */ uint64_t nvme_ns_get_lba_util(nvme_ns_t n); +/** + * nvme_ns_get_csi() - + * @n: + * + * Return: The namespace's command set identifier in use + */ +enum nvme_csi nvme_ns_get_csi(nvme_ns_t n); + /** * nvme_ns_get_eui64() - * @n: diff --git a/src/nvme/types.h b/src/nvme/types.h index 31fe5fac..31a46b75 100644 --- a/src/nvme/types.h +++ b/src/nvme/types.h @@ -145,6 +145,16 @@ enum nvme_constants { NVME_NQN_LENGTH = 256, NVMF_TRADDR_SIZE = 256, NVMF_TSAS_SIZE = 256, + NVME_ZNS_CHANGED_ZONES_MAX = 511, +}; + +/** + * enum nvme_csi - Defined command set indicators + * @NVME_CSI_NVM: NVM Command Set Indicator + */ +enum nvme_csi { + NVME_CSI_NVM = 0, + NVME_CSI_ZNS = 2, }; /** @@ -324,6 +334,7 @@ enum nvme_cc { NVME_CC_IOSQES_MASK = 0xf, NVME_CC_IOCQES_MASK = 0xf, NVME_CC_CSS_NVM = 0, + NVME_CC_CSS_CSI = 6, NVME_CC_CSS_ADMIN = 7, NVME_CC_AMS_RR = 0, NVME_CC_AMS_WRRU = 1, @@ -1903,12 +1914,14 @@ enum nvme_ns_id_desc_nidt { NVME_NIDT_EUI64 = 1, NVME_NIDT_NGUID = 2, NVME_NIDT_UUID = 3, + NVME_NIDT_CSI = 4, }; enum nvme_ns_id_desc_nidt_lens { NVME_NIDT_EUI64_LEN = 8, NVME_NIDT_NGUID_LEN = 16, NVME_NIDT_UUID_LEN = 16, + NVME_NIDT_CSI_LEN = 1, }; /** @@ -2021,6 +2034,50 @@ struct nvme_ns_list { __le32 ns[NVME_ID_NS_LIST_MAX]; }; +/** + * struct nvme_zns_lbafe - + * zsze: + * zdes: + */ +struct nvme_zns_lbafe { + __le64 zsze; + __u8 zdes; + __u8 rsvd9[7]; +}; + +/** + * struct nvme_zns_id_ns - + * @zoc: + * @ozcs: + * @mar: + * @mor: + * @rrl: + * @frl: + * @lbafe: + * @vs: + */ +struct nvme_zns_id_ns { + __le16 zoc; + __le16 ozcs; + __le32 mar; + __le32 mor; + __le32 rrl; + __le32 frl; + __u8 rsvd20[2796]; + struct nvme_zns_lbafe lbafe[16]; + __u8 rsvd3072[768]; + __u8 vs[256]; +}; + +/** + * struct nvme_zns_id_ctrl - + * @zamds: + */ +struct nvme_zns_id_ctrl { + __u8 zamds; + __u8 rsvd1[4095]; +}; + /** * struct nvme_primary_ctrl_cap - * @cntlid: @@ -2091,6 +2148,14 @@ struct nvme_secondary_ctrl_list { struct nvme_secondary_ctrl sc_entry[NVME_ID_SECONDARY_CTRL_MAX]; }; +/** + * struct nvme_id_iocs - NVMe Identify IO Command Set data structure + * @iocsc: List of supported IO Command Set Combination vectors + */ +struct nvme_id_iocs { + __u64 iocsc[512]; +}; + /** * struct nvme_error_log_page - */ @@ -2735,6 +2800,70 @@ enum nvme_sanitize_sstat { NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED_MASK = 0x1, }; +/** + * struct nvme_zns_changed_zone_log - ZNS Changed Zone List log + * @nrzid: + * @zid: + */ +struct nvme_zns_changed_zone_log { + __le16 nrzid; + __u8 rsvd2[6]; + __le64 zid[NVME_ZNS_CHANGED_ZONES_MAX]; +}; + +/** + * enum nvme_zns_zt - + */ +enum nvme_zns_zt { + NVME_ZONE_TYPE_SEQWRITE_REQ = 0x2, +}; + +/** + * enum nvme_zns_za - + */ +enum nvme_zns_za { + NVME_ZNS_ZA_ZFC = 1 << 0, + NVME_ZNS_ZA_FZR = 1 << 1, + NVME_ZNS_ZA_RZR = 1 << 2, + NVME_ZNS_ZA_ZDEV = 1 << 7, +}; + +/** + * enum nvme_zns_zs - + */ +enum nvme_zns_zs { + NVME_ZNS_ZS_EMPTY = 0x1, + NVME_ZNS_ZS_IMPL_OPEN = 0x2, + NVME_ZNS_ZS_EXPL_OPEN = 0x3, + NVME_ZNS_ZS_CLOSED = 0x4, + NVME_ZNS_ZS_READ_ONLY = 0xd, + NVME_ZNS_ZS_FULL = 0xe, + NVME_ZNS_ZS_OFFLINE = 0xf, +}; + +/** + * struct nvme_zns_desc - + */ +struct nvme_zns_desc { + __u8 zt; + __u8 zs; + __u8 za; + __u8 rsvd3[5]; + __le64 zcap; + __le64 zslba; + __le64 wp; + __u8 rsvd32[32]; +}; + +/** + * struct nvme_zone_report - + */ +struct nvme_zone_report { + __le64 nr_zones; + __u8 resv8[56]; + struct nvme_zns_desc entries[]; +}; + /** * struct nvme_lba_status_desc - * @dslba: @@ -4101,6 +4230,18 @@ enum nvme_status_field { NVME_SC_DISCOVERY_RESTART = 0x90, NVME_SC_AUTH_REQUIRED = 0x91, + /* + * I/O Command Set Specific - ZNS commands: + */ + NVME_SC_ZNS_BOUNDARY_ERROR = 0xb8, + NVME_SC_ZNS_FULL = 0xb9, + NVME_SC_ZNS_READ_ONLY = 0xba, + NVME_SC_ZNS_OFFLINE = 0xbb, + NVME_SC_ZNS_INVALID_WRITE = 0xbc, + NVME_SC_ZNS_TOO_MANY_ACTIVE = 0xbd, + NVME_SC_ZNS_TOO_MANY_OPENS = 0xbe, + NVME_SC_ZNS_INVAL_TRANSITION = 0xbf, + /* * Media and Data Integrity Errors: */ diff --git a/src/nvme/util.c b/src/nvme/util.c index 90e99025..50a39dd7 100644 --- a/src/nvme/util.c +++ b/src/nvme/util.c @@ -255,7 +255,7 @@ int __nvme_get_log_page(int fd, __u32 nsid, __u8 log_id, bool rae, ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE, NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE, - xfer, ptr); + NVME_CSI_NVM, xfer, ptr); if (ret) return ret; diff --git a/test/Makefile b/test/Makefile index 77669219..16206220 100644 --- a/test/Makefile +++ b/test/Makefile @@ -9,7 +9,7 @@ else CONFIG_CPLUSPLUS=y endif -c_targets += test register +c_targets += test register zns ifdef CONFIG_CPLUSPLUS cpp_targets += cpp @@ -23,10 +23,10 @@ all: $(all_targets) CXXFLAGS ?= -lstdc++ %: %.cc - $(QUIET_CC)$(CC) $(CFLAGS) $(CXXFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $@ $< -lnvme %: %.c - $(QUIET_CC)$(CC) $(CFLAGS) -o $@ $< -lnvme + $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lnvme clean: rm -f $(all_targets) diff --git a/test/test.c b/test/test.c index 79919e17..a2229876 100644 --- a/test/test.c +++ b/test/test.c @@ -147,7 +147,7 @@ static int test_ctrl(nvme_ctrl_t c) printf(" Device Self Test\n"); else printf(" ERROR: Device Self Test:%x\n", ret); - ret = nvme_get_log_cmd_effects(fd, &cfx); + ret = nvme_get_log_cmd_effects(fd, NVME_CSI_NVM, &cfx); if (!ret) printf(" Command Effects\n"); else @@ -359,7 +359,7 @@ int main() print_hex(nvme_ns_get_nguid(n), 16); nvme_ns_get_uuid(n, uuid); uuid_unparse_lower(uuid, uuid_str); - printf(" uuid:%s\n", uuid_str); + printf(" uuid:%s csi:%d\n", uuid_str, nvme_ns_get_csi(n)); } nvme_ctrl_for_each_path(c, p) diff --git a/test/zns.c b/test/zns.c new file mode 100644 index 00000000..fd186f19 --- /dev/null +++ b/test/zns.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/** + * This file is part of libnvme. + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: Keith Busch + */ + +/** + * Search out for ZNS type namespaces, and if found, report their properties. + */ +#include +#include +#include +#include +#include +#include + +static void show_zns_properties(nvme_ns_t n) +{ + struct nvme_zns_id_ns zns_ns; + struct nvme_zns_id_ctrl zns_ctrl; + struct nvme_zone_report *zr; + + zr = calloc(1, 0x1000); + if (!zr) + return; + + if (nvme_zns_identify_ns(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), + &zns_ns)) { + fprintf(stderr, "failed to identify zns ns\n");; + } + + printf("zoc:%x ozcs:%x mar:%x mor:%x\n", le16_to_cpu(zns_ns.zoc), + le16_to_cpu(zns_ns.ozcs), le32_to_cpu(zns_ns.mar), + le32_to_cpu(zns_ns.mor)); + + if (nvme_zns_identify_ctrl(nvme_ns_get_fd(n), &zns_ctrl)) { + fprintf(stderr, "failed to identify zns ctrl\n");; + return; + } + + printf("zamds:%u\n", zns_ctrl.zamds); + + if (nvme_zns_mgmt_recv(nvme_ns_get_fd(n), nvme_ns_get_nsid(n), 0, + NVME_ZNS_ZRA_REPORT_ZONES, NVME_ZNS_ZRAS_REPORT_ALL, + 0, 0x1000, (void *)zr)) { + fprintf(stderr, "failed to report zones\n");; + return; + } + + printf("nr_zones:%"PRIu64"\n", le64_to_cpu(zr->nr_zones)); + free(zr); +} + +int main() +{ + nvme_subsystem_t s; + nvme_root_t r; + nvme_ctrl_t c; + nvme_ns_t n; + + r = nvme_scan(); + if (!r) + return -1; + + nvme_for_each_subsystem(r, s) { + nvme_subsystem_for_each_ctrl(s, c) { + nvme_ctrl_for_each_ns(c, n) { + if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) + show_zns_properties(n); + } + } + nvme_subsystem_for_each_ns(s, n) { + if (nvme_ns_get_csi(n) == NVME_CSI_ZNS) + show_zns_properties(n); + } + } + nvme_free_tree(r); +}