diff options
Diffstat (limited to 'drivers/edac/edac_mc_sysfs.c')
-rw-r--r-- | drivers/edac/edac_mc_sysfs.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index e9a28f576d1..f6a29b0eedc 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -144,25 +144,31 @@ static ssize_t csrow_ce_count_show(struct csrow_info *csrow, char *data, | |||
144 | static ssize_t csrow_size_show(struct csrow_info *csrow, char *data, | 144 | static ssize_t csrow_size_show(struct csrow_info *csrow, char *data, |
145 | int private) | 145 | int private) |
146 | { | 146 | { |
147 | return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages)); | 147 | int i; |
148 | u32 nr_pages = 0; | ||
149 | |||
150 | for (i = 0; i < csrow->nr_channels; i++) | ||
151 | nr_pages += csrow->channels[i].dimm->nr_pages; | ||
152 | |||
153 | return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages)); | ||
148 | } | 154 | } |
149 | 155 | ||
150 | static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data, | 156 | static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data, |
151 | int private) | 157 | int private) |
152 | { | 158 | { |
153 | return sprintf(data, "%s\n", mem_types[csrow->mtype]); | 159 | return sprintf(data, "%s\n", mem_types[csrow->channels[0].dimm->mtype]); |
154 | } | 160 | } |
155 | 161 | ||
156 | static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data, | 162 | static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data, |
157 | int private) | 163 | int private) |
158 | { | 164 | { |
159 | return sprintf(data, "%s\n", dev_types[csrow->dtype]); | 165 | return sprintf(data, "%s\n", dev_types[csrow->channels[0].dimm->dtype]); |
160 | } | 166 | } |
161 | 167 | ||
162 | static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data, | 168 | static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data, |
163 | int private) | 169 | int private) |
164 | { | 170 | { |
165 | return sprintf(data, "%s\n", edac_caps[csrow->edac_mode]); | 171 | return sprintf(data, "%s\n", edac_caps[csrow->channels[0].dimm->edac_mode]); |
166 | } | 172 | } |
167 | 173 | ||
168 | /* show/store functions for DIMM Label attributes */ | 174 | /* show/store functions for DIMM Label attributes */ |
@@ -170,11 +176,11 @@ static ssize_t channel_dimm_label_show(struct csrow_info *csrow, | |||
170 | char *data, int channel) | 176 | char *data, int channel) |
171 | { | 177 | { |
172 | /* if field has not been initialized, there is nothing to send */ | 178 | /* if field has not been initialized, there is nothing to send */ |
173 | if (!csrow->channels[channel].label[0]) | 179 | if (!csrow->channels[channel].dimm->label[0]) |
174 | return 0; | 180 | return 0; |
175 | 181 | ||
176 | return snprintf(data, EDAC_MC_LABEL_LEN, "%s\n", | 182 | return snprintf(data, EDAC_MC_LABEL_LEN, "%s\n", |
177 | csrow->channels[channel].label); | 183 | csrow->channels[channel].dimm->label); |
178 | } | 184 | } |
179 | 185 | ||
180 | static ssize_t channel_dimm_label_store(struct csrow_info *csrow, | 186 | static ssize_t channel_dimm_label_store(struct csrow_info *csrow, |
@@ -184,8 +190,8 @@ static ssize_t channel_dimm_label_store(struct csrow_info *csrow, | |||
184 | ssize_t max_size = 0; | 190 | ssize_t max_size = 0; |
185 | 191 | ||
186 | max_size = min((ssize_t) count, (ssize_t) EDAC_MC_LABEL_LEN - 1); | 192 | max_size = min((ssize_t) count, (ssize_t) EDAC_MC_LABEL_LEN - 1); |
187 | strncpy(csrow->channels[channel].label, data, max_size); | 193 | strncpy(csrow->channels[channel].dimm->label, data, max_size); |
188 | csrow->channels[channel].label[max_size] = '\0'; | 194 | csrow->channels[channel].dimm->label[max_size] = '\0'; |
189 | 195 | ||
190 | return max_size; | 196 | return max_size; |
191 | } | 197 | } |
@@ -419,8 +425,8 @@ static ssize_t mci_reset_counters_store(struct mem_ctl_info *mci, | |||
419 | 425 | ||
420 | mci->ue_noinfo_count = 0; | 426 | mci->ue_noinfo_count = 0; |
421 | mci->ce_noinfo_count = 0; | 427 | mci->ce_noinfo_count = 0; |
422 | mci->ue_count = 0; | 428 | mci->ue_mc = 0; |
423 | mci->ce_count = 0; | 429 | mci->ce_mc = 0; |
424 | 430 | ||
425 | for (row = 0; row < mci->nr_csrows; row++) { | 431 | for (row = 0; row < mci->nr_csrows; row++) { |
426 | struct csrow_info *ri = &mci->csrows[row]; | 432 | struct csrow_info *ri = &mci->csrows[row]; |
@@ -489,12 +495,12 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data) | |||
489 | /* default attribute files for the MCI object */ | 495 | /* default attribute files for the MCI object */ |
490 | static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data) | 496 | static ssize_t mci_ue_count_show(struct mem_ctl_info *mci, char *data) |
491 | { | 497 | { |
492 | return sprintf(data, "%d\n", mci->ue_count); | 498 | return sprintf(data, "%d\n", mci->ue_mc); |
493 | } | 499 | } |
494 | 500 | ||
495 | static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data) | 501 | static ssize_t mci_ce_count_show(struct mem_ctl_info *mci, char *data) |
496 | { | 502 | { |
497 | return sprintf(data, "%d\n", mci->ce_count); | 503 | return sprintf(data, "%d\n", mci->ce_mc); |
498 | } | 504 | } |
499 | 505 | ||
500 | static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data) | 506 | static ssize_t mci_ce_noinfo_show(struct mem_ctl_info *mci, char *data) |
@@ -519,16 +525,16 @@ static ssize_t mci_ctl_name_show(struct mem_ctl_info *mci, char *data) | |||
519 | 525 | ||
520 | static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) | 526 | static ssize_t mci_size_mb_show(struct mem_ctl_info *mci, char *data) |
521 | { | 527 | { |
522 | int total_pages, csrow_idx; | 528 | int total_pages = 0, csrow_idx, j; |
523 | 529 | ||
524 | for (total_pages = csrow_idx = 0; csrow_idx < mci->nr_csrows; | 530 | for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) { |
525 | csrow_idx++) { | ||
526 | struct csrow_info *csrow = &mci->csrows[csrow_idx]; | 531 | struct csrow_info *csrow = &mci->csrows[csrow_idx]; |
527 | 532 | ||
528 | if (!csrow->nr_pages) | 533 | for (j = 0; j < csrow->nr_channels; j++) { |
529 | continue; | 534 | struct dimm_info *dimm = csrow->channels[j].dimm; |
530 | 535 | ||
531 | total_pages += csrow->nr_pages; | 536 | total_pages += dimm->nr_pages; |
537 | } | ||
532 | } | 538 | } |
533 | 539 | ||
534 | return sprintf(data, "%u\n", PAGES_TO_MiB(total_pages)); | 540 | return sprintf(data, "%u\n", PAGES_TO_MiB(total_pages)); |
@@ -900,7 +906,7 @@ static void edac_remove_mci_instance_attributes(struct mem_ctl_info *mci, | |||
900 | */ | 906 | */ |
901 | int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | 907 | int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) |
902 | { | 908 | { |
903 | int i; | 909 | int i, j; |
904 | int err; | 910 | int err; |
905 | struct csrow_info *csrow; | 911 | struct csrow_info *csrow; |
906 | struct kobject *kobj_mci = &mci->edac_mci_kobj; | 912 | struct kobject *kobj_mci = &mci->edac_mci_kobj; |
@@ -934,10 +940,13 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
934 | /* Make directories for each CSROW object under the mc<id> kobject | 940 | /* Make directories for each CSROW object under the mc<id> kobject |
935 | */ | 941 | */ |
936 | for (i = 0; i < mci->nr_csrows; i++) { | 942 | for (i = 0; i < mci->nr_csrows; i++) { |
943 | int nr_pages = 0; | ||
944 | |||
937 | csrow = &mci->csrows[i]; | 945 | csrow = &mci->csrows[i]; |
946 | for (j = 0; j < csrow->nr_channels; j++) | ||
947 | nr_pages += csrow->channels[j].dimm->nr_pages; | ||
938 | 948 | ||
939 | /* Only expose populated CSROWs */ | 949 | if (nr_pages > 0) { |
940 | if (csrow->nr_pages > 0) { | ||
941 | err = edac_create_csrow_object(mci, csrow, i); | 950 | err = edac_create_csrow_object(mci, csrow, i); |
942 | if (err) { | 951 | if (err) { |
943 | debugf1("%s() failure: create csrow %d obj\n", | 952 | debugf1("%s() failure: create csrow %d obj\n", |
@@ -949,12 +958,15 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) | |||
949 | 958 | ||
950 | return 0; | 959 | return 0; |
951 | 960 | ||
952 | /* CSROW error: backout what has already been registered, */ | ||
953 | fail1: | 961 | fail1: |
954 | for (i--; i >= 0; i--) { | 962 | for (i--; i >= 0; i--) { |
955 | if (csrow->nr_pages > 0) { | 963 | int nr_pages = 0; |
964 | |||
965 | csrow = &mci->csrows[i]; | ||
966 | for (j = 0; j < csrow->nr_channels; j++) | ||
967 | nr_pages += csrow->channels[j].dimm->nr_pages; | ||
968 | if (nr_pages > 0) | ||
956 | kobject_put(&mci->csrows[i].kobj); | 969 | kobject_put(&mci->csrows[i].kobj); |
957 | } | ||
958 | } | 970 | } |
959 | 971 | ||
960 | /* remove the mci instance's attributes, if any */ | 972 | /* remove the mci instance's attributes, if any */ |
@@ -973,14 +985,20 @@ fail0: | |||
973 | */ | 985 | */ |
974 | void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | 986 | void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) |
975 | { | 987 | { |
976 | int i; | 988 | struct csrow_info *csrow; |
989 | int i, j; | ||
977 | 990 | ||
978 | debugf0("%s()\n", __func__); | 991 | debugf0("%s()\n", __func__); |
979 | 992 | ||
980 | /* remove all csrow kobjects */ | 993 | /* remove all csrow kobjects */ |
981 | debugf4("%s() unregister this mci kobj\n", __func__); | 994 | debugf4("%s() unregister this mci kobj\n", __func__); |
982 | for (i = 0; i < mci->nr_csrows; i++) { | 995 | for (i = 0; i < mci->nr_csrows; i++) { |
983 | if (mci->csrows[i].nr_pages > 0) { | 996 | int nr_pages = 0; |
997 | |||
998 | csrow = &mci->csrows[i]; | ||
999 | for (j = 0; j < csrow->nr_channels; j++) | ||
1000 | nr_pages += csrow->channels[j].dimm->nr_pages; | ||
1001 | if (nr_pages > 0) { | ||
984 | debugf0("%s() unreg csrow-%d\n", __func__, i); | 1002 | debugf0("%s() unreg csrow-%d\n", __func__, i); |
985 | kobject_put(&mci->csrows[i].kobj); | 1003 | kobject_put(&mci->csrows[i].kobj); |
986 | } | 1004 | } |