]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
zns and ns-types
authorKeith Busch <kbusch@kernel.org>
Tue, 2 Jun 2020 03:11:41 +0000 (20:11 -0700)
committerKeith Busch <kbusch@kernel.org>
Thu, 4 Jun 2020 20:10:02 +0000 (13:10 -0700)
Signed-off-by: Keith Busch <kbusch@kernel.org>
.gitignore
src/nvme/ioctl.c
src/nvme/ioctl.h
src/nvme/tree.c
src/nvme/tree.h
src/nvme/types.h
src/nvme/util.c
test/Makefile
test/test.c
test/zns.c [new file with mode: 0644]

index ab78bf1ae2b8e3d80f1050020beaeab07730344f..cbf80394b6ccabd1cf30a9fa6602e689a0825fe5 100644 (file)
@@ -12,6 +12,7 @@ libnvme.pc
 test/register
 test/test
 test/cpp
+test/zns
 
 examples/display-tree
 examples/display-columnar
index 2c3a12163de24e6a18df47b699dcb4a464262d80..d2bb0727e5b2cc355ec74857e25266207cde6a72 100644 (file)
@@ -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);
+}
index 77ad9a3631a25105ba3f7624701f00819cb4cca5..d1ebc687119555c683b16c7541481ba6bbe90253 100644 (file)
@@ -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 */
index 4ef455ea00f4ce2ee35ed2f8d82b657a598199ba..097d6165eb656956fba340760d9805899e3b0647 100644 (file)
@@ -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;
                }
        }
 }
index 40a43f97bbb548756d3f624a656cd56582a061d3..dc52597485f6efc98eb8c51ae3be266cfb71c618 100644 (file)
@@ -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:
index 31fe5faccfcbb1b062f89bad8522d290e03511bf..31a46b7500ca5ece43ba1c75909326269a3a0a41 100644 (file)
@@ -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:
         */
index 90e990256fbf475a194ca836e841d7779d8bd9ec..50a39dd78f151558415234c137d5139372436c6c 100644 (file)
@@ -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;
 
index 77669219461ef5ad85a4727ef3d7dd2caf7ee1fa..16206220ed64ee3e1638b8f9946acd070f02de2d 100644 (file)
@@ -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)
index 79919e170befa9c496cc30f0e9101db0a6936097..a2229876d5247a77ce8eaecbc8ee9cca88720d0f 100644 (file)
@@ -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 (file)
index 0000000..fd186f1
--- /dev/null
@@ -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 <keith.busch@wdc.com>
+ */
+
+/**
+ * Search out for ZNS type namespaces, and if found, report their properties.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <libnvme.h>
+#include <inttypes.h>
+
+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);
+}