diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-05 16:43:07 +0900 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:14 -0500 |
commit | 55dba3120fbcbea6800f9a18503d25f73212a347 (patch) | |
tree | 1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/libata-core.c | |
parent | ceb0c642624f634c5b4f46b0e22df19be87a2e53 (diff) |
libata: update ->data_xfer hook for ATAPI
Depending on how many bytes are transferred as a unit, PIO data
transfer may consume more bytes than requested. Knowing how much
data is consumed is necessary to determine how much is left for
draining. This patch update ->data_xfer such that it returns the
number of consumed bytes.
While at it, it also makes the following changes.
* s/adev/dev/
* use READ/WRITE constants for rw indication
* misc clean ups
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2c9745a74d5..39cedd949ed 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4994,7 +4994,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) /** * ata_data_xfer - Transfer data by PIO - * @adev: device to target + * @dev: device to target * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -5003,37 +5003,44 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) * * LOCKING: * Inherited from caller. + * + * RETURNS: + * Bytes consumed. */ -void ata_data_xfer(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = dev->link->ap; + void __iomem *data_addr = ap->ioaddr.data_addr; unsigned int words = buflen >> 1; /* Transfer multiple of 2 bytes */ - if (write_data) - iowrite16_rep(ap->ioaddr.data_addr, buf, words); + if (rw == READ) + ioread16_rep(data_addr, buf, words); else - ioread16_rep(ap->ioaddr.data_addr, buf, words); + iowrite16_rep(data_addr, buf, words); /* Transfer trailing 1 byte, if any. */ if (unlikely(buflen & 0x01)) { u16 align_buf[1] = { 0 }; unsigned char *trailing_buf = buf + buflen - 1; - if (write_data) { - memcpy(align_buf, trailing_buf, 1); - iowrite16(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr); - } else { - align_buf[0] = cpu_to_le16(ioread16(ap->ioaddr.data_addr)); + if (rw == READ) { + align_buf[0] = cpu_to_le16(ioread16(data_addr)); memcpy(trailing_buf, align_buf, 1); + } else { + memcpy(align_buf, trailing_buf, 1); + iowrite16(le16_to_cpu(align_buf[0]), data_addr); } + words++; } + + return words << 1; } /** * ata_data_xfer_noirq - Transfer data by PIO - * @adev: device to target + * @dev: device to target * @buf: data buffer * @buflen: buffer length * @write_data: read/write @@ -5043,14 +5050,21 @@ void ata_data_xfer(struct ata_device *adev, unsigned char *buf, * * LOCKING: * Inherited from caller. + * + * RETURNS: + * Bytes consumed. */ -void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, - unsigned int buflen, int write_data) +unsigned int ata_data_xfer_noirq(struct ata_device *dev, unsigned char *buf, + unsigned int buflen, int rw) { unsigned long flags; + unsigned int consumed; + local_irq_save(flags); - ata_data_xfer(adev, buf, buflen, write_data); + consumed = ata_data_xfer(dev, buf, buflen, rw); local_irq_restore(flags); + + return consumed; } |