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 */