nvme: add Get/Set Feature wrappers with NSID

Some features are per namespace and require a namespace ID; the existing
get/set feature functions do not allow passing NSID, so add new API
functions that do:
* spdk_nvme_ctrlr_cmd_get_feature_ns
* spdk_nvme_ctrlr_cmd_set_feature_ns

Change-Id: Ia7dc96e57badf1a56489785fb288493592b58b80
Signed-off-by: Jakub Radtke <jakub.radtke@intel.com>
Reviewed-on: https://review.gerrithub.io/414706
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Jakub Radtke 2018-06-11 15:15:18 -07:00 committed by Jim Harris
parent caac0ed9e8
commit b3497d5da7
3 changed files with 163 additions and 0 deletions

View File

@ -876,6 +876,62 @@ int spdk_nvme_ctrlr_cmd_get_feature(struct spdk_nvme_ctrlr *ctrlr,
void *payload, uint32_t payload_size,
spdk_nvme_cmd_cb cb_fn, void *cb_arg);
/**
* \brief Get specific feature from given NVMe controller.
*
* \param ctrlr NVMe controller to query.
* \param feature The feature identifier.
* \param cdw11 as defined by the specification for this command.
* \param payload The pointer to the payload buffer.
* \param payload_size The size of payload buffer.
* \param cb_fn Callback function to invoke when the feature has been retrieved.
* \param cb_arg Argument to pass to the callback function.
* \param ns_is The namespace identifier.
*
* \return 0 if successfully submitted, ENOMEM if resources could not be allocated
* for this request
*
* This function is thread safe and can be called at any point while the controller
* is attached to the SPDK NVMe driver.
*
* Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
* of commands submitted through this function.
*
* \sa spdk_nvme_ctrlr_cmd_set_feature_ns()
*/
int spdk_nvme_ctrlr_cmd_get_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
uint32_t cdw11, void *payload, uint32_t payload_size,
spdk_nvme_cmd_cb cb_fn, void *cb_arg, uint32_t ns_id);
/**
* \brief Set specific feature for the given NVMe controller and namespace ID.
*
* \param ctrlr NVMe controller to manipulate.
* \param feature The feature identifier.
* \param cdw11 as defined by the specification for this command.
* \param cdw12 as defined by the specification for this command.
* \param payload The pointer to the payload buffer.
* \param payload_size The size of payload buffer.
* \param cb_fn Callback function to invoke when the feature has been set.
* \param cb_arg Argument to pass to the callback function.
* \param ns_is The namespace identifier.
*
* \return 0 if successfully submitted, ENOMEM if resources could not be allocated
* for this request.
*
* This function is thread safe and can be called at any point while the controller
* is attached to the SPDK NVMe driver.
*
* Call \ref spdk_nvme_ctrlr_process_admin_completions() to poll for completion
* of commands submitted through this function.
*
* \sa spdk_nvme_ctrlr_cmd_get_feature_ns()
*/
int spdk_nvme_ctrlr_cmd_set_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
uint32_t cdw11, uint32_t cdw12, void *payload,
uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
void *cb_arg, uint32_t ns_id);
/**
* \brief Attach the specified namespace to controllers.
*

View File

@ -340,6 +340,66 @@ spdk_nvme_ctrlr_cmd_get_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
return rc;
}
int
spdk_nvme_ctrlr_cmd_get_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
uint32_t cdw11, void *payload,
uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
void *cb_arg, uint32_t ns_id)
{
struct nvme_request *req;
struct spdk_nvme_cmd *cmd;
int rc;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
false);
if (req == NULL) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return -ENOMEM;
}
cmd = &req->cmd;
cmd->opc = SPDK_NVME_OPC_GET_FEATURES;
cmd->cdw10 = feature;
cmd->cdw11 = cdw11;
cmd->nsid = ns_id;
rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return rc;
}
int spdk_nvme_ctrlr_cmd_set_feature_ns(struct spdk_nvme_ctrlr *ctrlr, uint8_t feature,
uint32_t cdw11, uint32_t cdw12, void *payload,
uint32_t payload_size, spdk_nvme_cmd_cb cb_fn,
void *cb_arg, uint32_t ns_id)
{
struct nvme_request *req;
struct spdk_nvme_cmd *cmd;
int rc;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size, cb_fn, cb_arg,
true);
if (req == NULL) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return -ENOMEM;
}
cmd = &req->cmd;
cmd->opc = SPDK_NVME_OPC_SET_FEATURES;
cmd->cdw10 = feature;
cmd->cdw11 = cdw11;
cmd->cdw12 = cdw12;
cmd->nsid = ns_id;
rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return rc;
}
int
nvme_ctrlr_cmd_set_num_queues(struct spdk_nvme_ctrlr *ctrlr,
uint32_t num_queues, spdk_nvme_cmd_cb cb_fn, void *cb_arg)

View File

@ -56,6 +56,11 @@ uint16_t abort_sqid = 1;
uint32_t namespace_management_nsid = 1;
uint32_t format_nvme_nsid = 1;
uint32_t expected_feature_ns = 2;
uint32_t expected_feature_cdw10 = SPDK_NVME_FEAT_LBA_RANGE_TYPE;
uint32_t expected_feature_cdw11 = 1;
uint32_t expected_feature_cdw12 = 1;
typedef void (*verify_request_fn_t)(struct nvme_request *req);
verify_request_fn_t verify_fn;
@ -103,6 +108,15 @@ static void verify_set_feature_cmd(struct nvme_request *req)
CU_ASSERT(req->cmd.cdw12 == feature_cdw12);
}
static void verify_set_feature_ns_cmd(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_SET_FEATURES);
CU_ASSERT(req->cmd.cdw10 == expected_feature_cdw10);
CU_ASSERT(req->cmd.cdw11 == expected_feature_cdw11);
CU_ASSERT(req->cmd.cdw12 == expected_feature_cdw12);
CU_ASSERT(req->cmd.nsid == expected_feature_ns);
}
static void verify_get_feature_cmd(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_GET_FEATURES);
@ -110,6 +124,14 @@ static void verify_get_feature_cmd(struct nvme_request *req)
CU_ASSERT(req->cmd.cdw11 == get_feature_cdw11);
}
static void verify_get_feature_ns_cmd(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_GET_FEATURES);
CU_ASSERT(req->cmd.cdw10 == expected_feature_cdw10);
CU_ASSERT(req->cmd.cdw11 == expected_feature_cdw11);
CU_ASSERT(req->cmd.nsid == expected_feature_ns);
}
static void verify_abort_cmd(struct nvme_request *req)
{
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_ABORT);
@ -423,6 +445,29 @@ test_set_feature_cmd(void)
spdk_nvme_ctrlr_cmd_set_feature(&ctrlr, feature, feature_cdw11, feature_cdw12, NULL, 0, NULL, NULL);
}
static void
test_get_feature_ns_cmd(void)
{
DECLARE_AND_CONSTRUCT_CTRLR();
verify_fn = verify_get_feature_ns_cmd;
spdk_nvme_ctrlr_cmd_get_feature_ns(&ctrlr, expected_feature_cdw10,
expected_feature_cdw11, NULL, 0,
NULL, NULL, expected_feature_ns);
}
static void
test_set_feature_ns_cmd(void)
{
DECLARE_AND_CONSTRUCT_CTRLR();
verify_fn = verify_set_feature_ns_cmd;
spdk_nvme_ctrlr_cmd_set_feature_ns(&ctrlr, expected_feature_cdw10,
expected_feature_cdw11, expected_feature_cdw12,
NULL, 0, NULL, NULL, expected_feature_ns);
}
static void
test_get_feature_cmd(void)
@ -574,7 +619,9 @@ int main(int argc, char **argv)
if (
CU_add_test(suite, "test ctrlr cmd get_log_pages", test_get_log_pages) == NULL
|| CU_add_test(suite, "test ctrlr cmd set_feature", test_set_feature_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd set_feature_ns", test_set_feature_ns_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd get_feature", test_get_feature_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd get_feature_ns", test_get_feature_ns_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd abort_cmd", test_abort_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd io_raw_cmd", test_io_raw_cmd) == NULL
|| CU_add_test(suite, "test ctrlr cmd io_raw_cmd_with_md", test_io_raw_cmd_with_md) == NULL