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_qdi.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_qdi.c')
-rw-r--r-- | drivers/ata/pata_qdi.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c index a4c0e502cb42..9f308ed76cc8 100644 --- a/drivers/ata/pata_qdi.c +++ b/drivers/ata/pata_qdi.c | |||
@@ -124,29 +124,33 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc) | |||
124 | return ata_qc_issue_prot(qc); | 124 | return ata_qc_issue_prot(qc); |
125 | } | 125 | } |
126 | 126 | ||
127 | static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) | 127 | static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf, |
128 | unsigned int buflen, int rw) | ||
128 | { | 129 | { |
129 | struct ata_port *ap = adev->link->ap; | 130 | if (ata_id_has_dword_io(dev->id)) { |
130 | int slop = buflen & 3; | 131 | struct ata_port *ap = dev->link->ap; |
132 | int slop = buflen & 3; | ||
131 | 133 | ||
132 | if (ata_id_has_dword_io(adev->id)) { | 134 | if (rw == READ) |
133 | if (write_data) | ||
134 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
135 | else | ||
136 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 135 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
136 | else | ||
137 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
137 | 138 | ||
138 | if (unlikely(slop)) { | 139 | if (unlikely(slop)) { |
139 | __le32 pad = 0; | 140 | u32 pad; |
140 | if (write_data) { | 141 | if (rw == READ) { |
141 | memcpy(&pad, buf + buflen - slop, slop); | ||
142 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
143 | } else { | ||
144 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | 142 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); |
145 | memcpy(buf + buflen - slop, &pad, slop); | 143 | memcpy(buf + buflen - slop, &pad, slop); |
144 | } else { | ||
145 | memcpy(&pad, buf + buflen - slop, slop); | ||
146 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
146 | } | 147 | } |
148 | buflen += 4 - slop; | ||
147 | } | 149 | } |
148 | } else | 150 | } else |
149 | ata_data_xfer(adev, buf, buflen, write_data); | 151 | buflen = ata_data_xfer(dev, buf, buflen, rw); |
152 | |||
153 | return buflen; | ||
150 | } | 154 | } |
151 | 155 | ||
152 | static struct scsi_host_template qdi_sht = { | 156 | static struct scsi_host_template qdi_sht = { |