Loading include/spdk/nvme.h +9 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,15 @@ uint32_t nvme_ctrlr_get_num_ns(struct nvme_controller *ctrlr); */ bool nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page); /** * \brief Determine if a particular feature is supported by the given NVMe controller. * * This function is thread safe and can be called at any point after nvme_attach(). * * \sa nvme_ctrlr_cmd_get_feature() */ bool nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code); /** * Signature for callback function invoked when a command is completed. * Loading include/spdk/nvme_spec.h +2 −0 Original line number Diff line number Diff line Loading @@ -449,6 +449,8 @@ enum nvme_feature { NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09, NVME_FEAT_WRITE_ATOMICITY = 0x0A, NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B, NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C, NVME_FEAT_HOST_MEM_BUFFER = 0x0D, /* 0x0C-0x7F - reserved */ NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80, /* 0x81-0xBF - command set specific */ Loading lib/nvme/nvme_ctrlr.c +50 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,47 @@ nvme_ctrlr_set_supported_log_pages(struct nvme_controller *ctrlr) } } static void nvme_ctrlr_set_intel_supported_features(struct nvme_controller *ctrlr) { ctrlr->feature_supported[NVME_INTEL_FEAT_MAX_LBA] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_NATIVE_MAX_LBA] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_SMBUS_ADDRESS] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_LED_PATTERN] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_LATENCY_TRACKING] = true; } static void nvme_ctrlr_set_supported_features(struct nvme_controller *ctrlr) { memset(ctrlr->feature_supported, 0, sizeof(ctrlr->feature_supported)); /* Mandatory features */ ctrlr->feature_supported[NVME_FEAT_ARBITRATION] = true; ctrlr->feature_supported[NVME_FEAT_POWER_MANAGEMENT] = true; ctrlr->feature_supported[NVME_FEAT_TEMPERATURE_THRESHOLD] = true; ctrlr->feature_supported[NVME_FEAT_ERROR_RECOVERY] = true; ctrlr->feature_supported[NVME_FEAT_NUMBER_OF_QUEUES] = true; ctrlr->feature_supported[NVME_FEAT_INTERRUPT_COALESCING] = true; ctrlr->feature_supported[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION] = true; ctrlr->feature_supported[NVME_FEAT_WRITE_ATOMICITY] = true; ctrlr->feature_supported[NVME_FEAT_ASYNC_EVENT_CONFIGURATION] = true; /* Optional features */ if (ctrlr->cdata.vwc.present) { ctrlr->feature_supported[NVME_FEAT_VOLATILE_WRITE_CACHE] = true; } if (ctrlr->cdata.apsta.supported) { ctrlr->feature_supported[NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION] = true; } if (ctrlr->cdata.hmpre) { ctrlr->feature_supported[NVME_FEAT_HOST_MEM_BUFFER] = true; } if (ctrlr->cdata.vid == PCI_VENDOR_ID_INTEL) { nvme_ctrlr_set_intel_supported_features(ctrlr); } } static int nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr) { Loading Loading @@ -693,6 +734,7 @@ nvme_ctrlr_start(struct nvme_controller *ctrlr) } nvme_ctrlr_set_supported_log_pages(ctrlr); nvme_ctrlr_set_supported_features(ctrlr); return 0; } Loading Loading @@ -863,3 +905,11 @@ nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page SPDK_STATIC_ASSERT(sizeof(ctrlr->log_page_supported) == 256, "log_page_supported size mismatch"); return ctrlr->log_page_supported[log_page]; } bool nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code) { /* No bounds check necessary, since feature_code is uint8_t and feature_supported has 256 entries */ SPDK_STATIC_ASSERT(sizeof(ctrlr->feature_supported) == 256, "feature_supported size mismatch"); return ctrlr->feature_supported[feature_code]; } lib/nvme/nvme_internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,9 @@ struct nvme_controller { /** All the log pages supported */ bool log_page_supported[256]; /** All the features supported */ bool feature_supported[256]; /* Opaque handle to associated PCI device. */ void *devhandle; Loading test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c +24 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,28 @@ test_nvme_ctrlr_construct_intel_support_log_page_list(void) CU_ASSERT(res == false); } static void test_nvme_ctrlr_set_supported_features(void) { bool res; struct nvme_controller ctrlr = {}; /* set a invalid vendor id */ ctrlr.cdata.vid = 0xFFFF; nvme_ctrlr_set_supported_features(&ctrlr); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_FEAT_ARBITRATION); CU_ASSERT(res == true); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_INTEL_FEAT_MAX_LBA); CU_ASSERT(res == false); ctrlr.cdata.vid = PCI_VENDOR_ID_INTEL; nvme_ctrlr_set_supported_features(&ctrlr); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_FEAT_ARBITRATION); CU_ASSERT(res == true); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_INTEL_FEAT_MAX_LBA); CU_ASSERT(res == true); } int main(int argc, char **argv) { CU_pSuite suite = NULL; Loading @@ -244,6 +266,8 @@ int main(int argc, char **argv) CU_add_test(suite, "test nvme_ctrlr function nvme_ctrlr_fail", test_nvme_ctrlr_fail) == NULL || CU_add_test(suite, "test nvme ctrlr function nvme_ctrlr_construct_intel_support_log_page_list", test_nvme_ctrlr_construct_intel_support_log_page_list) == NULL || CU_add_test(suite, "test nvme ctrlr function nvme_ctrlr_set_supported_features", test_nvme_ctrlr_set_supported_features) == NULL ) { CU_cleanup_registry(); return CU_get_error(); Loading Loading
include/spdk/nvme.h +9 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,15 @@ uint32_t nvme_ctrlr_get_num_ns(struct nvme_controller *ctrlr); */ bool nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page); /** * \brief Determine if a particular feature is supported by the given NVMe controller. * * This function is thread safe and can be called at any point after nvme_attach(). * * \sa nvme_ctrlr_cmd_get_feature() */ bool nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code); /** * Signature for callback function invoked when a command is completed. * Loading
include/spdk/nvme_spec.h +2 −0 Original line number Diff line number Diff line Loading @@ -449,6 +449,8 @@ enum nvme_feature { NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09, NVME_FEAT_WRITE_ATOMICITY = 0x0A, NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B, NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C, NVME_FEAT_HOST_MEM_BUFFER = 0x0D, /* 0x0C-0x7F - reserved */ NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80, /* 0x81-0xBF - command set specific */ Loading
lib/nvme/nvme_ctrlr.c +50 −0 Original line number Diff line number Diff line Loading @@ -113,6 +113,47 @@ nvme_ctrlr_set_supported_log_pages(struct nvme_controller *ctrlr) } } static void nvme_ctrlr_set_intel_supported_features(struct nvme_controller *ctrlr) { ctrlr->feature_supported[NVME_INTEL_FEAT_MAX_LBA] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_NATIVE_MAX_LBA] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_POWER_GOVERNOR_SETTING] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_SMBUS_ADDRESS] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_LED_PATTERN] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_RESET_TIMED_WORKLOAD_COUNTERS] = true; ctrlr->feature_supported[NVME_INTEL_FEAT_LATENCY_TRACKING] = true; } static void nvme_ctrlr_set_supported_features(struct nvme_controller *ctrlr) { memset(ctrlr->feature_supported, 0, sizeof(ctrlr->feature_supported)); /* Mandatory features */ ctrlr->feature_supported[NVME_FEAT_ARBITRATION] = true; ctrlr->feature_supported[NVME_FEAT_POWER_MANAGEMENT] = true; ctrlr->feature_supported[NVME_FEAT_TEMPERATURE_THRESHOLD] = true; ctrlr->feature_supported[NVME_FEAT_ERROR_RECOVERY] = true; ctrlr->feature_supported[NVME_FEAT_NUMBER_OF_QUEUES] = true; ctrlr->feature_supported[NVME_FEAT_INTERRUPT_COALESCING] = true; ctrlr->feature_supported[NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION] = true; ctrlr->feature_supported[NVME_FEAT_WRITE_ATOMICITY] = true; ctrlr->feature_supported[NVME_FEAT_ASYNC_EVENT_CONFIGURATION] = true; /* Optional features */ if (ctrlr->cdata.vwc.present) { ctrlr->feature_supported[NVME_FEAT_VOLATILE_WRITE_CACHE] = true; } if (ctrlr->cdata.apsta.supported) { ctrlr->feature_supported[NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION] = true; } if (ctrlr->cdata.hmpre) { ctrlr->feature_supported[NVME_FEAT_HOST_MEM_BUFFER] = true; } if (ctrlr->cdata.vid == PCI_VENDOR_ID_INTEL) { nvme_ctrlr_set_intel_supported_features(ctrlr); } } static int nvme_ctrlr_construct_admin_qpair(struct nvme_controller *ctrlr) { Loading Loading @@ -693,6 +734,7 @@ nvme_ctrlr_start(struct nvme_controller *ctrlr) } nvme_ctrlr_set_supported_log_pages(ctrlr); nvme_ctrlr_set_supported_features(ctrlr); return 0; } Loading Loading @@ -863,3 +905,11 @@ nvme_ctrlr_is_log_page_supported(struct nvme_controller *ctrlr, uint8_t log_page SPDK_STATIC_ASSERT(sizeof(ctrlr->log_page_supported) == 256, "log_page_supported size mismatch"); return ctrlr->log_page_supported[log_page]; } bool nvme_ctrlr_is_feature_supported(struct nvme_controller *ctrlr, uint8_t feature_code) { /* No bounds check necessary, since feature_code is uint8_t and feature_supported has 256 entries */ SPDK_STATIC_ASSERT(sizeof(ctrlr->feature_supported) == 256, "feature_supported size mismatch"); return ctrlr->feature_supported[feature_code]; }
lib/nvme/nvme_internal.h +3 −0 Original line number Diff line number Diff line Loading @@ -299,6 +299,9 @@ struct nvme_controller { /** All the log pages supported */ bool log_page_supported[256]; /** All the features supported */ bool feature_supported[256]; /* Opaque handle to associated PCI device. */ void *devhandle; Loading
test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c +24 −0 Original line number Diff line number Diff line Loading @@ -225,6 +225,28 @@ test_nvme_ctrlr_construct_intel_support_log_page_list(void) CU_ASSERT(res == false); } static void test_nvme_ctrlr_set_supported_features(void) { bool res; struct nvme_controller ctrlr = {}; /* set a invalid vendor id */ ctrlr.cdata.vid = 0xFFFF; nvme_ctrlr_set_supported_features(&ctrlr); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_FEAT_ARBITRATION); CU_ASSERT(res == true); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_INTEL_FEAT_MAX_LBA); CU_ASSERT(res == false); ctrlr.cdata.vid = PCI_VENDOR_ID_INTEL; nvme_ctrlr_set_supported_features(&ctrlr); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_FEAT_ARBITRATION); CU_ASSERT(res == true); res = nvme_ctrlr_is_feature_supported(&ctrlr, NVME_INTEL_FEAT_MAX_LBA); CU_ASSERT(res == true); } int main(int argc, char **argv) { CU_pSuite suite = NULL; Loading @@ -244,6 +266,8 @@ int main(int argc, char **argv) CU_add_test(suite, "test nvme_ctrlr function nvme_ctrlr_fail", test_nvme_ctrlr_fail) == NULL || CU_add_test(suite, "test nvme ctrlr function nvme_ctrlr_construct_intel_support_log_page_list", test_nvme_ctrlr_construct_intel_support_log_page_list) == NULL || CU_add_test(suite, "test nvme ctrlr function nvme_ctrlr_set_supported_features", test_nvme_ctrlr_set_supported_features) == NULL ) { CU_cleanup_registry(); return CU_get_error(); Loading