diff options
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 77 |
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 | ||
99 | enum { | 99 | enum { |
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 | ||
447 | static 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 | |||
444 | static const struct piix_map_db *piix_map_db_table[] = { | 459 | static 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 | ||
452 | static struct ata_port_info piix_port_info[] = { | 468 | static 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 | ||
565 | static struct pci_bits piix_enable_bits[] = { | 592 | static 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 | ||
1177 | static 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 |