diff options
| -rw-r--r-- | drivers/scsi/sata_sil.c | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 510c2e0bd90e..9face3c6aa21 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #define DRV_VERSION "0.9" | 49 | #define DRV_VERSION "0.9" |
| 50 | 50 | ||
| 51 | enum { | 51 | enum { |
| 52 | SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), | ||
| 52 | SIL_FLAG_MOD15WRITE = (1 << 30), | 53 | SIL_FLAG_MOD15WRITE = (1 << 30), |
| 53 | 54 | ||
| 54 | sil_3112 = 0, | 55 | sil_3112 = 0, |
| @@ -202,7 +203,8 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 202 | { | 203 | { |
| 203 | .sht = &sil_sht, | 204 | .sht = &sil_sht, |
| 204 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 205 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 205 | ATA_FLAG_SRST | ATA_FLAG_MMIO, | 206 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
| 207 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
| 206 | .pio_mask = 0x1f, /* pio0-4 */ | 208 | .pio_mask = 0x1f, /* pio0-4 */ |
| 207 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 209 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| 208 | .udma_mask = 0x3f, /* udma0-5 */ | 210 | .udma_mask = 0x3f, /* udma0-5 */ |
| @@ -212,7 +214,8 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 212 | { | 214 | { |
| 213 | .sht = &sil_sht, | 215 | .sht = &sil_sht, |
| 214 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 216 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 215 | ATA_FLAG_SRST | ATA_FLAG_MMIO, | 217 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
| 218 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
| 216 | .pio_mask = 0x1f, /* pio0-4 */ | 219 | .pio_mask = 0x1f, /* pio0-4 */ |
| 217 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 220 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| 218 | .udma_mask = 0x3f, /* udma0-5 */ | 221 | .udma_mask = 0x3f, /* udma0-5 */ |
| @@ -229,12 +232,13 @@ static const struct { | |||
| 229 | unsigned long scr; /* SATA control register block */ | 232 | unsigned long scr; /* SATA control register block */ |
| 230 | unsigned long sien; /* SATA Interrupt Enable register */ | 233 | unsigned long sien; /* SATA Interrupt Enable register */ |
| 231 | unsigned long xfer_mode;/* data transfer mode register */ | 234 | unsigned long xfer_mode;/* data transfer mode register */ |
| 235 | unsigned long sfis_cfg; /* SATA FIS reception config register */ | ||
| 232 | } sil_port[] = { | 236 | } sil_port[] = { |
| 233 | /* port 0 ... */ | 237 | /* port 0 ... */ |
| 234 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, | 238 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, |
| 235 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, | 239 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, |
| 236 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, | 240 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, |
| 237 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, | 241 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, |
| 238 | /* ... port 3 */ | 242 | /* ... port 3 */ |
| 239 | }; | 243 | }; |
| 240 | 244 | ||
| @@ -484,6 +488,23 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 484 | dev_printk(KERN_WARNING, &pdev->dev, | 488 | dev_printk(KERN_WARNING, &pdev->dev, |
| 485 | "cache line size not set. Driver may not function\n"); | 489 | "cache line size not set. Driver may not function\n"); |
| 486 | 490 | ||
| 491 | /* Apply R_ERR on DMA activate FIS errata workaround */ | ||
| 492 | if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | ||
| 493 | int cnt; | ||
| 494 | |||
| 495 | for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) { | ||
| 496 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | ||
| 497 | if ((tmp & 0x3) != 0x01) | ||
| 498 | continue; | ||
| 499 | if (!cnt) | ||
| 500 | dev_printk(KERN_INFO, &pdev->dev, | ||
| 501 | "Applying R_ERR on DMA activate " | ||
| 502 | "FIS errata fix\n"); | ||
| 503 | writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); | ||
| 504 | cnt++; | ||
| 505 | } | ||
| 506 | } | ||
| 507 | |||
| 487 | if (ent->driver_data == sil_3114) { | 508 | if (ent->driver_data == sil_3114) { |
| 488 | irq_mask = SIL_MASK_4PORT; | 509 | irq_mask = SIL_MASK_4PORT; |
| 489 | 510 | ||
