]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
sata_mv: workaround errata SATA#13
authorMark Lord <liml@rtr.ca>
Mon, 6 Apr 2009 19:26:24 +0000 (15:26 -0400)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 7 Apr 2009 00:14:10 +0000 (20:14 -0400)
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>
drivers/ata/sata_mv.c

index 55d3ce087304d604e2493023a9b87a16718787db..82d928a426ac29b1ccbad80f7c1a5823e1812a51 100644 (file)
@@ -919,8 +919,26 @@ static void mv_save_cached_regs(struct ata_port *ap)
 static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new)
 {
        if (new != *old) {
+               unsigned long laddr;
                *old = new;
-               writel(new, addr);
+               /*
+                * Workaround for 88SX60x1-B2 FEr SATA#13:
+                * Read-after-write is needed to prevent generating 64-bit
+                * write cycles on the PCI bus for SATA interface registers
+                * at offsets ending in 0x4 or 0xc.
+                *
+                * Looks like a lot of fuss, but it avoids an unnecessary
+                * +1 usec read-after-write delay for unaffected registers.
+                */
+               laddr = (long)addr & 0xffff;
+               if (laddr >= 0x300 && laddr <= 0x33c) {
+                       laddr &= 0x000f;
+                       if (laddr == 0x4 || laddr == 0xc) {
+                               writelfl(new, addr); /* read after write */
+                               return;
+                       }
+               }
+               writel(new, addr); /* unaffected by the errata */
        }
 }