aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_ixp4xx_cf.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-05 02:43:07 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:14 -0500
commit55dba3120fbcbea6800f9a18503d25f73212a347 (patch)
tree1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/pata_ixp4xx_cf.c
parentceb0c642624f634c5b4f46b0e22df19be87a2e53 (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/pata_ixp4xx_cf.c')
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 120b5bfa7ce6..030878fedeb5 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -42,13 +42,13 @@ static int ixp4xx_set_mode(struct ata_link *link, struct ata_device **error)
42 return 0; 42 return 0;
43} 43}
44 44
45static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, 45static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
46 unsigned int buflen, int write_data) 46 unsigned char *buf, unsigned int buflen, int rw)
47{ 47{
48 unsigned int i; 48 unsigned int i;
49 unsigned int words = buflen >> 1; 49 unsigned int words = buflen >> 1;
50 u16 *buf16 = (u16 *) buf; 50 u16 *buf16 = (u16 *) buf;
51 struct ata_port *ap = adev->link->ap; 51 struct ata_port *ap = dev->link->ap;
52 void __iomem *mmio = ap->ioaddr.data_addr; 52 void __iomem *mmio = ap->ioaddr.data_addr;
53 struct ixp4xx_pata_data *data = ap->host->dev->platform_data; 53 struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
54 54
@@ -59,30 +59,32 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
59 udelay(100); 59 udelay(100);
60 60
61 /* Transfer multiple of 2 bytes */ 61 /* Transfer multiple of 2 bytes */
62 if (write_data) { 62 if (rw == READ)
63 for (i = 0; i < words; i++)
64 writew(buf16[i], mmio);
65 } else {
66 for (i = 0; i < words; i++) 63 for (i = 0; i < words; i++)
67 buf16[i] = readw(mmio); 64 buf16[i] = readw(mmio);
68 } 65 else
66 for (i = 0; i < words; i++)
67 writew(buf16[i], mmio);
69 68
70 /* Transfer trailing 1 byte, if any. */ 69 /* Transfer trailing 1 byte, if any. */
71 if (unlikely(buflen & 0x01)) { 70 if (unlikely(buflen & 0x01)) {
72 u16 align_buf[1] = { 0 }; 71 u16 align_buf[1] = { 0 };
73 unsigned char *trailing_buf = buf + buflen - 1; 72 unsigned char *trailing_buf = buf + buflen - 1;
74 73
75 if (write_data) { 74 if (rw == READ) {
76 memcpy(align_buf, trailing_buf, 1);
77 writew(align_buf[0], mmio);
78 } else {
79 align_buf[0] = readw(mmio); 75 align_buf[0] = readw(mmio);
80 memcpy(trailing_buf, align_buf, 1); 76 memcpy(trailing_buf, align_buf, 1);
77 } else {
78 memcpy(align_buf, trailing_buf, 1);
79 writew(align_buf[0], mmio);
81 } 80 }
81 words++;
82 } 82 }
83 83
84 udelay(100); 84 udelay(100);
85 *data->cs0_cfg |= 0x01; 85 *data->cs0_cfg |= 0x01;
86
87 return words << 1;
86} 88}
87 89
88static struct scsi_host_template ixp4xx_sht = { 90static struct scsi_host_template ixp4xx_sht = {