aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_sil.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sata_sil.c')
-rw-r--r--drivers/scsi/sata_sil.c33
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
51enum { 51enum {
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