diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-04-16 14:03:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-28 18:10:59 -0400 |
commit | ab5a503cb57c1acea3b67210f46ebc2cfb28945e (patch) | |
tree | 412a4a84e92405561af8b0cd85e1539226e08b68 /drivers/edac | |
parent | 4275be63559719c3149b19751029f1b0f1b26775 (diff) |
amd64_edac: convert driver to use the new edac ABI
The legacy edac ABI is going to be removed. Port the driver to use
and benefit from the new API functionality.
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Borislav Petkov <borislav.petkov@amd.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd64_edac.c | 137 |
1 files changed, 92 insertions, 45 deletions
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 1ceb8e276376..c431544519b1 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -1039,6 +1039,37 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | |||
1039 | int channel, csrow; | 1039 | int channel, csrow; |
1040 | u32 page, offset; | 1040 | u32 page, offset; |
1041 | 1041 | ||
1042 | error_address_to_page_and_offset(sys_addr, &page, &offset); | ||
1043 | |||
1044 | /* | ||
1045 | * Find out which node the error address belongs to. This may be | ||
1046 | * different from the node that detected the error. | ||
1047 | */ | ||
1048 | src_mci = find_mc_by_sys_addr(mci, sys_addr); | ||
1049 | if (!src_mci) { | ||
1050 | amd64_mc_err(mci, "failed to map error addr 0x%lx to a node\n", | ||
1051 | (unsigned long)sys_addr); | ||
1052 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, | ||
1053 | page, offset, syndrome, | ||
1054 | -1, -1, -1, | ||
1055 | EDAC_MOD_STR, | ||
1056 | "failed to map error addr to a node", | ||
1057 | NULL); | ||
1058 | return; | ||
1059 | } | ||
1060 | |||
1061 | /* Now map the sys_addr to a CSROW */ | ||
1062 | csrow = sys_addr_to_csrow(src_mci, sys_addr); | ||
1063 | if (csrow < 0) { | ||
1064 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, | ||
1065 | page, offset, syndrome, | ||
1066 | -1, -1, -1, | ||
1067 | EDAC_MOD_STR, | ||
1068 | "failed to map error addr to a csrow", | ||
1069 | NULL); | ||
1070 | return; | ||
1071 | } | ||
1072 | |||
1042 | /* CHIPKILL enabled */ | 1073 | /* CHIPKILL enabled */ |
1043 | if (pvt->nbcfg & NBCFG_CHIPKILL) { | 1074 | if (pvt->nbcfg & NBCFG_CHIPKILL) { |
1044 | channel = get_channel_from_ecc_syndrome(mci, syndrome); | 1075 | channel = get_channel_from_ecc_syndrome(mci, syndrome); |
@@ -1048,9 +1079,15 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | |||
1048 | * 2 DIMMs is in error. So we need to ID 'both' of them | 1079 | * 2 DIMMs is in error. So we need to ID 'both' of them |
1049 | * as suspect. | 1080 | * as suspect. |
1050 | */ | 1081 | */ |
1051 | amd64_mc_warn(mci, "unknown syndrome 0x%04x - possible " | 1082 | amd64_mc_warn(src_mci, "unknown syndrome 0x%04x - " |
1052 | "error reporting race\n", syndrome); | 1083 | "possible error reporting race\n", |
1053 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR); | 1084 | syndrome); |
1085 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, | ||
1086 | page, offset, syndrome, | ||
1087 | csrow, -1, -1, | ||
1088 | EDAC_MOD_STR, | ||
1089 | "unknown syndrome - possible error reporting race", | ||
1090 | NULL); | ||
1054 | return; | 1091 | return; |
1055 | } | 1092 | } |
1056 | } else { | 1093 | } else { |
@@ -1065,28 +1102,10 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | |||
1065 | channel = ((sys_addr & BIT(3)) != 0); | 1102 | channel = ((sys_addr & BIT(3)) != 0); |
1066 | } | 1103 | } |
1067 | 1104 | ||
1068 | /* | 1105 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, src_mci, |
1069 | * Find out which node the error address belongs to. This may be | 1106 | page, offset, syndrome, |
1070 | * different from the node that detected the error. | 1107 | csrow, channel, -1, |
1071 | */ | 1108 | EDAC_MOD_STR, "", NULL); |
1072 | src_mci = find_mc_by_sys_addr(mci, sys_addr); | ||
1073 | if (!src_mci) { | ||
1074 | amd64_mc_err(mci, "failed to map error addr 0x%lx to a node\n", | ||
1075 | (unsigned long)sys_addr); | ||
1076 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR); | ||
1077 | return; | ||
1078 | } | ||
1079 | |||
1080 | /* Now map the sys_addr to a CSROW */ | ||
1081 | csrow = sys_addr_to_csrow(src_mci, sys_addr); | ||
1082 | if (csrow < 0) { | ||
1083 | edac_mc_handle_ce_no_info(src_mci, EDAC_MOD_STR); | ||
1084 | } else { | ||
1085 | error_address_to_page_and_offset(sys_addr, &page, &offset); | ||
1086 | |||
1087 | edac_mc_handle_ce(src_mci, page, offset, syndrome, csrow, | ||
1088 | channel, EDAC_MOD_STR); | ||
1089 | } | ||
1090 | } | 1109 | } |
1091 | 1110 | ||
1092 | static int ddr2_cs_size(unsigned i, bool dct_width) | 1111 | static int ddr2_cs_size(unsigned i, bool dct_width) |
@@ -1592,15 +1611,20 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | |||
1592 | u32 page, offset; | 1611 | u32 page, offset; |
1593 | int nid, csrow, chan = 0; | 1612 | int nid, csrow, chan = 0; |
1594 | 1613 | ||
1614 | error_address_to_page_and_offset(sys_addr, &page, &offset); | ||
1615 | |||
1595 | csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan); | 1616 | csrow = f1x_translate_sysaddr_to_cs(pvt, sys_addr, &nid, &chan); |
1596 | 1617 | ||
1597 | if (csrow < 0) { | 1618 | if (csrow < 0) { |
1598 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR); | 1619 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, |
1620 | page, offset, syndrome, | ||
1621 | -1, -1, -1, | ||
1622 | EDAC_MOD_STR, | ||
1623 | "failed to map error addr to a csrow", | ||
1624 | NULL); | ||
1599 | return; | 1625 | return; |
1600 | } | 1626 | } |
1601 | 1627 | ||
1602 | error_address_to_page_and_offset(sys_addr, &page, &offset); | ||
1603 | |||
1604 | /* | 1628 | /* |
1605 | * We need the syndromes for channel detection only when we're | 1629 | * We need the syndromes for channel detection only when we're |
1606 | * ganged. Otherwise @chan should already contain the channel at | 1630 | * ganged. Otherwise @chan should already contain the channel at |
@@ -1609,16 +1633,10 @@ static void f1x_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | |||
1609 | if (dct_ganging_enabled(pvt)) | 1633 | if (dct_ganging_enabled(pvt)) |
1610 | chan = get_channel_from_ecc_syndrome(mci, syndrome); | 1634 | chan = get_channel_from_ecc_syndrome(mci, syndrome); |
1611 | 1635 | ||
1612 | if (chan >= 0) | 1636 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, |
1613 | edac_mc_handle_ce(mci, page, offset, syndrome, csrow, chan, | 1637 | page, offset, syndrome, |
1614 | EDAC_MOD_STR); | 1638 | csrow, chan, -1, |
1615 | else | 1639 | EDAC_MOD_STR, "", NULL); |
1616 | /* | ||
1617 | * Channel unknown, report all channels on this CSROW as failed. | ||
1618 | */ | ||
1619 | for (chan = 0; chan < mci->csrows[csrow].nr_channels; chan++) | ||
1620 | edac_mc_handle_ce(mci, page, offset, syndrome, | ||
1621 | csrow, chan, EDAC_MOD_STR); | ||
1622 | } | 1640 | } |
1623 | 1641 | ||
1624 | /* | 1642 | /* |
@@ -1899,7 +1917,12 @@ static void amd64_handle_ce(struct mem_ctl_info *mci, struct mce *m) | |||
1899 | /* Ensure that the Error Address is VALID */ | 1917 | /* Ensure that the Error Address is VALID */ |
1900 | if (!(m->status & MCI_STATUS_ADDRV)) { | 1918 | if (!(m->status & MCI_STATUS_ADDRV)) { |
1901 | amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); | 1919 | amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); |
1902 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR); | 1920 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, |
1921 | 0, 0, 0, | ||
1922 | -1, -1, -1, | ||
1923 | EDAC_MOD_STR, | ||
1924 | "HW has no ERROR_ADDRESS available", | ||
1925 | NULL); | ||
1903 | return; | 1926 | return; |
1904 | } | 1927 | } |
1905 | 1928 | ||
@@ -1923,11 +1946,17 @@ static void amd64_handle_ue(struct mem_ctl_info *mci, struct mce *m) | |||
1923 | 1946 | ||
1924 | if (!(m->status & MCI_STATUS_ADDRV)) { | 1947 | if (!(m->status & MCI_STATUS_ADDRV)) { |
1925 | amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); | 1948 | amd64_mc_err(mci, "HW has no ERROR_ADDRESS available\n"); |
1926 | edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR); | 1949 | edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, |
1950 | 0, 0, 0, | ||
1951 | -1, -1, -1, | ||
1952 | EDAC_MOD_STR, | ||
1953 | "HW has no ERROR_ADDRESS available", | ||
1954 | NULL); | ||
1927 | return; | 1955 | return; |
1928 | } | 1956 | } |
1929 | 1957 | ||
1930 | sys_addr = get_error_address(m); | 1958 | sys_addr = get_error_address(m); |
1959 | error_address_to_page_and_offset(sys_addr, &page, &offset); | ||
1931 | 1960 | ||
1932 | /* | 1961 | /* |
1933 | * Find out which node the error address belongs to. This may be | 1962 | * Find out which node the error address belongs to. This may be |
@@ -1937,7 +1966,11 @@ static void amd64_handle_ue(struct mem_ctl_info *mci, struct mce *m) | |||
1937 | if (!src_mci) { | 1966 | if (!src_mci) { |
1938 | amd64_mc_err(mci, "ERROR ADDRESS (0x%lx) NOT mapped to a MC\n", | 1967 | amd64_mc_err(mci, "ERROR ADDRESS (0x%lx) NOT mapped to a MC\n", |
1939 | (unsigned long)sys_addr); | 1968 | (unsigned long)sys_addr); |
1940 | edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR); | 1969 | edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, |
1970 | page, offset, 0, | ||
1971 | -1, -1, -1, | ||
1972 | EDAC_MOD_STR, | ||
1973 | "ERROR ADDRESS NOT mapped to a MC", NULL); | ||
1941 | return; | 1974 | return; |
1942 | } | 1975 | } |
1943 | 1976 | ||
@@ -1947,10 +1980,17 @@ static void amd64_handle_ue(struct mem_ctl_info *mci, struct mce *m) | |||
1947 | if (csrow < 0) { | 1980 | if (csrow < 0) { |
1948 | amd64_mc_err(mci, "ERROR_ADDRESS (0x%lx) NOT mapped to CS\n", | 1981 | amd64_mc_err(mci, "ERROR_ADDRESS (0x%lx) NOT mapped to CS\n", |
1949 | (unsigned long)sys_addr); | 1982 | (unsigned long)sys_addr); |
1950 | edac_mc_handle_ue_no_info(log_mci, EDAC_MOD_STR); | 1983 | edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, |
1984 | page, offset, 0, | ||
1985 | -1, -1, -1, | ||
1986 | EDAC_MOD_STR, | ||
1987 | "ERROR ADDRESS NOT mapped to CS", | ||
1988 | NULL); | ||
1951 | } else { | 1989 | } else { |
1952 | error_address_to_page_and_offset(sys_addr, &page, &offset); | 1990 | edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, |
1953 | edac_mc_handle_ue(log_mci, page, offset, csrow, EDAC_MOD_STR); | 1991 | page, offset, 0, |
1992 | csrow, -1, -1, | ||
1993 | EDAC_MOD_STR, "", NULL); | ||
1954 | } | 1994 | } |
1955 | } | 1995 | } |
1956 | 1996 | ||
@@ -2515,6 +2555,7 @@ static int amd64_init_one_instance(struct pci_dev *F2) | |||
2515 | struct amd64_pvt *pvt = NULL; | 2555 | struct amd64_pvt *pvt = NULL; |
2516 | struct amd64_family_type *fam_type = NULL; | 2556 | struct amd64_family_type *fam_type = NULL; |
2517 | struct mem_ctl_info *mci = NULL; | 2557 | struct mem_ctl_info *mci = NULL; |
2558 | struct edac_mc_layer layers[2]; | ||
2518 | int err = 0, ret; | 2559 | int err = 0, ret; |
2519 | u8 nid = get_node_id(F2); | 2560 | u8 nid = get_node_id(F2); |
2520 | 2561 | ||
@@ -2549,7 +2590,13 @@ static int amd64_init_one_instance(struct pci_dev *F2) | |||
2549 | goto err_siblings; | 2590 | goto err_siblings; |
2550 | 2591 | ||
2551 | ret = -ENOMEM; | 2592 | ret = -ENOMEM; |
2552 | mci = edac_mc_alloc(0, pvt->csels[0].b_cnt, pvt->channel_count, nid); | 2593 | layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; |
2594 | layers[0].size = pvt->csels[0].b_cnt; | ||
2595 | layers[0].is_virt_csrow = true; | ||
2596 | layers[1].type = EDAC_MC_LAYER_CHANNEL; | ||
2597 | layers[1].size = pvt->channel_count; | ||
2598 | layers[1].is_virt_csrow = false; | ||
2599 | mci = new_edac_mc_alloc(nid, ARRAY_SIZE(layers), layers, 0); | ||
2553 | if (!mci) | 2600 | if (!mci) |
2554 | goto err_siblings; | 2601 | goto err_siblings; |
2555 | 2602 | ||