diff options
author | FUJITA Tomonori <tomof@acm.org> | 2007-07-04 09:03:11 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-07-14 18:13:02 -0400 |
commit | c59fd9ebc46da8d48b76955d4d48e3597f8c8726 (patch) | |
tree | 17310b76cc57476b10b735603d3acc5b824ddecb /drivers/scsi | |
parent | d4bd4cd0630060a64681590b9405b87e43c11f14 (diff) |
[SCSI] lpfc: fix NPIV mapping problems
This patch uses dma_map_sg with phba->pcidev->dev instead of
scsi_dma_map.
scsi_dma_map doesn't work for NPIV since fc_vport->dev isn't fully
initialized. check_addr() in arch/x86_64/kernel/pci-nommu.c leads to
the crash since dev->dma_mask is NULL.
For more details:
http://marc.info/?l=linux-scsi&m=118312448030633&w=2
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Acked-by: James Smart <James.Smart@Emulex.Com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 3d35eae01475..8f45bbc42126 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -332,8 +332,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
332 | * data bde entry. | 332 | * data bde entry. |
333 | */ | 333 | */ |
334 | bpl += 2; | 334 | bpl += 2; |
335 | nseg = scsi_dma_map(scsi_cmnd); | 335 | if (scsi_sg_count(scsi_cmnd)) { |
336 | if (nseg > 0) { | ||
337 | /* | 336 | /* |
338 | * The driver stores the segment count returned from pci_map_sg | 337 | * The driver stores the segment count returned from pci_map_sg |
339 | * because this a count of dma-mappings used to map the use_sg | 338 | * because this a count of dma-mappings used to map the use_sg |
@@ -341,6 +340,11 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
341 | * architectures that implement an IOMMU. | 340 | * architectures that implement an IOMMU. |
342 | */ | 341 | */ |
343 | 342 | ||
343 | nseg = dma_map_sg(&phba->pcidev->dev, scsi_sglist(scsi_cmnd), | ||
344 | scsi_sg_count(scsi_cmnd), datadir); | ||
345 | if (unlikely(!nseg)) | ||
346 | return 1; | ||
347 | |||
344 | lpfc_cmd->seg_cnt = nseg; | 348 | lpfc_cmd->seg_cnt = nseg; |
345 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { | 349 | if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { |
346 | printk(KERN_ERR "%s: Too many sg segments from " | 350 | printk(KERN_ERR "%s: Too many sg segments from " |
@@ -370,8 +374,7 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
370 | bpl++; | 374 | bpl++; |
371 | num_bde++; | 375 | num_bde++; |
372 | } | 376 | } |
373 | } else if (nseg < 0) | 377 | } |
374 | return 1; | ||
375 | 378 | ||
376 | /* | 379 | /* |
377 | * Finish initializing those IOCB fields that are dependent on the | 380 | * Finish initializing those IOCB fields that are dependent on the |