diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-19 02:14:54 (GMT) |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-19 02:14:54 (GMT) |
commit | 972c26bdd6b58e7534473c4f7928584578cf43f4 (patch) | |
tree | e32f940cf913ee80ac7ae5e3d92d53f90a6b6552 | |
parent | b194b4250c2b7e9d762823ac6045316fcd4bf4f9 (diff) | |
download | linux-972c26bdd6b58e7534473c4f7928584578cf43f4.tar.xz |
libata: add ata_sg_is_last() helper, use it in several drivers
-rw-r--r-- | drivers/scsi/pdc_adma.c | 8 | ||||
-rw-r--r-- | drivers/scsi/sata_mv.c | 16 | ||||
-rw-r--r-- | drivers/scsi/sata_sil24.c | 15 | ||||
-rw-r--r-- | include/linux/libata.h | 12 |
4 files changed, 35 insertions, 16 deletions
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 53b8db4..c6825da 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -293,14 +293,14 @@ static void adma_eng_timeout(struct ata_port *ap) static int adma_fill_sg(struct ata_queued_cmd *qc) { - struct scatterlist *sg = qc->sg; + struct scatterlist *sg; struct ata_port *ap = qc->ap; struct adma_port_priv *pp = ap->private_data; u8 *buf = pp->pkt; - int nelem, i = (2 + buf[3]) * 8; + int i = (2 + buf[3]) * 8; u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0); - for (nelem = 0; nelem < qc->n_elem; nelem++,sg++) { + ata_for_each_sg(sg, qc) { u32 addr; u32 len; @@ -312,7 +312,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)(buf + i) = cpu_to_le32(len); i += 4; - if ((nelem + 1) == qc->n_elem) + if (ata_sg_is_last(sg, qc)) pFLAGS |= pEND; buf[i++] = pFLAGS; buf[i++] = qc->dev->dma_mode & 0xf; diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index d457f56..be7c378 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -785,22 +785,24 @@ static void mv_port_stop(struct ata_port *ap) static void mv_fill_sg(struct ata_queued_cmd *qc) { struct mv_port_priv *pp = qc->ap->private_data; - unsigned int i; + unsigned int i = 0; + struct scatterlist *sg; - for (i = 0; i < qc->n_elem; i++) { + ata_for_each_sg(sg, qc) { u32 sg_len; dma_addr_t addr; - addr = sg_dma_address(&qc->sg[i]); - sg_len = sg_dma_len(&qc->sg[i]); + addr = sg_dma_address(sg); + sg_len = sg_dma_len(sg); pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); - } - if (0 < qc->n_elem) { - pp->sg_tbl[qc->n_elem - 1].flags_size |= EPRD_FLAG_END_OF_TBL; + if (ata_sg_is_last(sg, qc)) + pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); + + i++; } } diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 1985781..e16d181 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -416,15 +416,20 @@ static void sil24_phy_reset(struct ata_port *ap) static inline void sil24_fill_sg(struct ata_queued_cmd *qc, struct sil24_cmd_block *cb) { - struct scatterlist *sg = qc->sg; struct sil24_sge *sge = cb->sge; - unsigned i; + struct scatterlist *sg; + unsigned int idx = 0; - for (i = 0; i < qc->n_elem; i++, sg++, sge++) { + ata_for_each_sg(sg, qc) { sge->addr = cpu_to_le64(sg_dma_address(sg)); sge->cnt = cpu_to_le32(sg_dma_len(sg)); - sge->flags = 0; - sge->flags = i < qc->n_elem - 1 ? 0 : cpu_to_le32(SGE_TRM); + if (ata_sg_is_last(sg, qc)) + sge->flags = cpu_to_le32(SGE_TRM); + else + sge->flags = 0; + + sge++; + idx++; } } diff --git a/include/linux/libata.h b/include/linux/libata.h index d3f58a7..d3dfefe 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -480,6 +480,18 @@ extern int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits); #endif /* CONFIG_PCI */ +static inline int +ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) +{ + if (sg == &qc->pad_sgent) + return 1; + if (qc->pad_len) + return 0; + if (((sg - qc->__sg) + 1) == qc->n_elem) + return 1; + return 0; +} + static inline struct scatterlist * ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc) { |