Commit 2d4f7e20 authored by James Bergsten's avatar James Bergsten Committed by Jim Harris
Browse files

nvme: add spdk_nvme_ctrlr_cmd_io_raw_no_payload_build



Send the given NVM I/O command, I/O buffers, lists and all to
the NVMe controller.

This is a low level interface for submitting I/O commands directly.

This can only be used on PCIe controllers and qpairs.

This function allows a caller to submit an I/O request that is
COMPLETELY pre-defined, right down to the "physical" memory buffers.
It is intended for testing hardware, specifying exact buffer location,
alignment, and offset.  It also allows for specific choice of PRP
and SGLs.

The driver sets the CID.  EVERYTHING else is assumed set by the caller.
Needless to say, this is potentially extremely dangerous for both the host
(accidental/malicionus storage usage/corruption), and the device.
Thus its intent is for very specific hardware testing and environment
reproduction.

Signed-off-by: default avatarJames Bergsten <jamesx.bergsten@intel.com>
Change-Id: I595fe02fe0dfa9c3ceba1ac116b6900357b02d2c
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/451994


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent 5f1e4681
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -987,6 +987,43 @@ struct spdk_nvme_qpair *spdk_nvme_ctrlr_alloc_io_qpair(struct spdk_nvme_ctrlr *c
 */
int spdk_nvme_ctrlr_free_io_qpair(struct spdk_nvme_qpair *qpair);

/**
 * Send the given NVM I/O command, I/O buffers, lists and all to the NVMe controller.
 *
 * This is a low level interface for submitting I/O commands directly.
 *
 * This function allows a caller to submit an I/O request that is
 * COMPLETELY pre-defined, right down to the "physical" memory buffers.
 * It is intended for testing hardware, specifying exact buffer location,
 * alignment, and offset.  It also allows for specific choice of PRP
 * and SGLs.
 *
 * The driver sets the CID.  EVERYTHING else is assumed set by the caller.
 * Needless to say, this is potentially extremely dangerous for both the host
 * (accidental/malicionus storage usage/corruption), and the device.
 * Thus its intent is for very specific hardware testing and environment
 * reproduction.
 *
 * The command is submitted to a qpair allocated by spdk_nvme_ctrlr_alloc_io_qpair().
 * The user must ensure that only one thread submits I/O on a given qpair at any
 * given time.
 *
 * This function can only be used on PCIe controllers and qpairs.
 *
 * \param ctrlr Opaque handle to NVMe controller.
 * \param qpair I/O qpair to submit command.
 * \param cmd NVM I/O command to submit.
 * \param cb_fn Callback function invoked when the I/O command completes.
 * \param cb_arg Argument passed to callback function.
 *
 * \return 0 on success, negated errno on failure.
 */

int spdk_nvme_ctrlr_io_cmd_raw_no_payload_build(struct spdk_nvme_ctrlr *ctrlr,
		struct spdk_nvme_qpair *qpair,
		struct spdk_nvme_cmd *cmd,
		spdk_nvme_cmd_cb cb_fn, void *cb_arg);

/**
 * Send the given NVM I/O command to the NVMe controller.
 *
+25 −0
Original line number Diff line number Diff line
@@ -33,6 +33,31 @@

#include "nvme_internal.h"

int
spdk_nvme_ctrlr_io_cmd_raw_no_payload_build(struct spdk_nvme_ctrlr *ctrlr,
		struct spdk_nvme_qpair *qpair,
		struct spdk_nvme_cmd *cmd,
		spdk_nvme_cmd_cb cb_fn, void *cb_arg)
{
	struct nvme_request *req;
	struct nvme_payload payload;

	if (ctrlr->trid.trtype != SPDK_NVME_TRANSPORT_PCIE) {
		return -EINVAL;
	}

	memset(&payload, 0, sizeof(payload));
	req = nvme_allocate_request(qpair, &payload, 0, cb_fn, cb_arg);

	if (req == NULL) {
		return -ENOMEM;
	}

	memcpy(&req->cmd, cmd, sizeof(req->cmd));

	return nvme_qpair_submit_request(qpair, req);
}

int
spdk_nvme_ctrlr_cmd_io_raw(struct spdk_nvme_ctrlr *ctrlr,
			   struct spdk_nvme_qpair *qpair,
+1 −1
Original line number Diff line number Diff line
@@ -2032,7 +2032,7 @@ nvme_pcie_qpair_submit_request(struct spdk_nvme_qpair *qpair, struct nvme_reques
	}

	if (req->payload_size == 0) {
		/* Null payload - leave PRP fields zeroed */
		/* Null payload - leave PRP fields untouched */
		rc = 0;
	} else if (nvme_payload_type(&req->payload) == NVME_PAYLOAD_TYPE_CONTIG) {
		rc = nvme_pcie_qpair_build_contig_request(qpair, req, tr);