aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ata_piix.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r--drivers/ata/ata_piix.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 071d274afaab..3b8bf1812dc8 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -94,7 +94,7 @@
94#include <linux/dmi.h> 94#include <linux/dmi.h>
95 95
96#define DRV_NAME "ata_piix" 96#define DRV_NAME "ata_piix"
97#define DRV_VERSION "2.11" 97#define DRV_VERSION "2.12"
98 98
99enum { 99enum {
100 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ 100 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -130,6 +130,7 @@ enum {
130 ich6m_sata_ahci = 8, 130 ich6m_sata_ahci = 8,
131 ich8_sata_ahci = 9, 131 ich8_sata_ahci = 9,
132 piix_pata_mwdma = 10, /* PIIX3 MWDMA only */ 132 piix_pata_mwdma = 10, /* PIIX3 MWDMA only */
133 tolapai_sata_ahci = 11,
133 134
134 /* constants for mapping table */ 135 /* constants for mapping table */
135 P0 = 0, /* port 0 */ 136 P0 = 0, /* port 0 */
@@ -253,6 +254,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
253 { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, 254 { 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
254 /* SATA Controller IDE (ICH9M) */ 255 /* SATA Controller IDE (ICH9M) */
255 { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci }, 256 { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
257 /* SATA Controller IDE (Tolapai) */
258 { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
256 259
257 { } /* terminate list */ 260 { } /* terminate list */
258}; 261};
@@ -441,12 +444,25 @@ static const struct piix_map_db ich8_map_db = {
441 }, 444 },
442}; 445};
443 446
447static const struct piix_map_db tolapai_map_db = {
448 .mask = 0x3,
449 .port_enable = 0x3,
450 .map = {
451 /* PM PS SM SS MAP */
452 { P0, NA, P1, NA }, /* 00b */
453 { RV, RV, RV, RV }, /* 01b */
454 { RV, RV, RV, RV }, /* 10b */
455 { RV, RV, RV, RV },
456 },
457};
458
444static const struct piix_map_db *piix_map_db_table[] = { 459static const struct piix_map_db *piix_map_db_table[] = {
445 [ich5_sata] = &ich5_map_db, 460 [ich5_sata] = &ich5_map_db,
446 [ich6_sata] = &ich6_map_db, 461 [ich6_sata] = &ich6_map_db,
447 [ich6_sata_ahci] = &ich6_map_db, 462 [ich6_sata_ahci] = &ich6_map_db,
448 [ich6m_sata_ahci] = &ich6m_map_db, 463 [ich6m_sata_ahci] = &ich6m_map_db,
449 [ich8_sata_ahci] = &ich8_map_db, 464 [ich8_sata_ahci] = &ich8_map_db,
465 [tolapai_sata_ahci] = &tolapai_map_db,
450}; 466};
451 467
452static struct ata_port_info piix_port_info[] = { 468static struct ata_port_info piix_port_info[] = {
@@ -560,6 +576,17 @@ static struct ata_port_info piix_port_info[] = {
560 .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ 576 .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
561 .port_ops = &piix_pata_ops, 577 .port_ops = &piix_pata_ops,
562 }, 578 },
579
580 /* tolapai_sata_ahci: 11: */
581 {
582 .sht = &piix_sht,
583 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
584 PIIX_FLAG_AHCI,
585 .pio_mask = 0x1f, /* pio0-4 */
586 .mwdma_mask = 0x07, /* mwdma0-2 */
587 .udma_mask = ATA_UDMA6,
588 .port_ops = &piix_sata_ops,
589 },
563}; 590};
564 591
565static struct pci_bits piix_enable_bits[] = { 592static struct pci_bits piix_enable_bits[] = {
@@ -908,6 +935,13 @@ static int piix_broken_suspend(void)
908 }, 935 },
909 }, 936 },
910 { 937 {
938 .ident = "Satellite U200",
939 .matches = {
940 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
941 DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U200"),
942 },
943 },
944 {
911 .ident = "Satellite U205", 945 .ident = "Satellite U205",
912 .matches = { 946 .matches = {
913 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), 947 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
@@ -921,7 +955,8 @@ static int piix_broken_suspend(void)
921 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"), 955 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M500"),
922 }, 956 },
923 }, 957 },
924 { } 958
959 { } /* terminate list */
925 }; 960 };
926 static const char *oemstrs[] = { 961 static const char *oemstrs[] = {
927 "Tecra M3,", 962 "Tecra M3,",
@@ -1139,6 +1174,41 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
1139 hpriv->map = map; 1174 hpriv->map = map;
1140} 1175}
1141 1176
1177static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
1178{
1179 static struct dmi_system_id sysids[] = {
1180 {
1181 /* Clevo M570U sets IOCFG bit 18 if the cdrom
1182 * isn't used to boot the system which
1183 * disables the channel.
1184 */
1185 .ident = "M570U",
1186 .matches = {
1187 DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."),
1188 DMI_MATCH(DMI_PRODUCT_NAME, "M570U"),
1189 },
1190 },
1191
1192 { } /* terminate list */
1193 };
1194 u32 iocfg;
1195
1196 if (!dmi_check_system(sysids))
1197 return;
1198
1199 /* The datasheet says that bit 18 is NOOP but certain systems
1200 * seem to use it to disable a channel. Clear the bit on the
1201 * affected systems.
1202 */
1203 pci_read_config_dword(pdev, PIIX_IOCFG, &iocfg);
1204 if (iocfg & (1 << 18)) {
1205 dev_printk(KERN_INFO, &pdev->dev,
1206 "applying IOCFG bit18 quirk\n");
1207 iocfg &= ~(1 << 18);
1208 pci_write_config_dword(pdev, PIIX_IOCFG, iocfg);
1209 }
1210}
1211
1142/** 1212/**
1143 * piix_init_one - Register PIIX ATA PCI device with kernel services 1213 * piix_init_one - Register PIIX ATA PCI device with kernel services
1144 * @pdev: PCI device to register 1214 * @pdev: PCI device to register
@@ -1200,6 +1270,9 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
1200 piix_map_db_table[ent->driver_data]); 1270 piix_map_db_table[ent->driver_data]);
1201 } 1271 }
1202 1272
1273 /* apply IOCFG bit18 quirk */
1274 piix_iocfg_bit18_quirk(pdev);
1275
1203 /* On ICH5, some BIOSen disable the interrupt using the 1276 /* On ICH5, some BIOSen disable the interrupt using the
1204 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3. 1277 * PCI_COMMAND_INTX_DISABLE bit added in PCI 2.3.
1205 * On ICH6, this bit has the same effect, but only when 1278 * On ICH6, this bit has the same effect, but only when