nvme: add initial namespace types support
Add support for getting the Command Set Identifier for a given namespace. The SPDK_NVME_CAP_CSS_IOCS feature can be implemented on top of an old NVMe specification. If the feature is set, retrieve the NS ID Descriptor List regardless of the NVMe specification version. The quirk is still respected. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Change-Id: I7b257115ecb0d813ba75201c0f48960c7070dcc9 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/4085 Community-CI: Broadcom CI Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
5c861295dd
commit
174a5fe140
@ -2274,6 +2274,15 @@ uint32_t spdk_nvme_ns_get_optimal_io_boundary(struct spdk_nvme_ns *ns);
|
||||
*/
|
||||
const struct spdk_uuid *spdk_nvme_ns_get_uuid(const struct spdk_nvme_ns *ns);
|
||||
|
||||
/**
|
||||
* Get the Command Set Identifier for the given namespace.
|
||||
*
|
||||
* \param ns Namespace to query.
|
||||
*
|
||||
* \return the namespace Command Set Identifier.
|
||||
*/
|
||||
enum spdk_nvme_csi spdk_nvme_ns_get_csi(const struct spdk_nvme_ns *ns);
|
||||
|
||||
/**
|
||||
* \brief Namespace command support flags.
|
||||
*/
|
||||
|
@ -980,6 +980,14 @@ SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cmd_cdw10) == 4, "Incorrect size");
|
||||
union spdk_nvme_cmd_cdw11 {
|
||||
uint32_t raw;
|
||||
|
||||
struct {
|
||||
/* NVM Set Identifier */
|
||||
uint32_t nvmsetid : 16;
|
||||
uint32_t reserved : 8;
|
||||
/* Command Set Identifier */
|
||||
uint32_t csi : 8;
|
||||
} identify;
|
||||
|
||||
struct {
|
||||
/* Physically Contiguous */
|
||||
uint32_t pc : 1;
|
||||
@ -2852,6 +2860,9 @@ enum spdk_nvme_nidt {
|
||||
|
||||
/** Namespace UUID */
|
||||
SPDK_NVME_NIDT_UUID = 0x03,
|
||||
|
||||
/** Namespace Command Set Identifier */
|
||||
SPDK_NVME_NIDT_CSI = 0x04,
|
||||
};
|
||||
|
||||
struct spdk_nvme_ns_id_desc {
|
||||
@ -2875,6 +2886,12 @@ struct spdk_nvme_ctrlr_list {
|
||||
};
|
||||
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_list) == 4096, "Incorrect size");
|
||||
|
||||
enum spdk_nvme_csi {
|
||||
SPDK_NVME_CSI_NVM = 0x0,
|
||||
SPDK_NVME_CSI_KV = 0x1,
|
||||
SPDK_NVME_CSI_ZNS = 0x2,
|
||||
};
|
||||
|
||||
enum spdk_nvme_secure_erase_setting {
|
||||
SPDK_NVME_FMT_NVM_SES_NO_SECURE_ERASE = 0x0,
|
||||
SPDK_NVME_FMT_NVM_SES_USER_DATA_ERASE = 0x1,
|
||||
|
@ -35,7 +35,7 @@ SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
SO_VER := 4
|
||||
SO_MINOR := 0
|
||||
SO_MINOR := 1
|
||||
|
||||
C_SRCS = nvme_ctrlr_cmd.c nvme_ctrlr.c nvme_fabric.c nvme_ns_cmd.c nvme_ns.c nvme_pcie.c nvme_qpair.c nvme.c nvme_quirks.c nvme_transport.c nvme_uevent.c nvme_ctrlr_ocssd_cmd.c \
|
||||
nvme_ns_ocssd_cmd.c nvme_tcp.c nvme_opal.c nvme_io_msg.c nvme_poll_group.c
|
||||
|
@ -1731,7 +1731,8 @@ nvme_ctrlr_identify_id_desc_namespaces(struct spdk_nvme_ctrlr *ctrlr)
|
||||
struct spdk_nvme_ns *ns;
|
||||
int rc;
|
||||
|
||||
if (ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) ||
|
||||
if ((ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) &&
|
||||
!(ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS)) ||
|
||||
(ctrlr->quirks & NVME_QUIRK_IDENTIFY_CNS)) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_NVME, "Version < 1.3; not attempting to retrieve NS ID Descriptor List\n");
|
||||
nvme_ctrlr_set_state(ctrlr, NVME_CTRLR_STATE_CONFIGURE_AER,
|
||||
|
@ -157,7 +157,8 @@ nvme_ctrlr_identify_id_desc(struct spdk_nvme_ns *ns)
|
||||
|
||||
memset(ns->id_desc_list, 0, sizeof(ns->id_desc_list));
|
||||
|
||||
if (ns->ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) ||
|
||||
if ((ns->ctrlr->vs.raw < SPDK_NVME_VERSION(1, 3, 0) &&
|
||||
!(ns->ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS)) ||
|
||||
(ns->ctrlr->quirks & NVME_QUIRK_IDENTIFY_CNS)) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_NVME, "Version < 1.3; not attempting to retrieve NS ID Descriptor List\n");
|
||||
return 0;
|
||||
@ -360,6 +361,29 @@ spdk_nvme_ns_get_uuid(const struct spdk_nvme_ns *ns)
|
||||
return uuid;
|
||||
}
|
||||
|
||||
enum spdk_nvme_csi
|
||||
spdk_nvme_ns_get_csi(const struct spdk_nvme_ns *ns) {
|
||||
const uint8_t *csi;
|
||||
size_t csi_size;
|
||||
|
||||
csi = nvme_ns_find_id_desc(ns, SPDK_NVME_NIDT_CSI, &csi_size);
|
||||
if (csi && csi_size != sizeof(*csi))
|
||||
{
|
||||
SPDK_WARNLOG("Invalid NIDT_CSI descriptor length reported: %zu (expected: %zu)\n",
|
||||
csi_size, sizeof(*csi));
|
||||
return SPDK_NVME_CSI_NVM;
|
||||
}
|
||||
if (!csi)
|
||||
{
|
||||
if (ns->ctrlr->cap.bits.css & SPDK_NVME_CAP_CSS_IOCS) {
|
||||
SPDK_WARNLOG("CSI not reported for NSID: %" PRIu32 "\n", ns->id);
|
||||
}
|
||||
return SPDK_NVME_CSI_NVM;
|
||||
}
|
||||
|
||||
return *csi;
|
||||
}
|
||||
|
||||
int nvme_ns_construct(struct spdk_nvme_ns *ns, uint32_t id,
|
||||
struct spdk_nvme_ctrlr *ctrlr)
|
||||
{
|
||||
|
@ -107,6 +107,7 @@
|
||||
spdk_nvme_ns_get_dealloc_logical_block_read_value;
|
||||
spdk_nvme_ns_get_optimal_io_boundary;
|
||||
spdk_nvme_ns_get_uuid;
|
||||
spdk_nvme_ns_get_csi;
|
||||
spdk_nvme_ns_get_flags;
|
||||
|
||||
spdk_nvme_ns_cmd_write;
|
||||
|
@ -135,6 +135,49 @@ test_nvme_ns_uuid(void)
|
||||
CU_ASSERT(memcmp(uuid, &expected_uuid, sizeof(*uuid)) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_nvme_ns_csi(void)
|
||||
{
|
||||
struct spdk_nvme_ctrlr ctrlr = {};
|
||||
struct spdk_nvme_ns ns = { .ctrlr = &ctrlr };
|
||||
enum spdk_nvme_csi csi;
|
||||
|
||||
/* Empty list - SPDK_NVME_CSI_NVM should be returned */
|
||||
memset(ns.id_desc_list, 0, sizeof(ns.id_desc_list));
|
||||
csi = spdk_nvme_ns_get_csi(&ns);
|
||||
CU_ASSERT(csi == SPDK_NVME_CSI_NVM);
|
||||
|
||||
/* NVM CSI - SPDK_NVME_CSI_NVM should be returned */
|
||||
memset(ns.id_desc_list, 0, sizeof(ns.id_desc_list));
|
||||
ns.id_desc_list[0] = 0x4; /* NIDT == CSI */
|
||||
ns.id_desc_list[1] = 0x1; /* NIDL */
|
||||
ns.id_desc_list[4] = 0x0; /* SPDK_NVME_CSI_NVM */
|
||||
csi = spdk_nvme_ns_get_csi(&ns);
|
||||
CU_ASSERT(csi == SPDK_NVME_CSI_NVM);
|
||||
|
||||
/* NGUID followed by ZNS CSI - SPDK_NVME_CSI_ZNS should be returned */
|
||||
memset(ns.id_desc_list, 0, sizeof(ns.id_desc_list));
|
||||
ns.id_desc_list[0] = 0x02; /* NIDT == NGUID */
|
||||
ns.id_desc_list[1] = 0x10; /* NIDL */
|
||||
memset(&ns.id_desc_list[4], 0xCC, 0x10);
|
||||
ns.id_desc_list[20] = 0x4; /* NIDT == CSI */
|
||||
ns.id_desc_list[21] = 0x1; /* NIDL */
|
||||
ns.id_desc_list[24] = 0x2; /* SPDK_NVME_CSI_ZNS */
|
||||
csi = spdk_nvme_ns_get_csi(&ns);
|
||||
CU_ASSERT(csi == SPDK_NVME_CSI_ZNS);
|
||||
|
||||
/* KV CSI followed by NGUID - SPDK_NVME_CSI_KV should be returned */
|
||||
memset(ns.id_desc_list, 0, sizeof(ns.id_desc_list));
|
||||
ns.id_desc_list[0] = 0x4; /* NIDT == CSI */
|
||||
ns.id_desc_list[1] = 0x1; /* NIDL */
|
||||
ns.id_desc_list[4] = 0x1; /* SPDK_NVME_CSI_KV */
|
||||
ns.id_desc_list[5] = 0x02; /* NIDT == NGUID */
|
||||
ns.id_desc_list[6] = 0x10; /* NIDL */
|
||||
memset(&ns.id_desc_list[9], 0xCC, 0x10);
|
||||
csi = spdk_nvme_ns_get_csi(&ns);
|
||||
CU_ASSERT(csi == SPDK_NVME_CSI_KV);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CU_pSuite suite = NULL;
|
||||
@ -147,6 +190,7 @@ int main(int argc, char **argv)
|
||||
|
||||
CU_ADD_TEST(suite, test_nvme_ns_construct);
|
||||
CU_ADD_TEST(suite, test_nvme_ns_uuid);
|
||||
CU_ADD_TEST(suite, test_nvme_ns_csi);
|
||||
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
CU_basic_run_tests();
|
||||
|
Loading…
Reference in New Issue
Block a user