From 3cec6c846b50645e53ceae8532d8504194bc75c6 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Tue, 29 Mar 2016 13:04:53 -0700 Subject: [PATCH] nvme: clarify single SGL descriptor case If only one descriptor is needed, there is a special case in the spec for SGL1 using the Data Block descriptor type. Add a comment to make it clear what is going on. Also tweak the SGL1 setup to copy from the first SGL descriptor list element instead of relying on the last value from the loop above, since that could be easily broken by accident. Change-Id: I49ef97fe5bf18d2bf1d86b4310a7d3abdfd03e57 Signed-off-by: Daniel Verkamp --- lib/nvme/nvme_qpair.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/nvme/nvme_qpair.c b/lib/nvme/nvme_qpair.c index a75ef78ca..7c031a30e 100644 --- a/lib/nvme/nvme_qpair.c +++ b/lib/nvme/nvme_qpair.c @@ -702,9 +702,15 @@ _nvme_qpair_build_hw_sgl_request(struct spdk_nvme_qpair *qpair, struct nvme_requ } if (nseg == 1) { + /* + * The whole transfer can be described by a single SGL descriptor. + * Use the special case described by the spec where SGL1's type is Data Block. + * This means the SGL in the tracker is not used at all, so copy the first (and only) + * SGL element into SGL1. + */ req->cmd.dptr.sgl1.type = SPDK_NVME_SGL_TYPE_DATA_BLOCK; - req->cmd.dptr.sgl1.address = phys_addr; - req->cmd.dptr.sgl1.length = data_transfered; + req->cmd.dptr.sgl1.address = tr->u.sgl[0].address; + req->cmd.dptr.sgl1.length = tr->u.sgl[0].length; } else { /* For now we can only support 1 SGL segment in NVMe controller */ req->cmd.dptr.sgl1.type = SPDK_NVME_SGL_TYPE_LAST_SEGMENT;