aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/pata_qdi.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_qdi.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_qdi.c')
-rw-r--r--drivers/ata/pata_qdi.c30
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
127static void qdi_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) 127static 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
152static struct scsi_host_template qdi_sht = { 156static struct scsi_host_template qdi_sht = {