diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 34 |
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 | } |
789 | EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); | 803 | EXPORT_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 | } |
2182 | EXPORT_SYMBOL_GPL(ata_sff_postreset); | 2199 | EXPORT_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"); |