Blob Blame History Raw
From: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
Date: Sat, 3 Aug 2019 09:59:52 -0400
Subject: [PATCH] scsi: mpt3sas: Support MEMORY MOVE Tool box command
References: bsc#1156632,jsc#SLE-10717
Git-commit: ba630ea068d7cb593ae3bb7085846c5a137d10a6
Patch-mainline: v5.4-rc1

Host uses the Memory Move Tool to copy data from any source/destination
combination of system memory and IOC memory.

Memory Move Tool box request contains two SGE fields, First SGE field must
contains the source buffer details described by an MPI Simple SGE.  The
second SGE field must contains the destination buffer details described by
an MPI Simple SGE.

 Source   ->   Destination

1. IOC    ->   IOC    (Both the SGE's will be filled by application)

2. HOST   ->   HOST   (Both the SGE's will be filled by the host,
               application should give sgl_offset to first SGE offset)

3. IOC    ->   HOST   (Application will fill the first SGE and set the
               sgl_offset to second SGE and hence driver fills
               the second SGE)
4. HOST   ->   IOC    (Application will fill IOC buffer information in the
               first SGE and set the sgl_offset to second SGE.
               Then driver will fill the second SGE with Host buffer
               information and just before posting the command to the
               firmware, driver will swap these two SGEs so that first
               SGE contains the HOST buffer information and second SGE
               contains the IOC information.

Driver has to take care only of the 4th case, other three cases are by
default supported by the current driver design.

Signed-off-by: Suganath Prabu <suganath-prabu.subramani@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index e7c0a301a765..72718bb1ce73 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -926,9 +926,32 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
 		    MPI26_TOOLBOX_BACKEND_PCIE_LANE_MARGIN))
 			ioc->build_sg(ioc, psge, data_out_dma, data_out_sz,
 				data_in_dma, data_in_sz);
-		else
+		else if (toolbox_request->Tool ==
+				MPI2_TOOLBOX_MEMORY_MOVE_TOOL) {
+			Mpi2ToolboxMemMoveRequest_t *mem_move_request =
+					(Mpi2ToolboxMemMoveRequest_t *)request;
+			Mpi2SGESimple64_t tmp, *src = NULL, *dst = NULL;
+
+			ioc->build_sg_mpi(ioc, psge, data_out_dma,
+					data_out_sz, data_in_dma, data_in_sz);
+			if (data_out_sz && !data_in_sz) {
+				dst =
+				    (Mpi2SGESimple64_t *)&mem_move_request->SGL;
+				src = (void *)dst + ioc->sge_size;
+
+				memcpy(&tmp, src, ioc->sge_size);
+				memcpy(src, dst, ioc->sge_size);
+				memcpy(dst, &tmp, ioc->sge_size);
+			}
+			if (ioc->logging_level & MPT_DEBUG_TM) {
+				ioc_info(ioc,
+				  "Mpi2ToolboxMemMoveRequest_t request msg\n");
+				_debug_dump_mf(mem_move_request,
+							ioc->request_sz/4);
+			}
+		} else
 			ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz,
-				data_in_dma, data_in_sz);
+			    data_in_dma, data_in_sz);
 		ioc->put_smid_default(ioc, smid);
 		break;
 	}
-- 
2.16.4