Unverified Commit 798865c6 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files
parents 6a7ec317 e9e579a7
Loading
Loading
Loading
Loading
+21 −17
Original line number Diff line number Diff line
@@ -2431,12 +2431,8 @@ _base_check_pcie_native_sgl(struct MPT3SAS_ADAPTER *ioc,

	/* Get the SG list pointer and info. */
	sges_left = scsi_dma_map(scmd);
	if (sges_left < 0) {
		sdev_printk(KERN_ERR, scmd->device,
			"scsi_dma_map failed: request for %d bytes!\n",
			scsi_bufflen(scmd));
	if (sges_left < 0)
		return 1;
	}

	/* Check if we need to build a native SG list. */
	if (base_is_prp_possible(ioc, pcie_device,
@@ -2496,6 +2492,22 @@ _base_build_zero_len_sge_ieee(struct MPT3SAS_ADAPTER *ioc, void *paddr)
	_base_add_sg_single_ieee(paddr, sgl_flags, 0, 0, -1);
}

static inline int _base_scsi_dma_map(struct scsi_cmnd *cmd)
{
	/*
	 * Some firmware versions byte-swap the REPORT ZONES command reply from
	 * ATA-ZAC devices by directly accessing in the host buffer. This does
	 * not respect the default command DMA direction and causes IOMMU page
	 * faults on some architectures with an IOMMU enforcing write mappings
	 * (e.g. AMD hosts). Avoid such issue by making the report zones buffer
	 * mapping bi-directional.
	 */
	if (cmd->cmnd[0] == ZBC_IN && cmd->cmnd[1] == ZI_REPORT_ZONES)
		cmd->sc_data_direction = DMA_BIDIRECTIONAL;

	return scsi_dma_map(cmd);
}

/**
 * _base_build_sg_scmd - main sg creation routine
 *		pcie_device is unused here!
@@ -2542,13 +2554,9 @@ _base_build_sg_scmd(struct MPT3SAS_ADAPTER *ioc,
	sgl_flags = sgl_flags << MPI2_SGE_FLAGS_SHIFT;

	sg_scmd = scsi_sglist(scmd);
	sges_left = scsi_dma_map(scmd);
	if (sges_left < 0) {
		sdev_printk(KERN_ERR, scmd->device,
		 "scsi_dma_map failed: request for %d bytes!\n",
		 scsi_bufflen(scmd));
	sges_left = _base_scsi_dma_map(scmd);
	if (sges_left < 0)
		return -ENOMEM;
	}

	sg_local = &mpi_request->SGL;
	sges_in_segment = ioc->max_sges_in_main_message;
@@ -2690,13 +2698,9 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc,
	}

	sg_scmd = scsi_sglist(scmd);
	sges_left = scsi_dma_map(scmd);
	if (sges_left < 0) {
		sdev_printk(KERN_ERR, scmd->device,
			"scsi_dma_map failed: request for %d bytes!\n",
			scsi_bufflen(scmd));
	sges_left = _base_scsi_dma_map(scmd);
	if (sges_left < 0)
		return -ENOMEM;
	}

	sg_local = &mpi_request->SGL;
	sges_in_segment = (ioc->request_sz -