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.c52
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
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,
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);
90static const struct pci_device_id sil_pci_tbl[] = { 92static 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