diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-05 07:13:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-05 07:13:30 -0400 |
commit | cedc9a478d8c6265879dc3839ef3d4849a709184 (patch) | |
tree | 0c8e0fbffdb6081381c01b8cfd93c95b168acb44 /drivers/scsi/sata_sx4.c | |
parent | ed39f731ab2e77e58122232f6e27333331d7793d (diff) |
libata: fix ATAPI DMA alignment issues
ATAPI needs to be padded to next 4 byte boundary, if misaligned.
Original work by me, many fixes from Tejun Heo.
Diffstat (limited to 'drivers/scsi/sata_sx4.c')
-rw-r--r-- | drivers/scsi/sata_sx4.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 540a85191172..79fdbbab513e 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -449,14 +449,14 @@ static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf, | |||
449 | 449 | ||
450 | static void pdc20621_dma_prep(struct ata_queued_cmd *qc) | 450 | static void pdc20621_dma_prep(struct ata_queued_cmd *qc) |
451 | { | 451 | { |
452 | struct scatterlist *sg = qc->sg; | 452 | struct scatterlist *sg; |
453 | struct ata_port *ap = qc->ap; | 453 | struct ata_port *ap = qc->ap; |
454 | struct pdc_port_priv *pp = ap->private_data; | 454 | struct pdc_port_priv *pp = ap->private_data; |
455 | void __iomem *mmio = ap->host_set->mmio_base; | 455 | void __iomem *mmio = ap->host_set->mmio_base; |
456 | struct pdc_host_priv *hpriv = ap->host_set->private_data; | 456 | struct pdc_host_priv *hpriv = ap->host_set->private_data; |
457 | void __iomem *dimm_mmio = hpriv->dimm_mmio; | 457 | void __iomem *dimm_mmio = hpriv->dimm_mmio; |
458 | unsigned int portno = ap->port_no; | 458 | unsigned int portno = ap->port_no; |
459 | unsigned int i, last, idx, total_len = 0, sgt_len; | 459 | unsigned int i, idx, total_len = 0, sgt_len; |
460 | u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; | 460 | u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ]; |
461 | 461 | ||
462 | assert(qc->flags & ATA_QCFLAG_DMAMAP); | 462 | assert(qc->flags & ATA_QCFLAG_DMAMAP); |
@@ -469,12 +469,11 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc) | |||
469 | /* | 469 | /* |
470 | * Build S/G table | 470 | * Build S/G table |
471 | */ | 471 | */ |
472 | last = qc->n_elem; | ||
473 | idx = 0; | 472 | idx = 0; |
474 | for (i = 0; i < last; i++) { | 473 | ata_for_each_sg(sg, qc) { |
475 | buf[idx++] = cpu_to_le32(sg_dma_address(&sg[i])); | 474 | buf[idx++] = cpu_to_le32(sg_dma_address(sg)); |
476 | buf[idx++] = cpu_to_le32(sg_dma_len(&sg[i])); | 475 | buf[idx++] = cpu_to_le32(sg_dma_len(sg)); |
477 | total_len += sg_dma_len(&sg[i]); | 476 | total_len += sg_dma_len(sg); |
478 | } | 477 | } |
479 | buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT); | 478 | buf[idx - 1] |= cpu_to_le32(ATA_PRD_EOT); |
480 | sgt_len = idx * 4; | 479 | sgt_len = idx * 4; |