diff options
author | Tejun Heo <htejun@gmail.com> | 2007-12-05 02:43:07 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-23 05:24:14 -0500 |
commit | 55dba3120fbcbea6800f9a18503d25f73212a347 (patch) | |
tree | 1b23e606aad8bc58dbe68ca905c0658625fb176e /drivers/ata/pata_ixp4xx_cf.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/pata_ixp4xx_cf.c')
-rw-r--r-- | drivers/ata/pata_ixp4xx_cf.c | 26 |
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 | ||
45 | static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, | 45 | static 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 | ||
88 | static struct scsi_host_template ixp4xx_sht = { | 90 | static struct scsi_host_template ixp4xx_sht = { |