Example #1
0
int
spdk_nvmf_request_exec(struct spdk_nvmf_request *req)
{
	struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
	bool done;

	if (cmd->opc == SPDK_NVME_OPC_FABRIC) {
		done = nvmf_process_fabrics_command(req);
	} else if (req->conn->type == CONN_TYPE_AQ) {
		done = nvmf_process_admin_cmd(req);
	} else {
		done = nvmf_process_io_cmd(req);
	}

	if (done) {
		/* Synchronous command - response is already filled out */
		return spdk_nvmf_request_complete(req);
	}

	/*
	 * Asynchronous command.
	 * The completion callback will call spdk_nvmf_request_complete().
	 */
	return 0;
}
Example #2
0
static int
nvmf_process_admin_command(struct spdk_nvmf_conn *conn,
			   struct nvme_qp_tx_desc *tx_desc)
{
	struct nvme_qp_rx_desc *rx_desc = tx_desc->rx_desc;
	struct nvmf_request *req;
	struct spdk_nvme_cmd *cmd;
	struct spdk_nvme_sgl_descriptor *sgl;
	struct spdk_nvmf_keyed_sgl_descriptor *keyed_sgl;
	void *buf = NULL;
	uint32_t len = 0;
	int	ret;

	req = &tx_desc->req_state;
	cmd = &req->cmd->nvme_cmd;
	sgl = (struct spdk_nvme_sgl_descriptor *)&cmd->dptr.sgl1;
	keyed_sgl = (struct spdk_nvmf_keyed_sgl_descriptor *)sgl;

	/*
	  NVMf does not support in-capsule data for admin command or response capsules.
	  If caller indicates SGL for return RDMA data, verify the SGL and prepare
	  data buffer reference and length for the NVMf library.  Only keyed type
	  SGLs are supported for return data
	 */
	if (sgl->type == SPDK_NVME_SGL_TYPE_KEYED_DATA_BLOCK &&
	    (sgl->type_specific == SPDK_NVME_SGL_SUBTYPE_ADDRESS ||
	     sgl->type_specific == SPDK_NVME_SGL_SUBTYPE_INVALIDATE_KEY)) {
		buf = (void *)rx_desc->bb;
		len = rx_desc->bb_sgl.length;
		req->remote_addr = keyed_sgl->address;
		req->rkey = keyed_sgl->key;
		req->length = keyed_sgl->length;
	}

	SPDK_TRACELOG(SPDK_TRACE_DEBUG, "	tx_desc %p: req_state %p, rsp %p, addr %p\n",
		      tx_desc, req, (void *)req->rsp, (void *)tx_desc->send_sgl.addr);

	/* send to NVMf library for backend NVMe processing */
	ret = nvmf_process_admin_cmd(req->session, cmd, buf, len, req);
	if (ret) {
		/* library failed the request and should have
		   Updated the response */
		SPDK_TRACELOG(SPDK_TRACE_NVMF, "send nvme admin cmd capsule sync response\n");
		ret = spdk_nvmf_send_response(conn, req);
		if (ret) {
			SPDK_ERRLOG("Unable to send aq qp tx descriptor\n");
			goto command_fail;
		}
	}

	return 0;

command_fail:
	return -1;
}