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 345e6f2d28a8..71d49548f0a3 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -27,6 +27,11 @@ | |||
27 | * libata documentation is available via 'make {ps|pdf}docs', | 27 | * libata documentation is available via 'make {ps|pdf}docs', |
28 | * as Documentation/DocBook/libata.* | 28 | * as Documentation/DocBook/libata.* |
29 | * | 29 | * |
30 | * Documentation for SiI 3112: | ||
31 | * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2 | ||
32 | * | ||
33 | * Other errata and documentation available under NDA. | ||
34 | * | ||
30 | */ | 35 | */ |
31 | 36 | ||
32 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -44,8 +49,11 @@ | |||
44 | #define DRV_VERSION "0.9" | 49 | #define DRV_VERSION "0.9" |
45 | 50 | ||
46 | enum { | 51 | enum { |
52 | SIL_FLAG_MOD15WRITE = (1 << 30), | ||
53 | |||
47 | sil_3112 = 0, | 54 | sil_3112 = 0, |
48 | sil_3114 = 1, | 55 | sil_3112_m15w = 1, |
56 | sil_3114 = 2, | ||
49 | 57 | ||
50 | SIL_FIFO_R0 = 0x40, | 58 | SIL_FIFO_R0 = 0x40, |
51 | SIL_FIFO_W0 = 0x41, | 59 | SIL_FIFO_W0 = 0x41, |
@@ -79,13 +87,13 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
79 | static void sil_post_set_mode (struct ata_port *ap); | 87 | static void sil_post_set_mode (struct ata_port *ap); |
80 | 88 | ||
81 | static struct pci_device_id sil_pci_tbl[] = { | 89 | static struct pci_device_id sil_pci_tbl[] = { |
82 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 90 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
83 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 91 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
84 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 92 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, |
85 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 93 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
86 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 94 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
87 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 95 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
88 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 96 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
89 | { } /* terminate list */ | 97 | { } /* terminate list */ |
90 | }; | 98 | }; |
91 | 99 | ||
@@ -177,6 +185,16 @@ static struct ata_port_info sil_port_info[] = { | |||
177 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 185 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
178 | .udma_mask = 0x3f, /* udma0-5 */ | 186 | .udma_mask = 0x3f, /* udma0-5 */ |
179 | .port_ops = &sil_ops, | 187 | .port_ops = &sil_ops, |
188 | }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | ||
189 | { | ||
190 | .sht = &sil_sht, | ||
191 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
192 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | ||
193 | SIL_FLAG_MOD15WRITE, | ||
194 | .pio_mask = 0x1f, /* pio0-4 */ | ||
195 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
196 | .udma_mask = 0x3f, /* udma0-5 */ | ||
197 | .port_ops = &sil_ops, | ||
180 | }, /* sil_3114 */ | 198 | }, /* sil_3114 */ |
181 | { | 199 | { |
182 | .sht = &sil_sht, | 200 | .sht = &sil_sht, |
@@ -326,15 +344,15 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
326 | while ((len > 0) && (s[len - 1] == ' ')) | 344 | while ((len > 0) && (s[len - 1] == ' ')) |
327 | len--; | 345 | len--; |
328 | 346 | ||
329 | for (n = 0; sil_blacklist[n].product; n++) | 347 | for (n = 0; sil_blacklist[n].product; n++) |
330 | if (!memcmp(sil_blacklist[n].product, s, | 348 | if (!memcmp(sil_blacklist[n].product, s, |
331 | strlen(sil_blacklist[n].product))) { | 349 | strlen(sil_blacklist[n].product))) { |
332 | quirks = sil_blacklist[n].quirk; | 350 | quirks = sil_blacklist[n].quirk; |
333 | break; | 351 | break; |
334 | } | 352 | } |
335 | 353 | ||
336 | /* limit requests to 15 sectors */ | 354 | /* limit requests to 15 sectors */ |
337 | if (quirks & SIL_QUIRK_MOD15WRITE) { | 355 | if ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE)) { |
338 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", | 356 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", |
339 | ap->id, dev->devno); | 357 | ap->id, dev->devno); |
340 | ap->host->max_sectors = 15; | 358 | ap->host->max_sectors = 15; |