diff options
Diffstat (limited to 'drivers/scsi/sata_sil.c')
-rw-r--r-- | drivers/scsi/sata_sil.c | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index e14ed4ebbeed..91ecf527bb8a 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -49,11 +49,13 @@ | |||
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, |
55 | sil_3112_m15w = 1, | 56 | sil_3112_m15w = 1, |
56 | sil_3114 = 2, | 57 | sil_3512 = 2, |
58 | sil_3114 = 3, | ||
57 | 59 | ||
58 | SIL_FIFO_R0 = 0x40, | 60 | SIL_FIFO_R0 = 0x40, |
59 | SIL_FIFO_W0 = 0x41, | 61 | SIL_FIFO_W0 = 0x41, |
@@ -90,7 +92,7 @@ static void sil_post_set_mode (struct ata_port *ap); | |||
90 | static const struct pci_device_id sil_pci_tbl[] = { | 92 | static const struct pci_device_id sil_pci_tbl[] = { |
91 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 93 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
92 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 94 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
93 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 95 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, |
94 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 96 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
95 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 97 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
96 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, | 98 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
@@ -185,7 +187,8 @@ static const struct ata_port_info sil_port_info[] = { | |||
185 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 187 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
186 | .udma_mask = 0x3f, /* udma0-5 */ | 188 | .udma_mask = 0x3f, /* udma0-5 */ |
187 | .port_ops = &sil_ops, | 189 | .port_ops = &sil_ops, |
188 | }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | 190 | }, |
191 | /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | ||
189 | { | 192 | { |
190 | .sht = &sil_sht, | 193 | .sht = &sil_sht, |
191 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 194 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
@@ -194,11 +197,24 @@ static const struct ata_port_info sil_port_info[] = { | |||
194 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 197 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
195 | .udma_mask = 0x3f, /* udma0-5 */ | 198 | .udma_mask = 0x3f, /* udma0-5 */ |
196 | .port_ops = &sil_ops, | 199 | .port_ops = &sil_ops, |
197 | }, /* sil_3114 */ | 200 | }, |
201 | /* sil_3512 */ | ||
198 | { | 202 | { |
199 | .sht = &sil_sht, | 203 | .sht = &sil_sht, |
200 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 204 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
201 | ATA_FLAG_MMIO, | 205 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
206 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
207 | .pio_mask = 0x1f, /* pio0-4 */ | ||
208 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
209 | .udma_mask = 0x3f, /* udma0-5 */ | ||
210 | .port_ops = &sil_ops, | ||
211 | }, | ||
212 | /* sil_3114 */ | ||
213 | { | ||
214 | .sht = &sil_sht, | ||
215 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
216 | ATA_FLAG_MMIO | | ||
217 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
202 | .pio_mask = 0x1f, /* pio0-4 */ | 218 | .pio_mask = 0x1f, /* pio0-4 */ |
203 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 219 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
204 | .udma_mask = 0x3f, /* udma0-5 */ | 220 | .udma_mask = 0x3f, /* udma0-5 */ |
@@ -215,12 +231,13 @@ static const struct { | |||
215 | unsigned long scr; /* SATA control register block */ | 231 | unsigned long scr; /* SATA control register block */ |
216 | unsigned long sien; /* SATA Interrupt Enable register */ | 232 | unsigned long sien; /* SATA Interrupt Enable register */ |
217 | unsigned long xfer_mode;/* data transfer mode register */ | 233 | unsigned long xfer_mode;/* data transfer mode register */ |
234 | unsigned long sfis_cfg; /* SATA FIS reception config register */ | ||
218 | } sil_port[] = { | 235 | } sil_port[] = { |
219 | /* port 0 ... */ | 236 | /* port 0 ... */ |
220 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, | 237 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, |
221 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, | 238 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, |
222 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, | 239 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, |
223 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, | 240 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, |
224 | /* ... port 3 */ | 241 | /* ... port 3 */ |
225 | }; | 242 | }; |
226 | 243 | ||
@@ -458,6 +475,23 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
458 | dev_printk(KERN_WARNING, &pdev->dev, | 475 | dev_printk(KERN_WARNING, &pdev->dev, |
459 | "cache line size not set. Driver may not function\n"); | 476 | "cache line size not set. Driver may not function\n"); |
460 | 477 | ||
478 | /* Apply R_ERR on DMA activate FIS errata workaround */ | ||
479 | if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) { | ||
480 | int cnt; | ||
481 | |||
482 | for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) { | ||
483 | tmp = readl(mmio_base + sil_port[i].sfis_cfg); | ||
484 | if ((tmp & 0x3) != 0x01) | ||
485 | continue; | ||
486 | if (!cnt) | ||
487 | dev_printk(KERN_INFO, &pdev->dev, | ||
488 | "Applying R_ERR on DMA activate " | ||
489 | "FIS errata fix\n"); | ||
490 | writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg); | ||
491 | cnt++; | ||
492 | } | ||
493 | } | ||
494 | |||
461 | if (ent->driver_data == sil_3114) { | 495 | if (ent->driver_data == sil_3114) { |
462 | irq_mask = SIL_MASK_4PORT; | 496 | irq_mask = SIL_MASK_4PORT; |
463 | 497 | ||