summaryrefslogtreecommitdiff
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-05 16:43:07 +0900
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:14 -0500
commit55dba3120fbcbea6800f9a18503d25f73212a347 (patch)
tree1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/libata-core.c
parentceb0c642624f634c5b4f46b0e22df19be87a2e53 (diff)
downloadkernel-common-55dba3120fbcbea6800f9a18503d25f73212a347.tar.gz
kernel-common-55dba3120fbcbea6800f9a18503d25f73212a347.tar.bz2
kernel-common-55dba3120fbcbea6800f9a18503d25f73212a347.zip
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.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2c9745a74d50..39cedd949ed4 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;
}