[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>
This commit is contained in:
parent
26106e3ca3
commit
c9872fe1ad
|
@ -467,7 +467,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
|
||||||
size_t count = sizeof(struct st_frame);
|
size_t count = sizeof(struct st_frame);
|
||||||
|
|
||||||
p = hba->copy_buffer;
|
p = hba->copy_buffer;
|
||||||
stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD);
|
stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
|
||||||
|
ST_FROM_CMD);
|
||||||
memset(p->base, 0, sizeof(u32)*6);
|
memset(p->base, 0, sizeof(u32)*6);
|
||||||
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
|
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
|
||||||
p->rom_addr = 0;
|
p->rom_addr = 0;
|
||||||
|
@ -485,7 +486,8 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
|
||||||
p->subid =
|
p->subid =
|
||||||
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
|
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
|
||||||
|
|
||||||
stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_TO_CMD);
|
stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd),
|
||||||
|
ST_TO_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -699,7 +701,7 @@ static void stex_copy_data(struct st_ccb *ccb,
|
||||||
if (ccb->cmd == NULL)
|
if (ccb->cmd == NULL)
|
||||||
return;
|
return;
|
||||||
stex_internal_copy(ccb->cmd,
|
stex_internal_copy(ccb->cmd,
|
||||||
resp->variable, &count, ccb->sg_count, ST_TO_CMD);
|
resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stex_ys_commands(struct st_hba *hba,
|
static void stex_ys_commands(struct st_hba *hba,
|
||||||
|
@ -724,7 +726,7 @@ static void stex_ys_commands(struct st_hba *hba,
|
||||||
|
|
||||||
count = STEX_EXTRA_SIZE;
|
count = STEX_EXTRA_SIZE;
|
||||||
stex_internal_copy(ccb->cmd, hba->copy_buffer,
|
stex_internal_copy(ccb->cmd, hba->copy_buffer,
|
||||||
&count, ccb->sg_count, ST_FROM_CMD);
|
&count, scsi_sg_count(ccb->cmd), ST_FROM_CMD);
|
||||||
inq_data = (ST_INQ *)hba->copy_buffer;
|
inq_data = (ST_INQ *)hba->copy_buffer;
|
||||||
if (inq_data->DeviceTypeQualifier != 0)
|
if (inq_data->DeviceTypeQualifier != 0)
|
||||||
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
|
ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT;
|
||||||
|
|
Loading…
Reference in New Issue