diff options
| -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 17f74d3c10e7..9face3c6aa21 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 | |
| @@ -195,11 +198,24 @@ static const struct ata_port_info sil_port_info[] = { | |||
| 195 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 198 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| 196 | .udma_mask = 0x3f, /* udma0-5 */ | 199 | .udma_mask = 0x3f, /* udma0-5 */ |
| 197 | .port_ops = &sil_ops, | 200 | .port_ops = &sil_ops, |
| 198 | }, /* sil_3114 */ | 201 | }, |
| 202 | /* sil_3512 */ | ||
| 199 | { | 203 | { |
| 200 | .sht = &sil_sht, | 204 | .sht = &sil_sht, |
| 201 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 205 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
| 202 | ATA_FLAG_SRST | ATA_FLAG_MMIO, | 206 | ATA_FLAG_SRST | ATA_FLAG_MMIO | |
| 207 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
| 208 | .pio_mask = 0x1f, /* pio0-4 */ | ||
| 209 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
| 210 | .udma_mask = 0x3f, /* udma0-5 */ | ||
| 211 | .port_ops = &sil_ops, | ||
| 212 | }, | ||
| 213 | /* sil_3114 */ | ||
| 214 | { | ||
| 215 | .sht = &sil_sht, | ||
| 216 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
| 217 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | ||
| 218 | SIL_FLAG_RERR_ON_DMA_ACT, | ||
| 203 | .pio_mask = 0x1f, /* pio0-4 */ | 219 | .pio_mask = 0x1f, /* pio0-4 */ |
| 204 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 220 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
| 205 | .udma_mask = 0x3f, /* udma0-5 */ | 221 | .udma_mask = 0x3f, /* udma0-5 */ |
| @@ -216,12 +232,13 @@ static const struct { | |||
| 216 | unsigned long scr; /* SATA control register block */ | 232 | unsigned long scr; /* SATA control register block */ |
| 217 | unsigned long sien; /* SATA Interrupt Enable register */ | 233 | unsigned long sien; /* SATA Interrupt Enable register */ |
| 218 | 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 */ | ||
| 219 | } sil_port[] = { | 236 | } sil_port[] = { |
| 220 | /* port 0 ... */ | 237 | /* port 0 ... */ |
| 221 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4 }, | 238 | { 0x80, 0x8A, 0x00, 0x100, 0x148, 0xb4, 0x14c }, |
| 222 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4 }, | 239 | { 0xC0, 0xCA, 0x08, 0x180, 0x1c8, 0xf4, 0x1cc }, |
| 223 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4 }, | 240 | { 0x280, 0x28A, 0x200, 0x300, 0x348, 0x2b4, 0x34c }, |
| 224 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4 }, | 241 | { 0x2C0, 0x2CA, 0x208, 0x380, 0x3c8, 0x2f4, 0x3cc }, |
| 225 | /* ... port 3 */ | 242 | /* ... port 3 */ |
| 226 | }; | 243 | }; |
| 227 | 244 | ||
| @@ -471,6 +488,23 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 471 | dev_printk(KERN_WARNING, &pdev->dev, | 488 | dev_printk(KERN_WARNING, &pdev->dev, |
| 472 | "cache line size not set. Driver may not function\n"); | 489 | "cache line size not set. Driver may not function\n"); |
| 473 | 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 | |||
| 474 | if (ent->driver_data == sil_3114) { | 508 | if (ent->driver_data == sil_3114) { |
| 475 | irq_mask = SIL_MASK_4PORT; | 509 | irq_mask = SIL_MASK_4PORT; |
| 476 | 510 | ||
