From: Mark Lord Date: Mon, 6 Apr 2009 19:26:24 +0000 (-0400) Subject: sata_mv: workaround errata SATA#13 X-Git-Tag: v2.6.30-rc1~10^2~1 X-Git-Url: http://bbs.cooldavid.org/git/?a=commitdiff_plain;h=12f3b6d7551306c00cf834540a33184de67c9187;p=net-next-2.6.git 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 Signed-off-by: Jeff Garzik --- diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 55d3ce08730..82d928a426a 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) 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 */ } }