aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-sff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r--drivers/ata/libata-sff.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 0b299b0f8172..f93dc029dfde 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -773,18 +773,32 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
773 else 773 else
774 iowrite32_rep(data_addr, buf, words); 774 iowrite32_rep(data_addr, buf, words);
775 775
776 /* Transfer trailing bytes, if any */
776 if (unlikely(slop)) { 777 if (unlikely(slop)) {
777 __le32 pad; 778 unsigned char pad[4];
779
780 /* Point buf to the tail of buffer */
781 buf += buflen - slop;
782
783 /*
784 * Use io*_rep() accessors here as well to avoid pointlessly
785 * swapping bytes to and fro on the big endian machines...
786 */
778 if (rw == READ) { 787 if (rw == READ) {
779 pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); 788 if (slop < 3)
780 memcpy(buf + buflen - slop, &pad, slop); 789 ioread16_rep(data_addr, pad, 1);
790 else
791 ioread32_rep(data_addr, pad, 1);
792 memcpy(buf, pad, slop);
781 } else { 793 } else {
782 memcpy(&pad, buf + buflen - slop, slop); 794 memcpy(pad, buf, slop);
783 iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); 795 if (slop < 3)
796 iowrite16_rep(data_addr, pad, 1);
797 else
798 iowrite32_rep(data_addr, pad, 1);
784 } 799 }
785 words++;
786 } 800 }
787 return words << 2; 801 return (buflen + 1) & ~1;
788} 802}
789EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); 803EXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
790 804
@@ -2052,6 +2066,7 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
2052 iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr); 2066 iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
2053 udelay(20); /* FIXME: flush */ 2067 udelay(20); /* FIXME: flush */
2054 iowrite8(ap->ctl, ioaddr->ctl_addr); 2068 iowrite8(ap->ctl, ioaddr->ctl_addr);
2069 ap->last_ctl = ap->ctl;
2055 2070
2056 /* wait the port to become ready */ 2071 /* wait the port to become ready */
2057 return ata_sff_wait_after_reset(&ap->link, devmask, deadline); 2072 return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
@@ -2176,8 +2191,10 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
2176 } 2191 }
2177 2192
2178 /* set up device control */ 2193 /* set up device control */
2179 if (ap->ioaddr.ctl_addr) 2194 if (ap->ioaddr.ctl_addr) {
2180 iowrite8(ap->ctl, ap->ioaddr.ctl_addr); 2195 iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
2196 ap->last_ctl = ap->ctl;
2197 }
2181} 2198}
2182EXPORT_SYMBOL_GPL(ata_sff_postreset); 2199EXPORT_SYMBOL_GPL(ata_sff_postreset);
2183 2200
@@ -2520,6 +2537,7 @@ void ata_bus_reset(struct ata_port *ap)
2520 if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) { 2537 if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
2521 /* set up device control for ATA_FLAG_SATA_RESET */ 2538 /* set up device control for ATA_FLAG_SATA_RESET */
2522 iowrite8(ap->ctl, ioaddr->ctl_addr); 2539 iowrite8(ap->ctl, ioaddr->ctl_addr);
2540 ap->last_ctl = ap->ctl;
2523 } 2541 }
2524 2542
2525 DPRINTK("EXIT\n"); 2543 DPRINTK("EXIT\n");