Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3459

kernel-2.6.18-194.11.1.el5.src.rpm

From: Rob Evers <revers@redhat.com>
Date: Mon, 4 Jan 2010 22:52:59 -0500
Subject: [scsi] lpfc: Fix single SCSI buffer not handled on SLI4
Message-id: <20100104225306.24386.72847.sendpatchset@localhost.localdomain>
Patchwork-id: 22309
O-Subject: [RHEL5.5 PATCH 17/18] Fix single SCSI buffer is not handled for SLI4
	adapters
Bugzilla: 549763
RH-Acked-by: Tomas Henzl <thenzl@redhat.com>
RH-Acked-by: Mike Christie <mchristi@redhat.com>

https://bugzilla.redhat.com/show_bug.cgi?id=549763

Fix single SCSI buffer is not handled for SLI4 adapters

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 1bfafe8..8340b7a 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1049,11 +1049,14 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 	struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
 	struct sli4_sge *sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
 	IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
+	uint32_t vpi = (lpfc_cmd->cur_iocbq.vport
+			? lpfc_cmd->cur_iocbq.vport->vpi
+			: 0);
 	dma_addr_t physaddr;
 	uint32_t num_bde = 0;
 	uint32_t dma_len;
 	uint32_t dma_offset = 0;
-	int nseg, datadir = scsi_cmnd->sc_data_direction;
+	int dma_error, nseg, datadir = scsi_cmnd->sc_data_direction;
 
 	/*
 	 * There are three possibilities here - use scatter-gather segment, use
@@ -1120,6 +1123,35 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 			sgel++;
 			num_bde++;
 		}
+	} else if (scsi_cmnd->request_buffer && scsi_cmnd->request_bufflen) {
+		physaddr = dma_map_single(&phba->pcidev->dev,
+					  scsi_cmnd->request_buffer,
+					  scsi_cmnd->request_bufflen,
+					  datadir);
+		dma_error = dma_mapping_error(physaddr);
+		if (dma_error) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+					"(%d):2729 Unable to dma_map_single "
+					"request_buffer: x%x\n",
+					vpi, dma_error);
+			return 1;
+		}
+		sgl += 1;
+		/* clear the last flag in the fcp_rsp map entry */
+		sgl->word2 = le32_to_cpu(sgl->word2);
+		bf_set(lpfc_sli4_sge_last, sgl, 0);
+		sgl->word2 = cpu_to_le32(sgl->word2);
+		sgl += 1;
+
+		bf_set(lpfc_sli4_sge_len, sgl, scsi_cmnd->request_bufflen);
+		sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
+		sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
+		bf_set(lpfc_sli4_sge_last, sgl, 1);
+		bf_set(lpfc_sli4_sge_offset, sgl, dma_offset);
+		sgl->word2 = cpu_to_le32(sgl->word2);
+		sgl->word3 = cpu_to_le32(sgl->word3);
+
+		lpfc_cmd->nonsg_phys = physaddr;
 	} else {
 		sgl += 1;
 		/* clear the last flag in the fcp_rsp map entry */