aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2009-04-06 15:26:24 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-04-06 20:14:10 -0400
commit12f3b6d7551306c00cf834540a33184de67c9187 (patch)
treea5de4682a13cf4d1640c15d13a7dccf9890319fa /drivers/ata
parentba68460b8e019dfd9c73ab69f5ed163a8b24e296 (diff)
sata_mv: workaround errata SATA#13
Add remainder of workaround for errata SATA#13. This prevents writes of certain adjacent 32-bit registers from being combined into single 64-bit writes, which might fail for the affected registers. Most of sata_mv is already safe from this issue, but adding this code to mv_write_cached_reg() will catch the remaining cases and hopefully prevent future ones. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_mv.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 55d3ce087304..82d928a426ac 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -919,8 +919,26 @@ static void mv_save_cached_regs(struct ata_port *ap)
919static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new) 919static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
920{ 920{
921 if (new != *old) { 921 if (new != *old) {
922 unsigned long laddr;
922 *old = new; 923 *old = new;
923 writel(new, addr); 924 /*
925 * Workaround for 88SX60x1-B2 FEr SATA#13:
926 * Read-after-write is needed to prevent generating 64-bit
927 * write cycles on the PCI bus for SATA interface registers
928 * at offsets ending in 0x4 or 0xc.
929 *
930 * Looks like a lot of fuss, but it avoids an unnecessary
931 * +1 usec read-after-write delay for unaffected registers.
932 */
933 laddr = (long)addr & 0xffff;
934 if (laddr >= 0x300 && laddr <= 0x33c) {
935 laddr &= 0x000f;
936 if (laddr == 0x4 || laddr == 0xc) {
937 writelfl(new, addr); /* read after write */
938 return;
939 }
940 }
941 writel(new, addr); /* unaffected by the errata */
924 } 942 }
925} 943}
926 944