Introduce an mci_for_each_dimm() iterator. It returns a pointer to a struct dimm_info. This makes the declaration and use of an index obsolete and avoids access to internal data of struct mci (direct array access etc). [ bp: push the struct dimm_info *dimm; declaration into the CONFIG_EDAC_DEBUG block. ]
Unified · Split
| @@ -145,15 +145,18 @@ static void edac_mc_dump_channel(struct rank_info *chan) · 144 unmodified lines | |||
| 145 | edac_dbg(4, " channel->dimm = %p\n", chan->dimm); | 145 | edac_dbg(4, " channel->dimm = %p\n", chan->dimm); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static void edac_mc_dump_dimm(struct dimm_info *dimm, int number) | 148 | static void edac_mc_dump_dimm(struct dimm_info *dimm) |
| 149 | { | 149 | { |
| 150 | char location[80]; | 150 | char location[80]; |
| 151 | 151 | ||
| 152 | if (!dimm->nr_pages) | ||
| 153 | return; | ||
| 154 | |||
| 152 | edac_dimm_info_location(dimm, location, sizeof(location)); | 155 | edac_dimm_info_location(dimm, location, sizeof(location)); |
| 153 | 156 | ||
| 154 | edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n", | 157 | edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n", |
| 155 | dimm->mci->csbased ? "rank" : "dimm", | 158 | dimm->mci->csbased ? "rank" : "dimm", |
| 156 | number, location, dimm->csrow, dimm->cschannel); | 159 | dimm->idx, location, dimm->csrow, dimm->cschannel); |
| 157 | edac_dbg(4, " dimm = %p\n", dimm); | 160 | edac_dbg(4, " dimm = %p\n", dimm); |
| 158 | edac_dbg(4, " dimm->label = '%s'\n", dimm->label); | 161 | edac_dbg(4, " dimm->label = '%s'\n", dimm->label); |
| 159 | edac_dbg(4, " dimm->nr_pages = 0x%x\n", dimm->nr_pages); | 162 | edac_dbg(4, " dimm->nr_pages = 0x%x\n", dimm->nr_pages); |
| @@ -712,6 +715,7 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci, · 552 unmodified lines | |||
| 712 | edac_mc_dump_mci(mci); | 715 | edac_mc_dump_mci(mci); |
| 713 | 716 | ||
| 714 | if (edac_debug_level >= 4) { | 717 | if (edac_debug_level >= 4) { |
| 718 | struct dimm_info *dimm; | ||
| 715 | int i; | 719 | int i; |
| 716 | 720 | ||
| 717 | for (i = 0; i < mci->nr_csrows; i++) { | 721 | for (i = 0; i < mci->nr_csrows; i++) { |
| @@ -728,9 +732,9 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci, · 10 unmodified lines | |||
| 728 | if (csrow->channels[j]->dimm->nr_pages) | 732 | if (csrow->channels[j]->dimm->nr_pages) |
| 729 | edac_mc_dump_channel(csrow->channels[j]); | 733 | edac_mc_dump_channel(csrow->channels[j]); |
| 730 | } | 734 | } |
| 731 | for (i = 0; i < mci->tot_dimms; i++) | 735 | |
| 732 | if (mci->dimms[i]->nr_pages) | 736 | mci_for_each_dimm(mci, dimm) |
| 733 | edac_mc_dump_dimm(mci->dimms[i], i); | 737 | edac_mc_dump_dimm(dimm); |
| 734 | } | 738 | } |
| 735 | #endif | 739 | #endif |
| 736 | mutex_lock(&mem_ctls_mutex); | 740 | mutex_lock(&mem_ctls_mutex); |
| @@ -1088,6 +1092,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, · 351 unmodified lines | |||
| 1088 | const char *msg, | 1092 | const char *msg, |
| 1089 | const char *other_detail) | 1093 | const char *other_detail) |
| 1090 | { | 1094 | { |
| 1095 | struct dimm_info *dimm; | ||
| 1091 | char *p; | 1096 | char *p; |
| 1092 | int row = -1, chan = -1; | 1097 | int row = -1, chan = -1; |
| 1093 | int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer }; | 1098 | int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer }; |
| @@ -1148,9 +1153,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, · 54 unmodified lines | |||
| 1148 | p = e->label; | 1153 | p = e->label; |
| 1149 | *p = '\0'; | 1154 | *p = '\0'; |
| 1150 | 1155 | ||
| 1151 | for (i = 0; i < mci->tot_dimms; i++) { | 1156 | mci_for_each_dimm(mci, dimm) { |
| 1152 | struct dimm_info *dimm = mci->dimms[i]; | ||
| 1153 | |||
| 1154 | if (top_layer >= 0 && top_layer != dimm->location[0]) | 1157 | if (top_layer >= 0 && top_layer != dimm->location[0]) |
| 1155 | continue; | 1158 | continue; |
| 1156 | if (mid_layer >= 0 && mid_layer != dimm->location[1]) | 1159 | if (mid_layer >= 0 && mid_layer != dimm->location[1]) |
| @@ -621,8 +621,7 @@ static const struct device_type dimm_attr_type = { · 620 unmodified lines | |||
| 621 | 621 | ||
| 622 | /* Create a DIMM object under specifed memory controller device */ | 622 | /* Create a DIMM object under specifed memory controller device */ |
| 623 | static int edac_create_dimm_object(struct mem_ctl_info *mci, | 623 | static int edac_create_dimm_object(struct mem_ctl_info *mci, |
| 624 | struct dimm_info *dimm, | 624 | struct dimm_info *dimm) |
| 625 | int index) | ||
| 626 | { | 625 | { |
| 627 | int err; | 626 | int err; |
| 628 | dimm->mci = mci; | 627 | dimm->mci = mci; |
| @@ -632,9 +631,9 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, · 3 unmodified lines | |||
| 632 | 631 | ||
| 633 | dimm->dev.parent = &mci->dev; | 632 | dimm->dev.parent = &mci->dev; |
| 634 | if (mci->csbased) | 633 | if (mci->csbased) |
| 635 | dev_set_name(&dimm->dev, "rank%d", index); | 634 | dev_set_name(&dimm->dev, "rank%d", dimm->idx); |
| 636 | else | 635 | else |
| 637 | dev_set_name(&dimm->dev, "dimm%d", index); | 636 | dev_set_name(&dimm->dev, "dimm%d", dimm->idx); |
| 638 | dev_set_drvdata(&dimm->dev, dimm); | 637 | dev_set_drvdata(&dimm->dev, dimm); |
| 639 | pm_runtime_forbid(&mci->dev); | 638 | pm_runtime_forbid(&mci->dev); |
| 640 | 639 | ||
| @@ -916,7 +915,8 @@ static const struct device_type mci_attr_type = { · 275 unmodified lines | |||
| 916 | int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, | 915 | int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, |
| 917 | const struct attribute_group **groups) | 916 | const struct attribute_group **groups) |
| 918 | { | 917 | { |
| 919 | int i, err; | 918 | struct dimm_info *dimm; |
| 919 | int err; | ||
| 920 | 920 | ||
| 921 | /* get the /sys/devices/system/edac subsys reference */ | 921 | /* get the /sys/devices/system/edac subsys reference */ |
| 922 | mci->dev.type = &mci_attr_type; | 922 | mci->dev.type = &mci_attr_type; |
| @@ -940,13 +940,12 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, · 17 unmodified lines | |||
| 940 | /* | 940 | /* |
| 941 | * Create the dimm/rank devices | 941 | * Create the dimm/rank devices |
| 942 | */ | 942 | */ |
| 943 | for (i = 0; i < mci->tot_dimms; i++) { | 943 | mci_for_each_dimm(mci, dimm) { |
| 944 | struct dimm_info *dimm = mci->dimms[i]; | ||
| 945 | /* Only expose populated DIMMs */ | 944 | /* Only expose populated DIMMs */ |
| 946 | if (!dimm->nr_pages) | 945 | if (!dimm->nr_pages) |
| 947 | continue; | 946 | continue; |
| 948 | 947 | ||
| 949 | err = edac_create_dimm_object(mci, dimm, i); | 948 | err = edac_create_dimm_object(mci, dimm); |
| 950 | if (err) | 949 | if (err) |
| 951 | goto fail_unregister_dimm; | 950 | goto fail_unregister_dimm; |
| 952 | } | 951 | } |
| @@ -961,12 +960,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, · 8 unmodified lines | |||
| 961 | return 0; | 960 | return 0; |
| 962 | 961 | ||
| 963 | fail_unregister_dimm: | 962 | fail_unregister_dimm: |
| 964 | for (i--; i >= 0; i--) { | 963 | mci_for_each_dimm(mci, dimm) { |
| 965 | struct dimm_info *dimm = mci->dimms[i]; | 964 | if (device_is_registered(&dimm->dev)) |
| 966 | if (!dimm->nr_pages) | 965 | device_unregister(&dimm->dev); |
| 967 | continue; | ||
| 968 | |||
| 969 | device_unregister(&dimm->dev); | ||
| 970 | } | 966 | } |
| 971 | device_unregister(&mci->dev); | 967 | device_unregister(&mci->dev); |
| 972 | 968 | ||
| @@ -978,7 +974,7 @@ fail_unregister_dimm: · 5 unmodified lines | |||
| 978 | */ | 974 | */ |
| 979 | void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) | 975 | void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) |
| 980 | { | 976 | { |
| 981 | int i; | 977 | struct dimm_info *dimm; |
| 982 | 978 | ||
| 983 | edac_dbg(0, "\n"); | 979 | edac_dbg(0, "\n"); |
| 984 | 980 | ||
| @@ -989,8 +985,7 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) · 4 unmodified lines | |||
| 989 | edac_delete_csrow_objects(mci); | 985 | edac_delete_csrow_objects(mci); |
| 990 | #endif | 986 | #endif |
| 991 | 987 | ||
| 992 | for (i = 0; i < mci->tot_dimms; i++) { | 988 | mci_for_each_dimm(mci, dimm) { |
| 993 | struct dimm_info *dimm = mci->dimms[i]; | ||
| 994 | if (dimm->nr_pages == 0) | 989 | if (dimm->nr_pages == 0) |
| 995 | continue; | 990 | continue; |
| 996 | edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev)); | 991 | edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev)); |
| @@ -90,12 +90,13 @@ static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg) · 89 unmodified lines | |||
| 90 | 90 | ||
| 91 | static int get_dimm_smbios_index(struct mem_ctl_info *mci, u16 handle) | 91 | static int get_dimm_smbios_index(struct mem_ctl_info *mci, u16 handle) |
| 92 | { | 92 | { |
| 93 | int i; | 93 | struct dimm_info *dimm; |
| 94 | 94 | ||
| 95 | for (i = 0; i < mci->tot_dimms; i++) { | 95 | mci_for_each_dimm(mci, dimm) { |
| 96 | if (mci->dimms[i]->smbios_handle == handle) | 96 | if (dimm->smbios_handle == handle) |
| 97 | return i; | 97 | return dimm->idx; |
| 98 | } | 98 | } |
| 99 | |||
| 99 | return -1; | 100 | return -1; |
| 100 | } | 101 | } |
| 101 | 102 | ||
| @@ -846,20 +846,17 @@ static void i5100_init_interleaving(struct pci_dev *pdev, · 845 unmodified lines | |||
| 846 | 846 | ||
| 847 | static void i5100_init_csrows(struct mem_ctl_info *mci) | 847 | static void i5100_init_csrows(struct mem_ctl_info *mci) |
| 848 | { | 848 | { |
| 849 | int i; | ||
| 850 | struct i5100_priv *priv = mci->pvt_info; | 849 | struct i5100_priv *priv = mci->pvt_info; |
| 850 | struct dimm_info *dimm; | ||
| 851 | 851 | ||
| 852 | for (i = 0; i < mci->tot_dimms; i++) { | 852 | mci_for_each_dimm(mci, dimm) { |
| 853 | struct dimm_info *dimm; | 853 | const unsigned long npages = i5100_npages(mci, dimm->idx); |
| 854 | const unsigned long npages = i5100_npages(mci, i); | 854 | const unsigned int chan = i5100_csrow_to_chan(mci, dimm->idx); |
| 855 | const unsigned int chan = i5100_csrow_to_chan(mci, i); | 855 | const unsigned int rank = i5100_csrow_to_rank(mci, dimm->idx); |
| 856 | const unsigned int rank = i5100_csrow_to_rank(mci, i); | ||
| 857 | 856 | ||
| 858 | if (!npages) | 857 | if (!npages) |
| 859 | continue; | 858 | continue; |
| 860 | 859 | ||
| 861 | dimm = edac_get_dimm(mci, chan, rank, 0); | ||
| 862 | |||
| 863 | dimm->nr_pages = npages; | 860 | dimm->nr_pages = npages; |
| 864 | dimm->grain = 32; | 861 | dimm->grain = 32; |
| 865 | dimm->dtype = (priv->mtr[chan][rank].width == 4) ? | 862 | dimm->dtype = (priv->mtr[chan][rank].width == 4) ? |
| @@ -599,6 +599,13 @@ struct mem_ctl_info { · 598 unmodified lines | |||
| 599 | u16 fake_inject_count; | 599 | u16 fake_inject_count; |
| 600 | }; | 600 | }; |
| 601 | 601 | ||
| 602 | #define mci_for_each_dimm(mci, dimm) \ | ||
| 603 | for ((dimm) = (mci)->dimms[0]; \ | ||
| 604 | (dimm); \ | ||
| 605 | (dimm) = (dimm)->idx + 1 < (mci)->tot_dimms \ | ||
| 606 | ? (mci)->dimms[(dimm)->idx + 1] \ | ||
| 607 | : NULL) | ||
| 608 | |||
| 602 | /** | 609 | /** |
| 603 | * edac_get_dimm_by_index - Get DIMM info at @index from a memory | 610 | * edac_get_dimm_by_index - Get DIMM info at @index from a memory |
| 604 | * controller | 611 | * controller |