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_legacy.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_legacy.c')
-rw-r--r-- | drivers/ata/pata_legacy.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 17159b5e1e43..dae85aa12e32 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -249,13 +249,14 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
249 | 249 | ||
250 | } | 250 | } |
251 | 251 | ||
252 | static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) | 252 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, |
253 | unsigned char *buf, unsigned int buflen, int rw) | ||
253 | { | 254 | { |
254 | struct ata_port *ap = adev->link->ap; | ||
255 | int slop = buflen & 3; | ||
256 | unsigned long flags; | ||
257 | |||
258 | if (ata_id_has_dword_io(adev->id)) { | 255 | if (ata_id_has_dword_io(adev->id)) { |
256 | struct ata_port *ap = dev->link->ap; | ||
257 | int slop = buflen & 3; | ||
258 | unsigned long flags; | ||
259 | |||
259 | local_irq_save(flags); | 260 | local_irq_save(flags); |
260 | 261 | ||
261 | /* Perform the 32bit I/O synchronization sequence */ | 262 | /* Perform the 32bit I/O synchronization sequence */ |
@@ -264,26 +265,27 @@ static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsig | |||
264 | ioread8(ap->ioaddr.nsect_addr); | 265 | ioread8(ap->ioaddr.nsect_addr); |
265 | 266 | ||
266 | /* Now the data */ | 267 | /* Now the data */ |
267 | 268 | if (rw == READ) | |
268 | if (write_data) | ||
269 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
270 | else | ||
271 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 269 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
270 | else | ||
271 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
272 | 272 | ||
273 | if (unlikely(slop)) { | 273 | if (unlikely(slop)) { |
274 | __le32 pad = 0; | 274 | u32 pad; |
275 | if (write_data) { | 275 | if (rw == READ) { |
276 | memcpy(&pad, buf + buflen - slop, slop); | ||
277 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
278 | } else { | ||
279 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | 276 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); |
280 | memcpy(buf + buflen - slop, &pad, slop); | 277 | memcpy(buf + buflen - slop, &pad, slop); |
278 | } else { | ||
279 | memcpy(&pad, buf + buflen - slop, slop); | ||
280 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
281 | } | 281 | } |
282 | buflen += 4 - slop; | ||
282 | } | 283 | } |
283 | local_irq_restore(flags); | 284 | local_irq_restore(flags); |
284 | } | 285 | } else |
285 | else | 286 | buflen = ata_data_xfer_noirq(dev, buf, buflen, rw); |
286 | ata_data_xfer_noirq(adev, buf, buflen, write_data); | 287 | |
288 | return buflen; | ||
287 | } | 289 | } |
288 | 290 | ||
289 | static struct ata_port_operations pdc20230_port_ops = { | 291 | static struct ata_port_operations pdc20230_port_ops = { |