diff options
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r-- | drivers/ata/ata_piix.c | 184 |
1 files changed, 54 insertions, 130 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index e6b4606e36b6..e9e32ed6b1a3 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -165,8 +165,10 @@ static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev); | |||
165 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); | 165 | static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev); |
166 | static int ich_pata_cable_detect(struct ata_port *ap); | 166 | static int ich_pata_cable_detect(struct ata_port *ap); |
167 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); | 167 | static u8 piix_vmw_bmdma_status(struct ata_port *ap); |
168 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val); | 168 | static int piix_sidpr_scr_read(struct ata_link *link, |
169 | static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val); | 169 | unsigned int reg, u32 *val); |
170 | static int piix_sidpr_scr_write(struct ata_link *link, | ||
171 | unsigned int reg, u32 val); | ||
170 | #ifdef CONFIG_PM | 172 | #ifdef CONFIG_PM |
171 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); | 173 | static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); |
172 | static int piix_pci_device_resume(struct pci_dev *pdev); | 174 | static int piix_pci_device_resume(struct pci_dev *pdev); |
@@ -278,12 +280,15 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
278 | /* SATA Controller IDE (PCH) */ | 280 | /* SATA Controller IDE (PCH) */ |
279 | { 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | 281 | { 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
280 | /* SATA Controller IDE (PCH) */ | 282 | /* SATA Controller IDE (PCH) */ |
283 | { 0x8086, 0x3b21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
284 | /* SATA Controller IDE (PCH) */ | ||
281 | { 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 285 | { 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
282 | /* SATA Controller IDE (PCH) */ | 286 | /* SATA Controller IDE (PCH) */ |
287 | { 0x8086, 0x3b28, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
288 | /* SATA Controller IDE (PCH) */ | ||
283 | { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 289 | { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
284 | /* SATA Controller IDE (PCH) */ | 290 | /* SATA Controller IDE (PCH) */ |
285 | { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | 291 | { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
286 | |||
287 | { } /* terminate list */ | 292 | { } /* terminate list */ |
288 | }; | 293 | }; |
289 | 294 | ||
@@ -582,6 +587,7 @@ static const struct ich_laptop ich_laptop[] = { | |||
582 | { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ | 587 | { 0x27DF, 0x1025, 0x0110 }, /* ICH7 on Acer 3682WLMi */ |
583 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ | 588 | { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ |
584 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ | 589 | { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ |
590 | { 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */ | ||
585 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ | 591 | { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
586 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ | 592 | { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ |
587 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ | 593 | { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ |
@@ -885,23 +891,9 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
885 | * Serial ATA Index/Data Pair Superset Registers access | 891 | * Serial ATA Index/Data Pair Superset Registers access |
886 | * | 892 | * |
887 | * Beginning from ICH8, there's a sane way to access SCRs using index | 893 | * Beginning from ICH8, there's a sane way to access SCRs using index |
888 | * and data register pair located at BAR5. This creates an | 894 | * and data register pair located at BAR5 which means that we have |
889 | * interesting problem of mapping two SCRs to one port. | 895 | * separate SCRs for master and slave. This is handled using libata |
890 | * | 896 | * slave_link facility. |
891 | * Although they have separate SCRs, the master and slave aren't | ||
892 | * independent enough to be treated as separate links - e.g. softreset | ||
893 | * resets both. Also, there's no protocol defined for hard resetting | ||
894 | * singled device sharing the virtual port (no defined way to acquire | ||
895 | * device signature). This is worked around by merging the SCR values | ||
896 | * into one sensible value and requesting follow-up SRST after | ||
897 | * hardreset. | ||
898 | * | ||
899 | * SCR merging is perfomed in nibbles which is the unit contents in | ||
900 | * SCRs are organized. If two values are equal, the value is used. | ||
901 | * When they differ, merge table which lists precedence of possible | ||
902 | * values is consulted and the first match or the last entry when | ||
903 | * nothing matches is used. When there's no merge table for the | ||
904 | * specific nibble, value from the first port is used. | ||
905 | */ | 897 | */ |
906 | static const int piix_sidx_map[] = { | 898 | static const int piix_sidx_map[] = { |
907 | [SCR_STATUS] = 0, | 899 | [SCR_STATUS] = 0, |
@@ -909,120 +901,38 @@ static const int piix_sidx_map[] = { | |||
909 | [SCR_CONTROL] = 1, | 901 | [SCR_CONTROL] = 1, |
910 | }; | 902 | }; |
911 | 903 | ||
912 | static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg) | 904 | static void piix_sidpr_sel(struct ata_link *link, unsigned int reg) |
913 | { | 905 | { |
914 | struct ata_port *ap = dev->link->ap; | 906 | struct ata_port *ap = link->ap; |
915 | struct piix_host_priv *hpriv = ap->host->private_data; | 907 | struct piix_host_priv *hpriv = ap->host->private_data; |
916 | 908 | ||
917 | iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg], | 909 | iowrite32(((ap->port_no * 2 + link->pmp) << 8) | piix_sidx_map[reg], |
918 | hpriv->sidpr + PIIX_SIDPR_IDX); | 910 | hpriv->sidpr + PIIX_SIDPR_IDX); |
919 | } | 911 | } |
920 | 912 | ||
921 | static int piix_sidpr_read(struct ata_device *dev, unsigned int reg) | 913 | static int piix_sidpr_scr_read(struct ata_link *link, |
922 | { | 914 | unsigned int reg, u32 *val) |
923 | struct piix_host_priv *hpriv = dev->link->ap->host->private_data; | ||
924 | |||
925 | piix_sidpr_sel(dev, reg); | ||
926 | return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA); | ||
927 | } | ||
928 | |||
929 | static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val) | ||
930 | { | ||
931 | struct piix_host_priv *hpriv = dev->link->ap->host->private_data; | ||
932 | |||
933 | piix_sidpr_sel(dev, reg); | ||
934 | iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA); | ||
935 | } | ||
936 | |||
937 | static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl) | ||
938 | { | ||
939 | u32 val = 0; | ||
940 | int i, mi; | ||
941 | |||
942 | for (i = 0, mi = 0; i < 32 / 4; i++) { | ||
943 | u8 c0 = (val0 >> (i * 4)) & 0xf; | ||
944 | u8 c1 = (val1 >> (i * 4)) & 0xf; | ||
945 | u8 merged = c0; | ||
946 | const int *cur; | ||
947 | |||
948 | /* if no merge preference, assume the first value */ | ||
949 | cur = merge_tbl[mi]; | ||
950 | if (!cur) | ||
951 | goto done; | ||
952 | mi++; | ||
953 | |||
954 | /* if two values equal, use it */ | ||
955 | if (c0 == c1) | ||
956 | goto done; | ||
957 | |||
958 | /* choose the first match or the last from the merge table */ | ||
959 | while (*cur != -1) { | ||
960 | if (c0 == *cur || c1 == *cur) | ||
961 | break; | ||
962 | cur++; | ||
963 | } | ||
964 | if (*cur == -1) | ||
965 | cur--; | ||
966 | merged = *cur; | ||
967 | done: | ||
968 | val |= merged << (i * 4); | ||
969 | } | ||
970 | |||
971 | return val; | ||
972 | } | ||
973 | |||
974 | static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val) | ||
975 | { | 915 | { |
976 | const int * const sstatus_merge_tbl[] = { | 916 | struct piix_host_priv *hpriv = link->ap->host->private_data; |
977 | /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 }, | ||
978 | /* SPD */ (const int []){ 2, 1, 0, -1 }, | ||
979 | /* IPM */ (const int []){ 6, 2, 1, 0, -1 }, | ||
980 | NULL, | ||
981 | }; | ||
982 | const int * const scontrol_merge_tbl[] = { | ||
983 | /* DET */ (const int []){ 1, 0, 4, 0, -1 }, | ||
984 | /* SPD */ (const int []){ 0, 2, 1, 0, -1 }, | ||
985 | /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 }, | ||
986 | NULL, | ||
987 | }; | ||
988 | u32 v0, v1; | ||
989 | 917 | ||
990 | if (reg >= ARRAY_SIZE(piix_sidx_map)) | 918 | if (reg >= ARRAY_SIZE(piix_sidx_map)) |
991 | return -EINVAL; | 919 | return -EINVAL; |
992 | 920 | ||
993 | if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) { | 921 | piix_sidpr_sel(link, reg); |
994 | *val = piix_sidpr_read(&ap->link.device[0], reg); | 922 | *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA); |
995 | return 0; | ||
996 | } | ||
997 | |||
998 | v0 = piix_sidpr_read(&ap->link.device[0], reg); | ||
999 | v1 = piix_sidpr_read(&ap->link.device[1], reg); | ||
1000 | |||
1001 | switch (reg) { | ||
1002 | case SCR_STATUS: | ||
1003 | *val = piix_merge_scr(v0, v1, sstatus_merge_tbl); | ||
1004 | break; | ||
1005 | case SCR_ERROR: | ||
1006 | *val = v0 | v1; | ||
1007 | break; | ||
1008 | case SCR_CONTROL: | ||
1009 | *val = piix_merge_scr(v0, v1, scontrol_merge_tbl); | ||
1010 | break; | ||
1011 | } | ||
1012 | |||
1013 | return 0; | 923 | return 0; |
1014 | } | 924 | } |
1015 | 925 | ||
1016 | static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val) | 926 | static int piix_sidpr_scr_write(struct ata_link *link, |
927 | unsigned int reg, u32 val) | ||
1017 | { | 928 | { |
929 | struct piix_host_priv *hpriv = link->ap->host->private_data; | ||
930 | |||
1018 | if (reg >= ARRAY_SIZE(piix_sidx_map)) | 931 | if (reg >= ARRAY_SIZE(piix_sidx_map)) |
1019 | return -EINVAL; | 932 | return -EINVAL; |
1020 | 933 | ||
1021 | piix_sidpr_write(&ap->link.device[0], reg, val); | 934 | piix_sidpr_sel(link, reg); |
1022 | 935 | iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA); | |
1023 | if (ap->flags & ATA_FLAG_SLAVE_POSS) | ||
1024 | piix_sidpr_write(&ap->link.device[1], reg, val); | ||
1025 | |||
1026 | return 0; | 936 | return 0; |
1027 | } | 937 | } |
1028 | 938 | ||
@@ -1363,28 +1273,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev, | |||
1363 | return map; | 1273 | return map; |
1364 | } | 1274 | } |
1365 | 1275 | ||
1366 | static void __devinit piix_init_sidpr(struct ata_host *host) | 1276 | static int __devinit piix_init_sidpr(struct ata_host *host) |
1367 | { | 1277 | { |
1368 | struct pci_dev *pdev = to_pci_dev(host->dev); | 1278 | struct pci_dev *pdev = to_pci_dev(host->dev); |
1369 | struct piix_host_priv *hpriv = host->private_data; | 1279 | struct piix_host_priv *hpriv = host->private_data; |
1370 | struct ata_device *dev0 = &host->ports[0]->link.device[0]; | 1280 | struct ata_link *link0 = &host->ports[0]->link; |
1371 | u32 scontrol; | 1281 | u32 scontrol; |
1372 | int i; | 1282 | int i, rc; |
1373 | 1283 | ||
1374 | /* check for availability */ | 1284 | /* check for availability */ |
1375 | for (i = 0; i < 4; i++) | 1285 | for (i = 0; i < 4; i++) |
1376 | if (hpriv->map[i] == IDE) | 1286 | if (hpriv->map[i] == IDE) |
1377 | return; | 1287 | return 0; |
1378 | 1288 | ||
1379 | if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) | 1289 | if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) |
1380 | return; | 1290 | return 0; |
1381 | 1291 | ||
1382 | if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 || | 1292 | if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 || |
1383 | pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN) | 1293 | pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN) |
1384 | return; | 1294 | return 0; |
1385 | 1295 | ||
1386 | if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME)) | 1296 | if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME)) |
1387 | return; | 1297 | return 0; |
1388 | 1298 | ||
1389 | hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; | 1299 | hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; |
1390 | 1300 | ||
@@ -1392,7 +1302,7 @@ static void __devinit piix_init_sidpr(struct ata_host *host) | |||
1392 | * Give it a test drive by inhibiting power save modes which | 1302 | * Give it a test drive by inhibiting power save modes which |
1393 | * we'll do anyway. | 1303 | * we'll do anyway. |
1394 | */ | 1304 | */ |
1395 | scontrol = piix_sidpr_read(dev0, SCR_CONTROL); | 1305 | piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol); |
1396 | 1306 | ||
1397 | /* if IPM is already 3, SCR access is probably working. Don't | 1307 | /* if IPM is already 3, SCR access is probably working. Don't |
1398 | * un-inhibit power save modes as BIOS might have inhibited | 1308 | * un-inhibit power save modes as BIOS might have inhibited |
@@ -1400,18 +1310,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host) | |||
1400 | */ | 1310 | */ |
1401 | if ((scontrol & 0xf00) != 0x300) { | 1311 | if ((scontrol & 0xf00) != 0x300) { |
1402 | scontrol |= 0x300; | 1312 | scontrol |= 0x300; |
1403 | piix_sidpr_write(dev0, SCR_CONTROL, scontrol); | 1313 | piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol); |
1404 | scontrol = piix_sidpr_read(dev0, SCR_CONTROL); | 1314 | piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol); |
1405 | 1315 | ||
1406 | if ((scontrol & 0xf00) != 0x300) { | 1316 | if ((scontrol & 0xf00) != 0x300) { |
1407 | dev_printk(KERN_INFO, host->dev, "SCR access via " | 1317 | dev_printk(KERN_INFO, host->dev, "SCR access via " |
1408 | "SIDPR is available but doesn't work\n"); | 1318 | "SIDPR is available but doesn't work\n"); |
1409 | return; | 1319 | return 0; |
1410 | } | 1320 | } |
1411 | } | 1321 | } |
1412 | 1322 | ||
1413 | host->ports[0]->ops = &piix_sidpr_sata_ops; | 1323 | /* okay, SCRs available, set ops and ask libata for slave_link */ |
1414 | host->ports[1]->ops = &piix_sidpr_sata_ops; | 1324 | for (i = 0; i < 2; i++) { |
1325 | struct ata_port *ap = host->ports[i]; | ||
1326 | |||
1327 | ap->ops = &piix_sidpr_sata_ops; | ||
1328 | |||
1329 | if (ap->flags & ATA_FLAG_SLAVE_POSS) { | ||
1330 | rc = ata_slave_link_init(ap); | ||
1331 | if (rc) | ||
1332 | return rc; | ||
1333 | } | ||
1334 | } | ||
1335 | |||
1336 | return 0; | ||
1415 | } | 1337 | } |
1416 | 1338 | ||
1417 | static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) | 1339 | static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) |
@@ -1521,7 +1443,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1521 | /* initialize controller */ | 1443 | /* initialize controller */ |
1522 | if (port_flags & ATA_FLAG_SATA) { | 1444 | if (port_flags & ATA_FLAG_SATA) { |
1523 | piix_init_pcs(host, piix_map_db_table[ent->driver_data]); | 1445 | piix_init_pcs(host, piix_map_db_table[ent->driver_data]); |
1524 | piix_init_sidpr(host); | 1446 | rc = piix_init_sidpr(host); |
1447 | if (rc) | ||
1448 | return rc; | ||
1525 | } | 1449 | } |
1526 | 1450 | ||
1527 | /* apply IOCFG bit18 quirk */ | 1451 | /* apply IOCFG bit18 quirk */ |