From 50ba0232fd5312410f1b65247e774244f89a628e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 20:50:36 +0200 Subject: Merging upstream version 6.8.9. Signed-off-by: Daniel Baumann --- drivers/scsi/mpi3mr/mpi3mr_fw.c | 117 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/mpi3mr/mpi3mr_fw.c') diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 0d148c39eb..528f19f782 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -475,7 +475,7 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc) * @op_reply_q: op_reply_qinfo object * @reply_ci: operational reply descriptor's queue consumer index * - * Returns reply descriptor frame address + * Returns: reply descriptor frame address */ static inline struct mpi3_default_reply_descriptor * mpi3mr_get_reply_desc(struct op_reply_qinfo *op_reply_q, u32 reply_ci) @@ -1058,6 +1058,112 @@ enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_ioc *mrioc) return MRIOC_STATE_RESET_REQUESTED; } +/** + * mpi3mr_free_ioctl_dma_memory - free memory for ioctl dma + * @mrioc: Adapter instance reference + * + * Free the DMA memory allocated for IOCTL handling purpose. + * + * Return: None + */ +static void mpi3mr_free_ioctl_dma_memory(struct mpi3mr_ioc *mrioc) +{ + struct dma_memory_desc *mem_desc; + u16 i; + + if (!mrioc->ioctl_dma_pool) + return; + + for (i = 0; i < MPI3MR_NUM_IOCTL_SGE; i++) { + mem_desc = &mrioc->ioctl_sge[i]; + if (mem_desc->addr) { + dma_pool_free(mrioc->ioctl_dma_pool, + mem_desc->addr, + mem_desc->dma_addr); + mem_desc->addr = NULL; + } + } + dma_pool_destroy(mrioc->ioctl_dma_pool); + mrioc->ioctl_dma_pool = NULL; + mem_desc = &mrioc->ioctl_chain_sge; + + if (mem_desc->addr) { + dma_free_coherent(&mrioc->pdev->dev, mem_desc->size, + mem_desc->addr, mem_desc->dma_addr); + mem_desc->addr = NULL; + } + mem_desc = &mrioc->ioctl_resp_sge; + if (mem_desc->addr) { + dma_free_coherent(&mrioc->pdev->dev, mem_desc->size, + mem_desc->addr, mem_desc->dma_addr); + mem_desc->addr = NULL; + } + + mrioc->ioctl_sges_allocated = false; +} + +/** + * mpi3mr_alloc_ioctl_dma_memory - Alloc memory for ioctl dma + * @mrioc: Adapter instance reference + * + * This function allocates dmaable memory required to handle the + * application issued MPI3 IOCTL requests. + * + * Return: None + */ +static void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_ioc *mrioc) + +{ + struct dma_memory_desc *mem_desc; + u16 i; + + mrioc->ioctl_dma_pool = dma_pool_create("ioctl dma pool", + &mrioc->pdev->dev, + MPI3MR_IOCTL_SGE_SIZE, + MPI3MR_PAGE_SIZE_4K, 0); + + if (!mrioc->ioctl_dma_pool) { + ioc_err(mrioc, "ioctl_dma_pool: dma_pool_create failed\n"); + goto out_failed; + } + + for (i = 0; i < MPI3MR_NUM_IOCTL_SGE; i++) { + mem_desc = &mrioc->ioctl_sge[i]; + mem_desc->size = MPI3MR_IOCTL_SGE_SIZE; + mem_desc->addr = dma_pool_zalloc(mrioc->ioctl_dma_pool, + GFP_KERNEL, + &mem_desc->dma_addr); + if (!mem_desc->addr) + goto out_failed; + } + + mem_desc = &mrioc->ioctl_chain_sge; + mem_desc->size = MPI3MR_PAGE_SIZE_4K; + mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev, + mem_desc->size, + &mem_desc->dma_addr, + GFP_KERNEL); + if (!mem_desc->addr) + goto out_failed; + + mem_desc = &mrioc->ioctl_resp_sge; + mem_desc->size = MPI3MR_PAGE_SIZE_4K; + mem_desc->addr = dma_alloc_coherent(&mrioc->pdev->dev, + mem_desc->size, + &mem_desc->dma_addr, + GFP_KERNEL); + if (!mem_desc->addr) + goto out_failed; + + mrioc->ioctl_sges_allocated = true; + + return; +out_failed: + ioc_warn(mrioc, "cannot allocate DMA memory for the mpt commands\n" + "from the applications, application interface for MPT command is disabled\n"); + mpi3mr_free_ioctl_dma_memory(mrioc); +} + /** * mpi3mr_clear_reset_history - clear reset history * @mrioc: Adapter instance reference @@ -1133,7 +1239,7 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc, * during reset/resume * @mrioc: Adapter instance reference * - * Return zero if the new IOCFacts parameters value is compatible with + * Return: zero if the new IOCFacts parameters value is compatible with * older values else return -EPERM */ static int @@ -3194,6 +3300,9 @@ static int mpi3mr_issue_iocinit(struct mpi3mr_ioc *mrioc) current_time = ktime_get_real(); iocinit_req.time_stamp = cpu_to_le64(ktime_to_ms(current_time)); + iocinit_req.msg_flags |= + MPI3_IOCINIT_MSGFLAGS_SCSIIOSTATUSREPLY_SUPPORTED; + init_completion(&mrioc->init_cmds.done); retval = mpi3mr_admin_request_post(mrioc, &iocinit_req, sizeof(iocinit_req), 1); @@ -3871,6 +3980,9 @@ retry_init: } } + dprint_init(mrioc, "allocating ioctl dma buffers\n"); + mpi3mr_alloc_ioctl_dma_memory(mrioc); + if (!mrioc->init_cmds.reply) { retval = mpi3mr_alloc_reply_sense_bufs(mrioc); if (retval) { @@ -4290,6 +4402,7 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc) struct mpi3mr_intr_info *intr_info; mpi3mr_free_enclosure_list(mrioc); + mpi3mr_free_ioctl_dma_memory(mrioc); if (mrioc->sense_buf_pool) { if (mrioc->sense_buf) -- cgit v1.2.3