From c5cd53cce0ba00da60a22007a5975878f4ce78b6 Mon Sep 17 00:00:00 2001 From: param Date: Thu, 22 Feb 2018 23:36:33 +0530 Subject: [PATCH] Support for Commands Supported and Effects Log Page Change-Id: If28662585887b613e3510a8fd8414caeca9ba99b Signed-off-by: param Reviewed-on: https://review.gerrithub.io/401314 Reviewed-by: Daniel Verkamp Tested-by: SPDK Automated Test System Reviewed-by: Jim Harris --- include/spdk/nvme_spec.h | 43 ++++++++++++++++++++++ lib/nvmf/ctrlr.c | 3 ++ lib/nvmf/nvmf.c | 52 +++++++++++++++++++++++++++ lib/nvmf/nvmf_internal.h | 2 ++ test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c | 3 ++ 5 files changed, 103 insertions(+) diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index 48a1ad5ef..653736fff 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -1749,6 +1749,49 @@ struct __attribute__((packed)) spdk_nvme_health_information_page { }; SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_health_information_page) == 512, "Incorrect size"); +/* Commands Supported and Effects Data Structure */ +struct spdk_nvme_cmds_and_effect_entry { + /** Command Supported */ + uint16_t csupp : 1; + + /** Logic Block Content Change */ + uint16_t lbcc : 1; + + /** Namespace Capability Change */ + uint16_t ncc : 1; + + /** Namespace Inventory Change */ + uint16_t nic : 1; + + /** Controller Capability Change */ + uint16_t ccc : 1; + + uint16_t reserved1 : 11; + + /* Command Submission and Execution recommendation + * 000 - No command submission or execution restriction + * 001 - Submitted when there is no outstanding command to same NS + * 010 - Submitted when there is no outstanding command to any NS + * others - Reserved + * \ref command_submission_and_execution in section 5.14.1.5 NVMe Revision 1.3 + */ + uint16_t cse : 3; + + uint16_t reserved2 : 13; +}; + +/* Commands Supported and Effects Log Page */ +struct spdk_nvme_cmds_and_effect_log_page { + /** Commands Supported and Effects Data Structure for the Admin Commands */ + struct spdk_nvme_cmds_and_effect_entry admin_cmds_supported[256]; + + /** Commands Supported and Effects Data Structure for the IO Commands */ + struct spdk_nvme_cmds_and_effect_entry io_cmds_supported[256]; + + uint8_t reserved0[2048]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_cmds_and_effect_log_page) == 4096, "Incorrect size"); + /** * Asynchronous Event Type */ diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 7deba751e..06c93c6bd 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -891,6 +891,9 @@ spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req) case SPDK_NVME_LOG_FIRMWARE_SLOT: /* TODO: actually fill out log page data */ return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG: + spdk_nvmf_get_cmds_and_effects_log_page(req->data, offset, len); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; default: goto invalid_log_page; } diff --git a/lib/nvmf/nvmf.c b/lib/nvmf/nvmf.c index c52a2bea7..e37cbb869 100644 --- a/lib/nvmf/nvmf.c +++ b/lib/nvmf/nvmf.c @@ -596,6 +596,58 @@ spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, return 0; } +/* The structure can be modified if we provide support for other commands in future */ +static const struct spdk_nvme_cmds_and_effect_log_page g_cmds_and_effect_log_page = { + .admin_cmds_supported = { + /* CSUPP, LBCC, NCC, NIC, CCC, CSE */ + /* Get Log Page */ + [SPDK_NVME_OPC_GET_LOG_PAGE] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Identify */ + [SPDK_NVME_OPC_IDENTIFY] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Abort */ + [SPDK_NVME_OPC_ABORT] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Set Features */ + [SPDK_NVME_OPC_SET_FEATURES] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Get Features */ + [SPDK_NVME_OPC_GET_FEATURES] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Async Event Request */ + [SPDK_NVME_OPC_ASYNC_EVENT_REQUEST] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* Keep Alive */ + [SPDK_NVME_OPC_KEEP_ALIVE] = {1, 0, 0, 0, 0, 0, 0, 0}, + }, + .io_cmds_supported = { + /* FLUSH */ + [SPDK_NVME_OPC_FLUSH] = {1, 1, 0, 0, 0, 0, 0, 0}, + /* WRITE */ + [SPDK_NVME_OPC_WRITE] = {1, 1, 0, 0, 0, 0, 0, 0}, + /* READ */ + [SPDK_NVME_OPC_READ] = {1, 0, 0, 0, 0, 0, 0, 0}, + /* WRITE ZEROES */ + [SPDK_NVME_OPC_WRITE_ZEROES] = {1, 1, 0, 0, 0, 0, 0, 0}, + /* DATASET MANAGEMENT */ + [SPDK_NVME_OPC_DATASET_MANAGEMENT] = {1, 1, 0, 0, 0, 0, 0, 0}, + }, +}; + +void +spdk_nvmf_get_cmds_and_effects_log_page(void *buffer, + uint64_t offset, uint32_t length) +{ + uint32_t page_size = sizeof(struct spdk_nvme_cmds_and_effect_log_page); + size_t copy_len = 0; + size_t zero_len = length; + + if (offset < page_size) { + copy_len = spdk_min(page_size - offset, length); + zero_len -= copy_len; + memcpy(buffer, (char *)(&g_cmds_and_effect_log_page) + offset, copy_len); + } + + if (zero_len) { + memset((char *)buffer + copy_len, 0, zero_len); + } +} + SPDK_TRACE_REGISTER_FN(nvmf_trace) { spdk_trace_register_object(OBJECT_NVMF_IO, 'r'); diff --git a/lib/nvmf/nvmf_internal.h b/lib/nvmf/nvmf_internal.h index 7eec61245..5ee4b4ef3 100644 --- a/lib/nvmf/nvmf_internal.h +++ b/lib/nvmf/nvmf_internal.h @@ -228,6 +228,8 @@ int spdk_nvmf_request_abort(struct spdk_nvmf_request *req); void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, void *buffer, uint64_t offset, uint32_t length); +void spdk_nvmf_get_cmds_and_effects_log_page(void *buffer, + uint64_t offset, uint32_t length); struct spdk_nvmf_qpair *spdk_nvmf_ctrlr_get_qpair(struct spdk_nvmf_ctrlr *ctrlr, uint16_t qid); void spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr); diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index 0e91bd01c..f00d7df82 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -126,6 +126,9 @@ DEFINE_STUB(spdk_nvmf_bdev_ctrlr_identify_ns, DEFINE_STUB_V(spdk_nvmf_get_discovery_log_page, (struct spdk_nvmf_tgt *tgt, void *buffer, uint64_t offset, uint32_t length)) +DEFINE_STUB_V(spdk_nvmf_get_cmds_and_effects_log_page, + (void *buffer, uint64_t offset, uint32_t length)) + DEFINE_STUB(spdk_nvmf_request_complete, int, (struct spdk_nvmf_request *req),