aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2008-02-22 09:11:04 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-22 18:20:59 -0500
commitc9872fe1add5709fffd42249e6ca1080999aa06a (patch)
tree8ee1278a998220785a3eaf1ae7c3fd4ba54ced22
parent26106e3ca379e30790c41d8835e79395437152ec (diff)
[SCSI] stex: stex_internal_copy should be called with sg_count in struct st_ccb
stex_internal_copy copies an in-kernel buffer to a sg list by using scsi_kmap_atomic_sg. Some functions calls stex_internal_copy with sg_count in struct st_ccb, which is the value that dma_map_sg returned. However it might be shorter than the actual number of sg entries (if the IOMMU merged the sg entries). scsi_kmap_atomic_sg doesn't see sg->dma_length so stex_internal_copy should be called with the actual number of sg entries (i.e. scsi_sg_count), because if the sg entries were merged, stex_direct_copy wrongly think that the data length in the sg list is shorter than the actual length. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Acked-by: Ed Lin <ed.lin@promise.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/stex.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 4b6861cf0417..654430edf74d 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -467,7 +467,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
467 size_t count = sizeof(struct st_frame); 467 size_t count = sizeof(struct st_frame);
468 468
469 p = hba->copy_buffer; 469 p = hba->copy_buffer;
470 stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); 470 stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
471 ST_FROM_CMD);
471 memset(p->base, 0, sizeof(u32)*6); 472 memset(p->base, 0, sizeof(u32)*6);
472 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); 473 *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
473 p->rom_addr = 0; 474 p->rom_addr = 0;
@@ -485,7 +486,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
485 p->subid = 486 p->subid =
486 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; 487 hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
487 488
488 stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD); 489 stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
490 ST_TO_CMD);
489} 491}
490 492
491static void 493static void
@@ -699,7 +701,7 @@ static void stex_copy_data(struct st_ccb *ccb,
699 if (ccb->cmd == NULL) 701 if (ccb->cmd == NULL)
700 return; 702 return;
701 stex_internal_copy(ccb->cmd, 703 stex_internal_copy(ccb->cmd,
702 resp->variable, &count, ccb->sg_count, ST_TO_CMD); 704 resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD);
703} 705}
704 706
705static void stex_ys_commands(struct st_hba *hba, 707static void stex_ys_commands(struct st_hba *hba,
@@ -724,7 +726,7 @@ static void stex_ys_commands(struct st_hba *hba,
724 726
725 count = STEX_EXTRA_SIZE; 727 count = STEX_EXTRA_SIZE;
726 stex_internal_copy(ccb->cmd, hba->copy_buffer, 728 stex_internal_copy(ccb->cmd, hba->copy_buffer,
727 &count, ccb->sg_count, ST_FROM_CMD); 729 &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD);
728 inq_data = (ST_INQ *)hba->copy_buffer; 730 inq_data = (ST_INQ *)hba->copy_buffer;
729 if (inq_data->DeviceTypeQualifier != 0) 731 if (inq_data->DeviceTypeQualifier != 0)
730 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; 732 ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;