Commit 730750fa authored by Ben Walker's avatar Ben Walker
Browse files

nvmf/rdma: Add utility for detecting transfer direction



This can probably be moved to the generic nvmf code
in the future, since nothing about it is RDMA specific.

Change-Id: I99103e174d99a619d36e519820a8a8a9b56473ac
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/374538


Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent ea957ff3
Loading
Loading
Loading
Loading
+57 −29
Original line number Diff line number Diff line
@@ -751,28 +751,23 @@ spdk_nvmf_rdma_mem_notify(void *cb_ctx, struct spdk_mem_map *map,
	return 0;
}

static spdk_nvmf_request_prep_type
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
{
	struct spdk_nvme_cmd			*cmd;
	struct spdk_nvme_cpl			*rsp;
	struct spdk_nvmf_rdma_request		*rdma_req;
	struct spdk_nvme_sgl_descriptor		*sgl;
	struct spdk_nvmf_rdma_transport		*rtransport;
	struct spdk_nvmf_rdma_device		*device;
typedef enum spdk_nvme_data_transfer spdk_nvme_data_transfer_t;

	cmd = &req->cmd->nvme_cmd;
	rsp = &req->rsp->nvme_cpl;
	rdma_req = SPDK_CONTAINEROF(req, struct spdk_nvmf_rdma_request, req);

	req->length = 0;
	req->data = NULL;
static spdk_nvme_data_transfer_t
spdk_nvmf_rdma_request_get_xfer(struct spdk_nvmf_rdma_request *rdma_req)
{
	enum spdk_nvme_data_transfer xfer;
	struct spdk_nvme_cmd *cmd = &rdma_req->req.cmd->nvme_cmd;
	struct spdk_nvme_sgl_descriptor *sgl = &cmd->dptr.sgl1;

	/* Figure out data transfer direction */
	if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
		req->xfer = spdk_nvme_opc_get_data_transfer(req->cmd->nvmf_cmd.fctype);
		xfer = spdk_nvme_opc_get_data_transfer(rdma_req->req.cmd->nvmf_cmd.fctype);
	} else {
		req->xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);
		if ((req->qpair->type == QPAIR_TYPE_AQ) &&
		xfer = spdk_nvme_opc_get_data_transfer(cmd->opc);

		/* Some admin commands are special cases */
		if ((rdma_req->req.qpair->qid == 0) &&
		    ((cmd->opc == SPDK_NVME_OPC_GET_FEATURES) ||
		     (cmd->opc == SPDK_NVME_OPC_SET_FEATURES))) {
			switch (cmd->cdw10 & 0xff) {
@@ -781,12 +776,55 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
			case SPDK_NVME_FEAT_HOST_IDENTIFIER:
				break;
			default:
				req->xfer = SPDK_NVME_DATA_NONE;
				xfer = SPDK_NVME_DATA_NONE;
			}
		}
	}

	if (xfer == SPDK_NVME_DATA_NONE) {
		return xfer;
	}

	/* Even for commands that may transfer data, they could have specified 0 length.
	 * We want those to show up with xfer SPDK_NVME_DATA_NONE.
	 */
	switch (sgl->generic.type) {
	case SPDK_NVME_SGL_TYPE_DATA_BLOCK:
	case SPDK_NVME_SGL_TYPE_BIT_BUCKET:
	case SPDK_NVME_SGL_TYPE_SEGMENT:
	case SPDK_NVME_SGL_TYPE_LAST_SEGMENT:
		if (sgl->unkeyed.length == 0) {
			xfer = SPDK_NVME_DATA_NONE;
		}
		break;
	case SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK:
		if (sgl->keyed.length == 0) {
			xfer = SPDK_NVME_DATA_NONE;
		}
		break;
	}

	return xfer;
}

static spdk_nvmf_request_prep_type
spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
{
	struct spdk_nvme_cmd			*cmd;
	struct spdk_nvme_cpl			*rsp;
	struct spdk_nvmf_rdma_request		*rdma_req;
	struct spdk_nvme_sgl_descriptor		*sgl;
	struct spdk_nvmf_rdma_transport		*rtransport;
	struct spdk_nvmf_rdma_device		*device;

	cmd = &req->cmd->nvme_cmd;
	rsp = &req->rsp->nvme_cpl;
	rdma_req = SPDK_CONTAINEROF(req, struct spdk_nvmf_rdma_request, req);

	req->length = 0;
	req->data = NULL;

	req->xfer = spdk_nvmf_rdma_request_get_xfer(rdma_req);
	if (req->xfer == SPDK_NVME_DATA_NONE) {
		return SPDK_NVMF_REQUEST_PREP_READY;
	}
@@ -805,11 +843,6 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
			return SPDK_NVMF_REQUEST_PREP_ERROR;
		}

		if (sgl->keyed.length == 0) {
			req->xfer = SPDK_NVME_DATA_NONE;
			return SPDK_NVMF_REQUEST_PREP_READY;
		}

		req->length = sgl->keyed.length;
		req->data = spdk_mempool_get(rtransport->data_buf_pool);
		if (!req->data) {
@@ -856,11 +889,6 @@ spdk_nvmf_request_prep_data(struct spdk_nvmf_request *req)
			return SPDK_NVMF_REQUEST_PREP_ERROR;
		}

		if (sgl->unkeyed.length == 0) {
			req->xfer = SPDK_NVME_DATA_NONE;
			return SPDK_NVMF_REQUEST_PREP_READY;
		}

		req->data = rdma_req->recv->buf + offset;
		rdma_req->data_from_pool = false;
		req->length = sgl->unkeyed.length;