From ab1f6bdc54fc52025b79737f28610bf3f04c2d8b Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 27 May 2016 08:39:45 -0700 Subject: [PATCH] nvme: add enum for opcode data direction NVMe opcodes contain a two-bit field that encodes the expected data direction for each command. Add an enum and a function to extract these bits. Change-Id: Ie214319f121cf0899c6aa5663866f2988b128dd2 Signed-off-by: Daniel Verkamp --- include/spdk/nvme_spec.h | 28 ++++++++++++++++++++++++++++ test/lib/nvme/nvme.sh | 2 +- test/lib/nvme/unit/nvme_c/nvme_ut.c | 23 +++++++++++++++++++---- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index 321074281..42d7073f7 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -526,6 +526,34 @@ enum spdk_nvme_nvm_opcode { SPDK_NVME_OPC_RESERVATION_RELEASE = 0x15, }; +/** + * Data transfer (bits 1:0) of an NVMe opcode. + * + * \sa spdk_nvme_opc_get_data_transfer + */ +enum spdk_nvme_data_transfer { + /** Opcode does not transfer data */ + SPDK_NVME_DATA_NONE = 0, + /** Opcode transfers data from host to controller (e.g. Write) */ + SPDK_NVME_DATA_HOST_TO_CONTROLLER = 1, + /** Opcode transfers data from controller to host (e.g. Read) */ + SPDK_NVME_DATA_CONTROLLER_TO_HOST = 2, + /** Opcode transfers data both directions */ + SPDK_NVME_DATA_BIDIRECTIONAL = 3 +}; + +/** + * Extract the Data Transfer bits from an NVMe opcode. + * + * This determines whether a command requires a data buffer and + * which direction (host to controller or controller to host) it is + * transferred. + */ +static inline enum spdk_nvme_data_transfer spdk_nvme_opc_get_data_transfer(uint8_t opc) +{ + return opc & 3; +} + enum spdk_nvme_feat { /* 0x00 - reserved */ SPDK_NVME_FEAT_ARBITRATION = 0x01, diff --git a/test/lib/nvme/nvme.sh b/test/lib/nvme/nvme.sh index 4bbe55864..fcd7898e4 100755 --- a/test/lib/nvme/nvme.sh +++ b/test/lib/nvme/nvme.sh @@ -14,7 +14,7 @@ timing_enter nvme timing_enter unit $valgrind $testdir/unit/nvme_ns_cmd_c/nvme_ns_cmd_ut -$testdir/unit/nvme_c/nvme_ut +$valgrind $testdir/unit/nvme_c/nvme_ut $valgrind $testdir/unit/nvme_qpair_c/nvme_qpair_ut $valgrind $testdir/unit/nvme_ctrlr_c/nvme_ctrlr_ut $valgrind $testdir/unit/nvme_ctrlr_cmd_c/nvme_ctrlr_cmd_ut diff --git a/test/lib/nvme/unit/nvme_c/nvme_ut.c b/test/lib/nvme/unit/nvme_c/nvme_ut.c index e11c125e7..08a6a5051 100644 --- a/test/lib/nvme/unit/nvme_c/nvme_ut.c +++ b/test/lib/nvme/unit/nvme_c/nvme_ut.c @@ -71,6 +71,24 @@ spdk_nvme_ctrlr_opts_set_defaults(struct spdk_nvme_ctrlr_opts *opts) memset(opts, 0, sizeof(*opts)); } +static void +test_opc_data_transfer(void) +{ + enum spdk_nvme_data_transfer xfer; + + xfer = spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_FLUSH); + CU_ASSERT(xfer == SPDK_NVME_DATA_NONE); + + xfer = spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_WRITE); + CU_ASSERT(xfer == SPDK_NVME_DATA_HOST_TO_CONTROLLER); + + xfer = spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_READ); + CU_ASSERT(xfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST); + + xfer = spdk_nvme_opc_get_data_transfer(SPDK_NVME_OPC_GET_LOG_PAGE); + CU_ASSERT(xfer == SPDK_NVME_DATA_CONTROLLER_TO_HOST); +} + int main(int argc, char **argv) { CU_pSuite suite = NULL; @@ -86,15 +104,12 @@ int main(int argc, char **argv) return CU_get_error(); } -#if 0 if ( - CU_add_test(suite, "test1", test1) == NULL - || CU_add_test(suite, "test2", test2) == NULL + CU_add_test(suite, "test_opc_data_transfer", test_opc_data_transfer) == NULL ) { CU_cleanup_registry(); return CU_get_error(); } -#endif CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests();