scsi: mpt3sas: Support MEMORY MOVE Tool box command

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>
This commit is contained in:
Suganath Prabu 2019-08-03 09:59:52 -04:00 committed by Martin K. Petersen
parent 3c090ce3f0
commit ba630ea068
1 changed files with 25 additions and 2 deletions

View File

@ -934,9 +934,32 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
MPI26_TOOLBOX_BACKEND_PCIE_LANE_MARGIN)) MPI26_TOOLBOX_BACKEND_PCIE_LANE_MARGIN))
ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, ioc->build_sg(ioc, psge, data_out_dma, data_out_sz,
data_in_dma, data_in_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, 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); ioc->put_smid_default(ioc, smid);
break; break;
} }