diff options
Diffstat (limited to 'drivers/scsi/sata_sil.c')
-rw-r--r-- | drivers/scsi/sata_sil.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 49ed557a4b66..9d24d6c328b4 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -24,6 +24,11 @@ | |||
24 | * If you do not delete the provisions above, a recipient may use your | 24 | * If you do not delete the provisions above, a recipient may use your |
25 | * version of this file under either the OSL or the GPL. | 25 | * version of this file under either the OSL or the GPL. |
26 | * | 26 | * |
27 | * Documentation for SiI 3112: | ||
28 | * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2 | ||
29 | * | ||
30 | * Other errata and documentation available under NDA. | ||
31 | * | ||
27 | */ | 32 | */ |
28 | 33 | ||
29 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
@@ -41,8 +46,11 @@ | |||
41 | #define DRV_VERSION "0.9" | 46 | #define DRV_VERSION "0.9" |
42 | 47 | ||
43 | enum { | 48 | enum { |
49 | SIL_FLAG_MOD15WRITE = (1 << 30), | ||
50 | |||
44 | sil_3112 = 0, | 51 | sil_3112 = 0, |
45 | sil_3114 = 1, | 52 | sil_3112_m15w = 1, |
53 | sil_3114 = 2, | ||
46 | 54 | ||
47 | SIL_FIFO_R0 = 0x40, | 55 | SIL_FIFO_R0 = 0x40, |
48 | SIL_FIFO_W0 = 0x41, | 56 | SIL_FIFO_W0 = 0x41, |
@@ -76,13 +84,13 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
76 | static void sil_post_set_mode (struct ata_port *ap); | 84 | static void sil_post_set_mode (struct ata_port *ap); |
77 | 85 | ||
78 | static struct pci_device_id sil_pci_tbl[] = { | 86 | static struct pci_device_id sil_pci_tbl[] = { |
79 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 87 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
80 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 88 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
81 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 89 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, |
82 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 90 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
83 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 91 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
84 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 92 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
85 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 93 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
86 | { } /* terminate list */ | 94 | { } /* terminate list */ |
87 | }; | 95 | }; |
88 | 96 | ||
@@ -174,6 +182,16 @@ static struct ata_port_info sil_port_info[] = { | |||
174 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 182 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
175 | .udma_mask = 0x3f, /* udma0-5 */ | 183 | .udma_mask = 0x3f, /* udma0-5 */ |
176 | .port_ops = &sil_ops, | 184 | .port_ops = &sil_ops, |
185 | }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | ||
186 | { | ||
187 | .sht = &sil_sht, | ||
188 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
189 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | ||
190 | SIL_FLAG_MOD15WRITE, | ||
191 | .pio_mask = 0x1f, /* pio0-4 */ | ||
192 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
193 | .udma_mask = 0x3f, /* udma0-5 */ | ||
194 | .port_ops = &sil_ops, | ||
177 | }, /* sil_3114 */ | 195 | }, /* sil_3114 */ |
178 | { | 196 | { |
179 | .sht = &sil_sht, | 197 | .sht = &sil_sht, |
@@ -323,15 +341,15 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
323 | while ((len > 0) && (s[len - 1] == ' ')) | 341 | while ((len > 0) && (s[len - 1] == ' ')) |
324 | len--; | 342 | len--; |
325 | 343 | ||
326 | for (n = 0; sil_blacklist[n].product; n++) | 344 | for (n = 0; sil_blacklist[n].product; n++) |
327 | if (!memcmp(sil_blacklist[n].product, s, | 345 | if (!memcmp(sil_blacklist[n].product, s, |
328 | strlen(sil_blacklist[n].product))) { | 346 | strlen(sil_blacklist[n].product))) { |
329 | quirks = sil_blacklist[n].quirk; | 347 | quirks = sil_blacklist[n].quirk; |
330 | break; | 348 | break; |
331 | } | 349 | } |
332 | 350 | ||
333 | /* limit requests to 15 sectors */ | 351 | /* limit requests to 15 sectors */ |
334 | if (quirks & SIL_QUIRK_MOD15WRITE) { | 352 | if ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE)) { |
335 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", | 353 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", |
336 | ap->id, dev->devno); | 354 | ap->id, dev->devno); |
337 | ap->host->max_sectors = 15; | 355 | ap->host->max_sectors = 15; |