aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorMark Lord <liml@rtr.ca>2009-04-06 15:24:14 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-04-06 20:13:48 -0400
commit65ad7fef10b50b6c06d6165fa847e2d3636b0a66 (patch)
tree500afce9205d59853e14901813ae4f6689210019 /drivers/ata
parentc361acbc59c434315f8649ab06e5b7d5b297d1b7 (diff)
sata_mv: workaround errata PCI#7
Workaround for 60x1-B2 errata PCI#7. Write-combining may be unreliable when chip operates in PCI-X mode, so disable write-combining when in PCI-X mode. Also, update the errata comments at the top of sata_mv, and include a note about errata PCI#11. 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.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index a49643d16f33..b0c929d36234 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -28,10 +28,6 @@
28/* 28/*
29 * sata_mv TODO list: 29 * sata_mv TODO list:
30 * 30 *
31 * --> More errata workarounds for PCI-X.
32 *
33 * --> Complete a full errata audit for all chipsets to identify others.
34 *
35 * --> Develop a low-power-consumption strategy, and implement it. 31 * --> Develop a low-power-consumption strategy, and implement it.
36 * 32 *
37 * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds. 33 * --> Add sysfs attributes for per-chip / per-HC IRQ coalescing thresholds.
@@ -44,6 +40,15 @@
44 * connect two SATA ports. 40 * connect two SATA ports.
45 */ 41 */
46 42
43/*
44 * 80x1-B2 errata PCI#11:
45 *
46 * Users of the 6041/6081 Rev.B2 chips (current is C0)
47 * should be careful to insert those cards only onto PCI-X bus #0,
48 * and only in device slots 0..7, not higher. The chips may not
49 * work correctly otherwise (note: this is a pretty rare condition).
50 */
51
47#include <linux/kernel.h> 52#include <linux/kernel.h>
48#include <linux/module.h> 53#include <linux/module.h>
49#include <linux/pci.h> 54#include <linux/pci.h>
@@ -181,6 +186,7 @@ enum {
181 /* PCI interface registers */ 186 /* PCI interface registers */
182 187
183 PCI_COMMAND_OFS = 0xc00, 188 PCI_COMMAND_OFS = 0xc00,
189 PCI_COMMAND_MWRCOM = (1 << 4), /* PCI Master Write Combining */
184 PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */ 190 PCI_COMMAND_MRDTRIG = (1 << 7), /* PCI Master Read Trigger */
185 191
186 PCI_MAIN_CMD_STS_OFS = 0xd30, 192 PCI_MAIN_CMD_STS_OFS = 0xd30,
@@ -3527,6 +3533,18 @@ static int mv_pci_cut_through_okay(struct ata_host *host)
3527 return 1; /* okay */ 3533 return 1; /* okay */
3528} 3534}
3529 3535
3536static void mv_60x1b2_errata_pci7(struct ata_host *host)
3537{
3538 struct mv_host_priv *hpriv = host->private_data;
3539 void __iomem *mmio = hpriv->base;
3540
3541 /* workaround for 60x1-B2 errata PCI#7 */
3542 if (mv_in_pcix_mode(host)) {
3543 u32 reg = readl(mmio + PCI_COMMAND_OFS);
3544 writelfl(reg & ~PCI_COMMAND_MWRCOM, mmio + PCI_COMMAND_OFS);
3545 }
3546}
3547
3530static int mv_chip_id(struct ata_host *host, unsigned int board_idx) 3548static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
3531{ 3549{
3532 struct pci_dev *pdev = to_pci_dev(host->dev); 3550 struct pci_dev *pdev = to_pci_dev(host->dev);
@@ -3580,6 +3598,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
3580 3598
3581 switch (pdev->revision) { 3599 switch (pdev->revision) {
3582 case 0x7: 3600 case 0x7:
3601 mv_60x1b2_errata_pci7(host);
3583 hp_flags |= MV_HP_ERRATA_60X1B2; 3602 hp_flags |= MV_HP_ERRATA_60X1B2;
3584 break; 3603 break;
3585 case 0x9: 3604 case 0x9: