diff --git a/lib/nvme/nvme_fabric.c b/lib/nvme/nvme_fabric.c index 259cb8b49..45a36a3ad 100644 --- a/lib/nvme/nvme_fabric.c +++ b/lib/nvme/nvme_fabric.c @@ -41,6 +41,13 @@ #include "spdk/endian.h" #include "spdk/string.h" +struct nvme_fabric_prop_ctx { + uint64_t value; + int size; + spdk_nvme_reg_cb cb_fn; + void *cb_arg; +}; + static int nvme_fabric_prop_set_cmd(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint8_t size, uint64_t value, @@ -92,6 +99,43 @@ nvme_fabric_prop_set_cmd_sync(struct spdk_nvme_ctrlr *ctrlr, return 0; } +static void +nvme_fabric_prop_set_cmd_done(void *ctx, const struct spdk_nvme_cpl *cpl) +{ + struct nvme_fabric_prop_ctx *prop_ctx = ctx; + + prop_ctx->cb_fn(prop_ctx->cb_arg, prop_ctx->value, cpl); + free(prop_ctx); +} + +static int +nvme_fabric_prop_set_cmd_async(struct spdk_nvme_ctrlr *ctrlr, + uint32_t offset, uint8_t size, uint64_t value, + spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + struct nvme_fabric_prop_ctx *ctx; + int rc; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + SPDK_ERRLOG("Failed to allocate fabrics property context\n"); + return -ENOMEM; + } + + ctx->value = value; + ctx->cb_fn = cb_fn; + ctx->cb_arg = cb_arg; + + rc = nvme_fabric_prop_set_cmd(ctrlr, offset, size, value, + nvme_fabric_prop_set_cmd_done, ctx); + if (rc != 0) { + SPDK_ERRLOG("Failed to send Property Set fabrics command\n"); + free(ctx); + } + + return rc; +} + static int nvme_fabric_prop_get_cmd(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint8_t size, spdk_nvme_cmd_cb cb_fn, void *cb_arg) @@ -150,6 +194,58 @@ nvme_fabric_prop_get_cmd_sync(struct spdk_nvme_ctrlr *ctrlr, return 0; } +static void +nvme_fabric_prop_get_cmd_done(void *ctx, const struct spdk_nvme_cpl *cpl) +{ + struct nvme_fabric_prop_ctx *prop_ctx = ctx; + struct spdk_nvmf_fabric_prop_get_rsp *response; + uint64_t value = 0; + + if (spdk_nvme_cpl_is_success(cpl)) { + response = (struct spdk_nvmf_fabric_prop_get_rsp *)cpl; + + switch (prop_ctx->size) { + case SPDK_NVMF_PROP_SIZE_4: + value = response->value.u32.low; + break; + case SPDK_NVMF_PROP_SIZE_8: + value = response->value.u64; + break; + default: + assert(0 && "Should never happen"); + } + } + + prop_ctx->cb_fn(prop_ctx->cb_arg, value, cpl); + free(prop_ctx); +} + +static int +nvme_fabric_prop_get_cmd_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint8_t size, + spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + struct nvme_fabric_prop_ctx *ctx; + int rc; + + ctx = calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + SPDK_ERRLOG("Failed to allocate fabrics property context\n"); + return -ENOMEM; + } + + ctx->size = size; + ctx->cb_fn = cb_fn; + ctx->cb_arg = cb_arg; + + rc = nvme_fabric_prop_get_cmd(ctrlr, offset, size, nvme_fabric_prop_get_cmd_done, ctx); + if (rc != 0) { + SPDK_ERRLOG("Failed to send Property Get fabrics command\n"); + free(ctx); + } + + return rc; +} + int nvme_fabric_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value) { @@ -181,6 +277,36 @@ nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint return nvme_fabric_prop_get_cmd_sync(ctrlr, offset, SPDK_NVMF_PROP_SIZE_8, value); } +int +nvme_fabric_ctrlr_set_reg_4_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + uint32_t value, spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + return nvme_fabric_prop_set_cmd_async(ctrlr, offset, SPDK_NVMF_PROP_SIZE_4, value, + cb_fn, cb_arg); +} + +int +nvme_fabric_ctrlr_set_reg_8_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + uint64_t value, spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + return nvme_fabric_prop_set_cmd_async(ctrlr, offset, SPDK_NVMF_PROP_SIZE_8, value, + cb_fn, cb_arg); +} + +int +nvme_fabric_ctrlr_get_reg_4_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + return nvme_fabric_prop_get_cmd_async(ctrlr, offset, SPDK_NVMF_PROP_SIZE_4, cb_fn, cb_arg); +} + +int +nvme_fabric_ctrlr_get_reg_8_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + spdk_nvme_reg_cb cb_fn, void *cb_arg) +{ + return nvme_fabric_prop_get_cmd_async(ctrlr, offset, SPDK_NVMF_PROP_SIZE_8, cb_fn, cb_arg); +} + static void nvme_fabric_discover_probe(struct spdk_nvmf_discovery_log_page_entry *entry, struct spdk_nvme_probe_ctx *probe_ctx, diff --git a/lib/nvme/nvme_internal.h b/lib/nvme/nvme_internal.h index 792924f27..a2875b690 100644 --- a/lib/nvme/nvme_internal.h +++ b/lib/nvme/nvme_internal.h @@ -1158,8 +1158,16 @@ int nvme_ns_cmd_zone_appendv_with_md(struct spdk_nvme_ns *ns, struct spdk_nvme_q int nvme_fabric_ctrlr_set_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t value); int nvme_fabric_ctrlr_set_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t value); int nvme_fabric_ctrlr_get_reg_4(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint32_t *value); -int nvme_fabric_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx, bool direct_connect); int nvme_fabric_ctrlr_get_reg_8(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, uint64_t *value); +int nvme_fabric_ctrlr_set_reg_4_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + uint32_t value, spdk_nvme_reg_cb cb_fn, void *cb_arg); +int nvme_fabric_ctrlr_set_reg_8_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + uint64_t value, spdk_nvme_reg_cb cb_fn, void *cb_arg); +int nvme_fabric_ctrlr_get_reg_4_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + spdk_nvme_reg_cb cb_fn, void *cb_arg); +int nvme_fabric_ctrlr_get_reg_8_async(struct spdk_nvme_ctrlr *ctrlr, uint32_t offset, + spdk_nvme_reg_cb cb_fn, void *cb_arg); +int nvme_fabric_ctrlr_scan(struct spdk_nvme_probe_ctx *probe_ctx, bool direct_connect); int nvme_fabric_ctrlr_discover(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_probe_ctx *probe_ctx); int nvme_fabric_qpair_connect(struct spdk_nvme_qpair *qpair, uint32_t num_entries);