From 99c8c6d8e1aaa9b93745591dddb76603e823a4ad Mon Sep 17 00:00:00 2001 From: Ben Walker Date: Tue, 22 May 2018 13:54:02 -0700 Subject: [PATCH] nvme: Allow users to request which I/O command set they'd like to use As of NVMe 1.3b, there is only one command set. But pipe this through the driver per-spec anyway. Change-Id: I4faf8596f5ce638e5e2a500b424e00ceb6e89edc Signed-off-by: Ben Walker Reviewed-on: https://review.gerrithub.io/412102 Tested-by: SPDK Automated Test System Reviewed-by: Daniel Verkamp Reviewed-by: Changpeng Liu --- examples/nvme/identify/identify.c | 2 +- include/spdk/nvme.h | 9 +++++++++ include/spdk/nvme_spec.h | 15 ++++++++++++--- lib/nvme/nvme_ctrlr.c | 18 ++++++++++++++++++ lib/nvmf/ctrlr.c | 2 +- lib/vhost/vhost_nvme.c | 2 +- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/examples/nvme/identify/identify.c b/examples/nvme/identify/identify.c index dbcc9522d..ecb946f54 100644 --- a/examples/nvme/identify/identify.c +++ b/examples/nvme/identify/identify.c @@ -823,7 +823,7 @@ print_controller(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_transport cap.bits.nssrs ? "Supported" : "Not Supported"); printf("Command Sets Supported\n"); printf(" NVM Command Set: %s\n", - cap.bits.css_nvm ? "Supported" : "Not Supported"); + cap.bits.css & SPDK_NVME_CAP_CSS_NVM ? "Supported" : "Not Supported"); printf("Boot Partition: %s\n", cap.bits.bps ? "Supported" : "Not Supported"); printf("Memory Page Size Minimum: %" PRIu64 " bytes\n", diff --git a/include/spdk/nvme.h b/include/spdk/nvme.h index b55cbe515..f384fed30 100644 --- a/include/spdk/nvme.h +++ b/include/spdk/nvme.h @@ -144,6 +144,15 @@ struct spdk_nvme_ctrlr_opts { * Set to all zeroes to specify that no host ID should be provided to the controller. */ uint8_t extended_host_id[16]; + + /** + * The I/O command set to select. + * + * If the requested command set is not supported, the controller + * initialization process will not proceed. By default, the NVM + * command set is used. + */ + enum spdk_nvme_cc_css command_set; }; /** diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index f57fc3572..6763ea1f1 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -96,9 +96,7 @@ union spdk_nvme_cap_register { uint32_t nssrs : 1; /** command sets supported */ - uint32_t css_nvm : 1; - - uint32_t css_reserved : 7; + uint32_t css : 8; /** boot partition support */ uint32_t bps : 1; @@ -116,6 +114,17 @@ union spdk_nvme_cap_register { }; SPDK_STATIC_ASSERT(sizeof(union spdk_nvme_cap_register) == 8, "Incorrect size"); +/** + * I/O Command Set Selected + * + * Only a single command set is defined as of NVMe 1.3 (NVM). + */ +enum spdk_nvme_cc_css { + SPDK_NVME_CC_CSS_NVM = 0x0, /**< NVM command set */ +}; + +#define SPDK_NVME_CAP_CSS_NVM (1u << SPDK_NVME_CC_CSS_NVM) /**< NVM command set supported */ + union spdk_nvme_cc_register { uint32_t raw; struct { diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 107156f0f..63d177bc9 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -134,6 +134,10 @@ spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t if (FIELD_OK(src_svcid)) { memset(opts->src_svcid, 0, sizeof(opts->src_svcid)); } + + if (FIELD_OK(command_set)) { + opts->command_set = SPDK_NVME_CC_CSS_NVM; + } #undef FIELD_OK } @@ -553,6 +557,20 @@ nvme_ctrlr_enable(struct spdk_nvme_ctrlr *ctrlr) /* Page size is 2 ^ (12 + mps). */ cc.bits.mps = spdk_u32log2(ctrlr->page_size) - 12; + if (ctrlr->cap.bits.css == 0) { + SPDK_INFOLOG(SPDK_LOG_NVME, + "Drive reports no command sets supported. Assuming NVM is supported.\n"); + ctrlr->cap.bits.css = SPDK_NVME_CAP_CSS_NVM; + } + + if (!(ctrlr->cap.bits.css & (1u << ctrlr->opts.command_set))) { + SPDK_DEBUGLOG(SPDK_LOG_NVME, "Requested I/O command set %u but supported mask is 0x%x\n", + ctrlr->opts.command_set, ctrlr->cap.bits.css); + return -EINVAL; + } + + cc.bits.css = ctrlr->opts.command_set; + switch (ctrlr->opts.arb_mechanism) { case SPDK_NVME_CC_AMS_RR: break; diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index a646dd720..470df0b24 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -166,7 +166,7 @@ spdk_nvmf_ctrlr_create(struct spdk_nvmf_subsystem *subsystem, ctrlr->vcprop.cap.bits.ams = 0; /* optional arb mechanisms */ ctrlr->vcprop.cap.bits.to = 1; /* ready timeout - 500 msec units */ ctrlr->vcprop.cap.bits.dstrd = 0; /* fixed to 0 for NVMe-oF */ - ctrlr->vcprop.cap.bits.css_nvm = 1; /* NVM command set */ + ctrlr->vcprop.cap.bits.css = SPDK_NVME_CAP_CSS_NVM; /* NVM command set */ ctrlr->vcprop.cap.bits.mpsmin = 0; /* 2 ^ (12 + mpsmin) == 4k */ ctrlr->vcprop.cap.bits.mpsmax = 0; /* 2 ^ (12 + mpsmax) == 4k */ diff --git a/lib/vhost/vhost_nvme.c b/lib/vhost/vhost_nvme.c index 5a9d97b0f..da705867b 100644 --- a/lib/vhost/vhost_nvme.c +++ b/lib/vhost/vhost_nvme.c @@ -1216,7 +1216,7 @@ spdk_vhost_nvme_ctrlr_identify_update(struct spdk_vhost_nvme_dev *dev) dev->cap.bits.cqr = 1; dev->cap.bits.to = 1; dev->cap.bits.dstrd = 0; - dev->cap.bits.css_nvm = 1; + dev->cap.bits.css = SPDK_NVME_CAP_CSS_NVM; dev->cap.bits.mpsmin = 0; dev->cap.bits.mpsmax = 0; /* MQES is 0 based value */