diff options
author | Mark Lord <liml@rtr.ca> | 2009-04-06 15:26:24 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-04-06 20:14:10 -0400 |
commit | 12f3b6d7551306c00cf834540a33184de67c9187 (patch) | |
tree | a5de4682a13cf4d1640c15d13a7dccf9890319fa /drivers/ata | |
parent | ba68460b8e019dfd9c73ab69f5ed163a8b24e296 (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.c | 20 |
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) | |||
919 | static inline void mv_write_cached_reg(void __iomem *addr, u32 *old, u32 new) | 919 | static 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 | ||