aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_legacy.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_legacy.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_legacy.c')
-rw-r--r--drivers/ata/pata_legacy.c36
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
252static void pdc_data_xfer_vlb(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) 252static 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
289static struct ata_port_operations pdc20230_port_ops = { 291static struct ata_port_operations pdc20230_port_ops = {