|
@@ -773,18 +773,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
|
|
|
else
|
|
|
iowrite32_rep(data_addr, buf, words);
|
|
|
|
|
|
+ /* Transfer trailing bytes, if any */
|
|
|
if (unlikely(slop)) {
|
|
|
- __le32 pad;
|
|
|
+ unsigned char pad[4];
|
|
|
+
|
|
|
+ /* Point buf to the tail of buffer */
|
|
|
+ buf += buflen - slop;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Use io*_rep() accessors here as well to avoid pointlessly
|
|
|
+ * swapping bytes to and fro on the big endian machines...
|
|
|
+ */
|
|
|
if (rw == READ) {
|
|
|
- pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr));
|
|
|
- memcpy(buf + buflen - slop, &pad, slop);
|
|
|
+ if (slop < 3)
|
|
|
+ ioread16_rep(data_addr, pad, 1);
|
|
|
+ else
|
|
|
+ ioread32_rep(data_addr, pad, 1);
|
|
|
+ memcpy(buf, pad, slop);
|
|
|
} else {
|
|
|
- memcpy(&pad, buf + buflen - slop, slop);
|
|
|
- iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr);
|
|
|
+ memcpy(pad, buf, slop);
|
|
|
+ if (slop < 3)
|
|
|
+ iowrite16_rep(data_addr, pad, 1);
|
|
|
+ else
|
|
|
+ iowrite32_rep(data_addr, pad, 1);
|
|
|
}
|
|
|
- words++;
|
|
|
}
|
|
|
- return words << 2;
|
|
|
+ return (buflen + 1) & ~1;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
|
|
|
|