aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ata_piix.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2008-07-31 04:02:44 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-29 00:25:32 -0400
commitbe77e43abb433c2d6f2fc69352289e34dcbf040a (patch)
treef8bf257c2f0fdbfeec0e5d6fd6fc48a741117616 /drivers/ata/ata_piix.c
parentb1c72916abbdd0a55015c87358536ca0ebaf6735 (diff)
ata_piix: drop merged SCR access and use slave_link instead
Now that libata has slave_link, there's no need to keep ugly merged SCR access. Drop it and use slave_link instead. This results in simpler code and much better separate link handling for master and slave. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/ata_piix.c')
-rw-r--r--drivers/ata/ata_piix.c167
1 files changed, 40 insertions, 127 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 81387ff48937..9d8cb804ee2b 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -887,23 +887,9 @@ static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev)
887 * Serial ATA Index/Data Pair Superset Registers access 887 * Serial ATA Index/Data Pair Superset Registers access
888 * 888 *
889 * Beginning from ICH8, there's a sane way to access SCRs using index 889 * Beginning from ICH8, there's a sane way to access SCRs using index
890 * and data register pair located at BAR5. This creates an 890 * and data register pair located at BAR5 which means that we have
891 * interesting problem of mapping two SCRs to one port. 891 * separate SCRs for master and slave. This is handled using libata
892 * 892 * slave_link facility.
893 * Although they have separate SCRs, the master and slave aren't
894 * independent enough to be treated as separate links - e.g. softreset
895 * resets both. Also, there's no protocol defined for hard resetting
896 * singled device sharing the virtual port (no defined way to acquire
897 * device signature). This is worked around by merging the SCR values
898 * into one sensible value and requesting follow-up SRST after
899 * hardreset.
900 *
901 * SCR merging is perfomed in nibbles which is the unit contents in
902 * SCRs are organized. If two values are equal, the value is used.
903 * When they differ, merge table which lists precedence of possible
904 * values is consulted and the first match or the last entry when
905 * nothing matches is used. When there's no merge table for the
906 * specific nibble, value from the first port is used.
907 */ 893 */
908static const int piix_sidx_map[] = { 894static const int piix_sidx_map[] = {
909 [SCR_STATUS] = 0, 895 [SCR_STATUS] = 0,
@@ -911,125 +897,38 @@ static const int piix_sidx_map[] = {
911 [SCR_CONTROL] = 1, 897 [SCR_CONTROL] = 1,
912}; 898};
913 899
914static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg) 900static void piix_sidpr_sel(struct ata_link *link, unsigned int reg)
915{ 901{
916 struct ata_port *ap = dev->link->ap; 902 struct ata_port *ap = link->ap;
917 struct piix_host_priv *hpriv = ap->host->private_data; 903 struct piix_host_priv *hpriv = ap->host->private_data;
918 904
919 iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg], 905 iowrite32(((ap->port_no * 2 + link->pmp) << 8) | piix_sidx_map[reg],
920 hpriv->sidpr + PIIX_SIDPR_IDX); 906 hpriv->sidpr + PIIX_SIDPR_IDX);
921} 907}
922 908
923static int piix_sidpr_read(struct ata_device *dev, unsigned int reg)
924{
925 struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
926
927 piix_sidpr_sel(dev, reg);
928 return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
929}
930
931static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
932{
933 struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
934
935 piix_sidpr_sel(dev, reg);
936 iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
937}
938
939static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
940{
941 u32 val = 0;
942 int i, mi;
943
944 for (i = 0, mi = 0; i < 32 / 4; i++) {
945 u8 c0 = (val0 >> (i * 4)) & 0xf;
946 u8 c1 = (val1 >> (i * 4)) & 0xf;
947 u8 merged = c0;
948 const int *cur;
949
950 /* if no merge preference, assume the first value */
951 cur = merge_tbl[mi];
952 if (!cur)
953 goto done;
954 mi++;
955
956 /* if two values equal, use it */
957 if (c0 == c1)
958 goto done;
959
960 /* choose the first match or the last from the merge table */
961 while (*cur != -1) {
962 if (c0 == *cur || c1 == *cur)
963 break;
964 cur++;
965 }
966 if (*cur == -1)
967 cur--;
968 merged = *cur;
969 done:
970 val |= merged << (i * 4);
971 }
972
973 return val;
974}
975
976static int piix_sidpr_scr_read(struct ata_link *link, 909static int piix_sidpr_scr_read(struct ata_link *link,
977 unsigned int reg, u32 *val) 910 unsigned int reg, u32 *val)
978{ 911{
979 struct ata_port *ap = link->ap; 912 struct piix_host_priv *hpriv = link->ap->host->private_data;
980 const int * const sstatus_merge_tbl[] = {
981 /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
982 /* SPD */ (const int []){ 2, 1, 0, -1 },
983 /* IPM */ (const int []){ 6, 2, 1, 0, -1 },
984 NULL,
985 };
986 const int * const scontrol_merge_tbl[] = {
987 /* DET */ (const int []){ 1, 0, 4, 0, -1 },
988 /* SPD */ (const int []){ 0, 2, 1, 0, -1 },
989 /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 },
990 NULL,
991 };
992 u32 v0, v1;
993 913
994 if (reg >= ARRAY_SIZE(piix_sidx_map)) 914 if (reg >= ARRAY_SIZE(piix_sidx_map))
995 return -EINVAL; 915 return -EINVAL;
996 916
997 if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) { 917 piix_sidpr_sel(link, reg);
998 *val = piix_sidpr_read(&ap->link.device[0], reg); 918 *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
999 return 0;
1000 }
1001
1002 v0 = piix_sidpr_read(&ap->link.device[0], reg);
1003 v1 = piix_sidpr_read(&ap->link.device[1], reg);
1004
1005 switch (reg) {
1006 case SCR_STATUS:
1007 *val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
1008 break;
1009 case SCR_ERROR:
1010 *val = v0 | v1;
1011 break;
1012 case SCR_CONTROL:
1013 *val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
1014 break;
1015 }
1016
1017 return 0; 919 return 0;
1018} 920}
1019 921
1020static int piix_sidpr_scr_write(struct ata_link *link, 922static int piix_sidpr_scr_write(struct ata_link *link,
1021 unsigned int reg, u32 val) 923 unsigned int reg, u32 val)
1022{ 924{
1023 struct ata_port *ap = link->ap; 925 struct piix_host_priv *hpriv = link->ap->host->private_data;
1024 926
1025 if (reg >= ARRAY_SIZE(piix_sidx_map)) 927 if (reg >= ARRAY_SIZE(piix_sidx_map))
1026 return -EINVAL; 928 return -EINVAL;
1027 929
1028 piix_sidpr_write(&ap->link.device[0], reg, val); 930 piix_sidpr_sel(link, reg);
1029 931 iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
1030 if (ap->flags & ATA_FLAG_SLAVE_POSS)
1031 piix_sidpr_write(&ap->link.device[1], reg, val);
1032
1033 return 0; 932 return 0;
1034} 933}
1035 934
@@ -1370,28 +1269,28 @@ static const int *__devinit piix_init_sata_map(struct pci_dev *pdev,
1370 return map; 1269 return map;
1371} 1270}
1372 1271
1373static void __devinit piix_init_sidpr(struct ata_host *host) 1272static int __devinit piix_init_sidpr(struct ata_host *host)
1374{ 1273{
1375 struct pci_dev *pdev = to_pci_dev(host->dev); 1274 struct pci_dev *pdev = to_pci_dev(host->dev);
1376 struct piix_host_priv *hpriv = host->private_data; 1275 struct piix_host_priv *hpriv = host->private_data;
1377 struct ata_device *dev0 = &host->ports[0]->link.device[0]; 1276 struct ata_link *link0 = &host->ports[0]->link;
1378 u32 scontrol; 1277 u32 scontrol;
1379 int i; 1278 int i, rc;
1380 1279
1381 /* check for availability */ 1280 /* check for availability */
1382 for (i = 0; i < 4; i++) 1281 for (i = 0; i < 4; i++)
1383 if (hpriv->map[i] == IDE) 1282 if (hpriv->map[i] == IDE)
1384 return; 1283 return 0;
1385 1284
1386 if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR)) 1285 if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
1387 return; 1286 return 0;
1388 1287
1389 if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 || 1288 if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
1390 pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN) 1289 pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
1391 return; 1290 return 0;
1392 1291
1393 if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME)) 1292 if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
1394 return; 1293 return 0;
1395 1294
1396 hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR]; 1295 hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
1397 1296
@@ -1399,7 +1298,7 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
1399 * Give it a test drive by inhibiting power save modes which 1298 * Give it a test drive by inhibiting power save modes which
1400 * we'll do anyway. 1299 * we'll do anyway.
1401 */ 1300 */
1402 scontrol = piix_sidpr_read(dev0, SCR_CONTROL); 1301 piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
1403 1302
1404 /* if IPM is already 3, SCR access is probably working. Don't 1303 /* if IPM is already 3, SCR access is probably working. Don't
1405 * un-inhibit power save modes as BIOS might have inhibited 1304 * un-inhibit power save modes as BIOS might have inhibited
@@ -1407,18 +1306,30 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
1407 */ 1306 */
1408 if ((scontrol & 0xf00) != 0x300) { 1307 if ((scontrol & 0xf00) != 0x300) {
1409 scontrol |= 0x300; 1308 scontrol |= 0x300;
1410 piix_sidpr_write(dev0, SCR_CONTROL, scontrol); 1309 piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol);
1411 scontrol = piix_sidpr_read(dev0, SCR_CONTROL); 1310 piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
1412 1311
1413 if ((scontrol & 0xf00) != 0x300) { 1312 if ((scontrol & 0xf00) != 0x300) {
1414 dev_printk(KERN_INFO, host->dev, "SCR access via " 1313 dev_printk(KERN_INFO, host->dev, "SCR access via "
1415 "SIDPR is available but doesn't work\n"); 1314 "SIDPR is available but doesn't work\n");
1416 return; 1315 return 0;
1417 } 1316 }
1418 } 1317 }
1419 1318
1420 host->ports[0]->ops = &piix_sidpr_sata_ops; 1319 /* okay, SCRs available, set ops and ask libata for slave_link */
1421 host->ports[1]->ops = &piix_sidpr_sata_ops; 1320 for (i = 0; i < 2; i++) {
1321 struct ata_port *ap = host->ports[i];
1322
1323 ap->ops = &piix_sidpr_sata_ops;
1324
1325 if (ap->flags & ATA_FLAG_SLAVE_POSS) {
1326 rc = ata_slave_link_init(ap);
1327 if (rc)
1328 return rc;
1329 }
1330 }
1331
1332 return 0;
1422} 1333}
1423 1334
1424static void piix_iocfg_bit18_quirk(struct pci_dev *pdev) 1335static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
@@ -1528,7 +1439,9 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
1528 /* initialize controller */ 1439 /* initialize controller */
1529 if (port_flags & ATA_FLAG_SATA) { 1440 if (port_flags & ATA_FLAG_SATA) {
1530 piix_init_pcs(host, piix_map_db_table[ent->driver_data]); 1441 piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
1531 piix_init_sidpr(host); 1442 rc = piix_init_sidpr(host);
1443 if (rc)
1444 return rc;
1532 } 1445 }
1533 1446
1534 /* apply IOCFG bit18 quirk */ 1447 /* apply IOCFG bit18 quirk */