lib/nvme: add two async API for Directive Send and Directive Receive.
Add two async API for Directive Send and Directive Receive. spdk_nvme_ctrlr_cmd_directive_send; spdk_nvme_ctrlr_cmd_directive_receive; Signed-off-by: sunshihao <sunshihao@huawei.com> Change-Id: Icb6974f74902df1512a5ffa9835188132634291b Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5803 Community-CI: Broadcom CI Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
parent
e69af13dea
commit
5fba455d3e
@ -42,6 +42,9 @@ Updated DPDK submodule to DPDK 20.11.
|
||||
|
||||
Directives support was added to the NVMe driver.
|
||||
|
||||
Two async APIs 'spdk_nvme_ctrlr_cmd_directive_receive' and 'spdk_nvme_ctrlr_cmd_directive_send'
|
||||
are added for Directive Send and Directive Receive command, respectively.
|
||||
|
||||
Added a new function `spdk_nvme_ctrlr_reset_subsystem` to perform a NVMe
|
||||
subsystem reset. Note: The NVMf target does not support the subsystem reset yet.
|
||||
Add a new function 'spdk_nvme_bytes_to_numd' to transfer bytes to number of
|
||||
|
@ -1912,6 +1912,62 @@ int spdk_nvme_ctrlr_security_receive(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp
|
||||
int spdk_nvme_ctrlr_security_send(struct spdk_nvme_ctrlr *ctrlr, uint8_t secp,
|
||||
uint16_t spsp, uint8_t nssf, void *payload, size_t size);
|
||||
|
||||
/**
|
||||
* Receive data related to a specific Directive Type from the controller.
|
||||
*
|
||||
* This function is thread safe and can be called at any point after spdk_nvme_probe().
|
||||
*
|
||||
* Call spdk_nvme_ctrlr_process_admin_completions() to poll for completion of
|
||||
* commands submitted through this function.
|
||||
*
|
||||
* \param ctrlr NVMe controller to use for directive receive command submission.
|
||||
* \param nsid Specific Namespace Identifier.
|
||||
* \param doper Directive Operation defined in nvme_spec.h.
|
||||
* \param dtype Directive Type defined in nvme_spec.h.
|
||||
* \param dspec Directive Specific defined in nvme_spec.h.
|
||||
* \param payload The pointer to the payload buffer.
|
||||
* \param payload_size The size of payload buffer.
|
||||
* \param cdw12 Command dword 12.
|
||||
* \param cdw13 Command dword 13.
|
||||
* \param cb_fn Callback function to invoke when the command has been completed.
|
||||
* \param cb_arg Argument to pass to the callback function.
|
||||
*
|
||||
* \return 0 if successfully submitted, negated errno if resources could not be allocated
|
||||
* for this request.
|
||||
*/
|
||||
int spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
|
||||
|
||||
/**
|
||||
* Send data related to a specific Directive Type to the controller.
|
||||
*
|
||||
* This function is thread safe and can be called at any point after spdk_nvme_probe().
|
||||
*
|
||||
* Call spdk_nvme_ctrlr_process_admin_completions() to poll for completion of
|
||||
* commands submitted through this function.
|
||||
*
|
||||
* \param ctrlr NVMe controller to use for directive send command submission.
|
||||
* \param nsid Specific Namespace Identifier.
|
||||
* \param doper Directive Operation defined in nvme_spec.h.
|
||||
* \param dtype Directive Type defined in nvme_spec.h.
|
||||
* \param dspec Directive Specific defined in nvme_spec.h.
|
||||
* \param payload The pointer to the payload buffer.
|
||||
* \param payload_size The size of payload buffer.
|
||||
* \param cdw12 Command dword 12.
|
||||
* \param cdw13 Command dword 13.
|
||||
* \param cb_fn Callback function to invoke when the command has been completed.
|
||||
* \param cb_arg Argument to pass to the callback function.
|
||||
*
|
||||
* \return 0 if successfully submitted, negated errno if resources could not be allocated
|
||||
* for this request.
|
||||
*/
|
||||
int spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg);
|
||||
|
||||
/**
|
||||
* Get supported flags of the controller.
|
||||
*
|
||||
|
@ -1570,6 +1570,10 @@ nvme_ctrlr_identify_done(void *arg, const struct spdk_nvme_cpl *cpl)
|
||||
ctrlr->flags |= SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED;
|
||||
}
|
||||
|
||||
if (ctrlr->cdata.oacs.directives) {
|
||||
ctrlr->flags |= SPDK_NVME_CTRLR_DIRECTIVES_SUPPORTED;
|
||||
}
|
||||
|
||||
SPDK_DEBUGLOG(nvme, "fuses compare and write: %d\n", ctrlr->cdata.fuses.compare_and_write);
|
||||
if (ctrlr->cdata.fuses.compare_and_write) {
|
||||
ctrlr->flags |= SPDK_NVME_CTRLR_COMPARE_AND_WRITE_SUPPORTED;
|
||||
|
@ -965,3 +965,59 @@ nvme_ctrlr_cmd_sanitize(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
nvme_ctrlr_cmd_directive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg,
|
||||
uint16_t opc_type, bool host_to_ctrlr)
|
||||
{
|
||||
struct nvme_request *req = NULL;
|
||||
struct spdk_nvme_cmd *cmd = NULL;
|
||||
int rc;
|
||||
|
||||
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
|
||||
req = nvme_allocate_request_user_copy(ctrlr->adminq, payload, payload_size,
|
||||
cb_fn, cb_arg, host_to_ctrlr);
|
||||
if (req == NULL) {
|
||||
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cmd = &req->cmd;
|
||||
cmd->opc = opc_type;
|
||||
cmd->nsid = nsid;
|
||||
|
||||
cmd->cdw10 = (payload_size >> 2) - 1;
|
||||
cmd->cdw11_bits.directive.doper = doper;
|
||||
cmd->cdw11_bits.directive.dtype = dtype;
|
||||
cmd->cdw11_bits.directive.dspec = dspec;
|
||||
cmd->cdw12 = cdw12;
|
||||
cmd->cdw13 = cdw13;
|
||||
rc = nvme_ctrlr_submit_admin_request(ctrlr, req);
|
||||
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
|
||||
payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
|
||||
SPDK_NVME_OPC_DIRECTIVE_SEND, true);
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
return nvme_ctrlr_cmd_directive(ctrlr, nsid, doper, dtype, dspec,
|
||||
payload, payload_size, cdw12, cdw13, cb_fn, cb_arg,
|
||||
SPDK_NVME_OPC_DIRECTIVE_RECEIVE, false);
|
||||
}
|
||||
|
@ -74,6 +74,8 @@
|
||||
spdk_nvme_ctrlr_cmd_security_send;
|
||||
spdk_nvme_ctrlr_security_receive;
|
||||
spdk_nvme_ctrlr_security_send;
|
||||
spdk_nvme_ctrlr_cmd_directive_receive;
|
||||
spdk_nvme_ctrlr_cmd_directive_send;
|
||||
spdk_nvme_ctrlr_get_flags;
|
||||
spdk_nvme_ctrlr_attach_ns;
|
||||
spdk_nvme_ctrlr_detach_ns;
|
||||
|
@ -439,6 +439,24 @@ nvme_ctrlr_cmd_format(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, struct spdk_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvme_ctrlr_cmd_directive_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_nvme_ctrlr_cmd_directive_receive(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid,
|
||||
uint32_t doper, uint32_t dtype, uint32_t dspec,
|
||||
void *payload, uint32_t payload_size, uint32_t cdw12,
|
||||
uint32_t cdw13, spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nvme_ctrlr_cmd_fw_commit(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_fw_commit *fw_commit,
|
||||
spdk_nvme_cmd_cb cb_fn, void *cb_arg)
|
||||
|
@ -61,6 +61,7 @@ uint64_t PRP_ENTRY_2 = 4096;
|
||||
uint32_t format_nvme_nsid = 1;
|
||||
uint32_t sanitize_nvme_nsid = 1;
|
||||
uint32_t expected_host_id_size = 0xFF;
|
||||
uint32_t directive_nsid = 1;
|
||||
|
||||
uint32_t expected_feature_ns = 2;
|
||||
uint32_t expected_feature_cdw10 = SPDK_NVME_FEAT_LBA_RANGE_TYPE;
|
||||
@ -325,6 +326,18 @@ static void verify_nvme_sanitize(struct nvme_request *req)
|
||||
CU_ASSERT(req->cmd.nsid == sanitize_nvme_nsid);
|
||||
}
|
||||
|
||||
static void verify_directive_receive(struct nvme_request *req)
|
||||
{
|
||||
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_DIRECTIVE_RECEIVE);
|
||||
CU_ASSERT(req->cmd.nsid == directive_nsid);
|
||||
}
|
||||
|
||||
static void verify_directive_send(struct nvme_request *req)
|
||||
{
|
||||
CU_ASSERT(req->cmd.opc == SPDK_NVME_OPC_DIRECTIVE_SEND);
|
||||
CU_ASSERT(req->cmd.nsid == directive_nsid);
|
||||
}
|
||||
|
||||
struct nvme_request *
|
||||
nvme_allocate_request_user_copy(struct spdk_nvme_qpair *qpair, void *buffer, uint32_t payload_size,
|
||||
spdk_nvme_cmd_cb cb_fn, void *cb_arg, bool host_to_controller)
|
||||
@ -723,6 +736,33 @@ test_sanitize(void)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
test_directive_receive(void)
|
||||
{
|
||||
DECLARE_AND_CONSTRUCT_CTRLR();
|
||||
verify_fn = verify_directive_receive;
|
||||
|
||||
spdk_nvme_ctrlr_cmd_directive_receive(&ctrlr, directive_nsid, 0, 0, 0, NULL, 0,
|
||||
0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_directive_send(void)
|
||||
{
|
||||
DECLARE_AND_CONSTRUCT_CTRLR();
|
||||
verify_fn = verify_directive_send;
|
||||
|
||||
spdk_nvme_ctrlr_cmd_directive_send(&ctrlr, directive_nsid, 0, 0, 0, NULL, 0,
|
||||
0, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_directive(void)
|
||||
{
|
||||
test_directive_receive();
|
||||
test_directive_send();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CU_pSuite suite = NULL;
|
||||
@ -752,6 +792,7 @@ int main(int argc, char **argv)
|
||||
CU_ADD_TEST(suite, test_fw_commit);
|
||||
CU_ADD_TEST(suite, test_fw_image_download);
|
||||
CU_ADD_TEST(suite, test_sanitize);
|
||||
CU_ADD_TEST(suite, test_directive);
|
||||
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
CU_basic_run_tests();
|
||||
|
Loading…
Reference in New Issue
Block a user