Commit 084a4fccef39ac7abb039511f32380f28d0b67e6
1 parent
a7d7d2e1a0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
edac: move dimm properties to struct dimm_info
On systems based on chip select rows, all channels need to use memories with the same properties, otherwise the memories on channels A and B won't be recognized. However, such assumption is not true for all types of memory controllers. Controllers for FB-DIMM's don't have such requirements. Also, modern Intel controllers seem to be capable of handling such differences. So, we need to get rid of storing the DIMM information into a per-csrow data, storing it, instead at the right place. The first step is to move grain, mtype, dtype and edac_mode to the per-dimm struct. Reviewed-by: Aristeu Rozanski <arozansk@redhat.com> Reviewed-by: Borislav Petkov <borislav.petkov@amd.com> Acked-by: Chris Metcalf <cmetcalf@tilera.com> Cc: Doug Thompson <norsk5@yahoo.com> Cc: Borislav Petkov <borislav.petkov@amd.com> Cc: Mark Gross <mark.gross@intel.com> Cc: Jason Uhlenkott <juhlenko@akamai.com> Cc: Tim Small <tim@buttersideup.com> Cc: Ranganathan Desikan <ravi@jetztechnologies.com> Cc: "Arvind R." <arvino55@gmail.com> Cc: Olof Johansson <olof@lixom.net> Cc: Egor Martovetsky <egor@pasemi.com> Cc: Michal Marek <mmarek@suse.cz> Cc: Jiri Kosina <jkosina@suse.cz> Cc: Joe Perches <joe@perches.com> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Hitoshi Mitake <h.mitake@gmail.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: James Bottomley <James.Bottomley@parallels.com> Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com> Cc: Shaohui Xie <Shaohui.Xie@freescale.com> Cc: Josh Boyer <jwboyer@gmail.com> Cc: Mike Williams <mike@mikebwilliams.com> Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Showing 28 changed files with 334 additions and 257 deletions Side-by-side Diff
- drivers/edac/amd64_edac.c
- drivers/edac/amd76x_edac.c
- drivers/edac/cell_edac.c
- drivers/edac/cpc925_edac.c
- drivers/edac/e752x_edac.c
- drivers/edac/e7xxx_edac.c
- drivers/edac/edac_mc.c
- drivers/edac/edac_mc_sysfs.c
- drivers/edac/i3000_edac.c
- drivers/edac/i3200_edac.c
- drivers/edac/i5000_edac.c
- drivers/edac/i5100_edac.c
- drivers/edac/i5400_edac.c
- drivers/edac/i7300_edac.c
- drivers/edac/i7core_edac.c
- drivers/edac/i82443bxgx_edac.c
- drivers/edac/i82860_edac.c
- drivers/edac/i82875p_edac.c
- drivers/edac/i82975x_edac.c
- drivers/edac/mpc85xx_edac.c
- drivers/edac/mv64x60_edac.c
- drivers/edac/pasemi_edac.c
- drivers/edac/ppc4xx_edac.c
- drivers/edac/r82600_edac.c
- drivers/edac/sb_edac.c
- drivers/edac/tile_edac.c
- drivers/edac/x38_edac.c
- include/linux/edac.h
drivers/edac/amd64_edac.c
... | ... | @@ -2187,7 +2187,9 @@ |
2187 | 2187 | struct amd64_pvt *pvt = mci->pvt_info; |
2188 | 2188 | u64 input_addr_min, input_addr_max, sys_addr, base, mask; |
2189 | 2189 | u32 val; |
2190 | - int i, empty = 1; | |
2190 | + int i, j, empty = 1; | |
2191 | + enum mem_type mtype; | |
2192 | + enum edac_type edac_mode; | |
2191 | 2193 | |
2192 | 2194 | amd64_read_pci_cfg(pvt->F3, NBCFG, &val); |
2193 | 2195 | |
... | ... | @@ -2224,7 +2226,7 @@ |
2224 | 2226 | csrow->page_mask = ~mask; |
2225 | 2227 | /* 8 bytes of resolution */ |
2226 | 2228 | |
2227 | - csrow->mtype = amd64_determine_memory_type(pvt, i); | |
2229 | + mtype = amd64_determine_memory_type(pvt, i); | |
2228 | 2230 | |
2229 | 2231 | debugf1(" for MC node %d csrow %d:\n", pvt->mc_node_id, i); |
2230 | 2232 | debugf1(" input_addr_min: 0x%lx input_addr_max: 0x%lx\n", |
2231 | 2233 | |
... | ... | @@ -2241,11 +2243,15 @@ |
2241 | 2243 | * determine whether CHIPKILL or JUST ECC or NO ECC is operating |
2242 | 2244 | */ |
2243 | 2245 | if (pvt->nbcfg & NBCFG_ECC_ENABLE) |
2244 | - csrow->edac_mode = | |
2245 | - (pvt->nbcfg & NBCFG_CHIPKILL) ? | |
2246 | - EDAC_S4ECD4ED : EDAC_SECDED; | |
2246 | + edac_mode = (pvt->nbcfg & NBCFG_CHIPKILL) ? | |
2247 | + EDAC_S4ECD4ED : EDAC_SECDED; | |
2247 | 2248 | else |
2248 | - csrow->edac_mode = EDAC_NONE; | |
2249 | + edac_mode = EDAC_NONE; | |
2250 | + | |
2251 | + for (j = 0; j < pvt->channel_count; j++) { | |
2252 | + csrow->channels[j].dimm->mtype = mtype; | |
2253 | + csrow->channels[j].dimm->edac_mode = edac_mode; | |
2254 | + } | |
2249 | 2255 | } |
2250 | 2256 | |
2251 | 2257 | return empty; |
drivers/edac/amd76x_edac.c
... | ... | @@ -186,11 +186,13 @@ |
186 | 186 | enum edac_type edac_mode) |
187 | 187 | { |
188 | 188 | struct csrow_info *csrow; |
189 | + struct dimm_info *dimm; | |
189 | 190 | u32 mba, mba_base, mba_mask, dms; |
190 | 191 | int index; |
191 | 192 | |
192 | 193 | for (index = 0; index < mci->nr_csrows; index++) { |
193 | 194 | csrow = &mci->csrows[index]; |
195 | + dimm = csrow->channels[0].dimm; | |
194 | 196 | |
195 | 197 | /* find the DRAM Chip Select Base address and mask */ |
196 | 198 | pci_read_config_dword(pdev, |
... | ... | @@ -206,10 +208,10 @@ |
206 | 208 | csrow->nr_pages = (mba_mask + 1) >> PAGE_SHIFT; |
207 | 209 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
208 | 210 | csrow->page_mask = mba_mask >> PAGE_SHIFT; |
209 | - csrow->grain = csrow->nr_pages << PAGE_SHIFT; | |
210 | - csrow->mtype = MEM_RDDR; | |
211 | - csrow->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN; | |
212 | - csrow->edac_mode = edac_mode; | |
211 | + dimm->grain = csrow->nr_pages << PAGE_SHIFT; | |
212 | + dimm->mtype = MEM_RDDR; | |
213 | + dimm->dtype = ((dms >> index) & 0x1) ? DEV_X4 : DEV_UNKNOWN; | |
214 | + dimm->edac_mode = edac_mode; | |
213 | 215 | } |
214 | 216 | } |
215 | 217 |
drivers/edac/cell_edac.c
... | ... | @@ -124,8 +124,10 @@ |
124 | 124 | static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci) |
125 | 125 | { |
126 | 126 | struct csrow_info *csrow = &mci->csrows[0]; |
127 | + struct dimm_info *dimm; | |
127 | 128 | struct cell_edac_priv *priv = mci->pvt_info; |
128 | 129 | struct device_node *np; |
130 | + int j; | |
129 | 131 | |
130 | 132 | for (np = NULL; |
131 | 133 | (np = of_find_node_by_name(np, "memory")) != NULL;) { |
... | ... | @@ -142,8 +144,12 @@ |
142 | 144 | csrow->first_page = r.start >> PAGE_SHIFT; |
143 | 145 | csrow->nr_pages = resource_size(&r) >> PAGE_SHIFT; |
144 | 146 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
145 | - csrow->mtype = MEM_XDR; | |
146 | - csrow->edac_mode = EDAC_SECDED; | |
147 | + | |
148 | + for (j = 0; j < csrow->nr_channels; j++) { | |
149 | + dimm = csrow->channels[j].dimm; | |
150 | + dimm->mtype = MEM_XDR; | |
151 | + dimm->edac_mode = EDAC_SECDED; | |
152 | + } | |
147 | 153 | dev_dbg(mci->dev, |
148 | 154 | "Initialized on node %d, chanmask=0x%x," |
149 | 155 | " first_page=0x%lx, nr_pages=0x%x\n", |
drivers/edac/cpc925_edac.c
... | ... | @@ -329,7 +329,8 @@ |
329 | 329 | { |
330 | 330 | struct cpc925_mc_pdata *pdata = mci->pvt_info; |
331 | 331 | struct csrow_info *csrow; |
332 | - int index; | |
332 | + struct dimm_info *dimm; | |
333 | + int index, j; | |
333 | 334 | u32 mbmr, mbbar, bba; |
334 | 335 | unsigned long row_size, last_nr_pages = 0; |
335 | 336 | |
336 | 337 | |
337 | 338 | |
... | ... | @@ -354,32 +355,35 @@ |
354 | 355 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
355 | 356 | last_nr_pages = csrow->last_page + 1; |
356 | 357 | |
357 | - csrow->mtype = MEM_RDDR; | |
358 | - csrow->edac_mode = EDAC_SECDED; | |
358 | + for (j = 0; j < csrow->nr_channels; j++) { | |
359 | + dimm = csrow->channels[j].dimm; | |
360 | + dimm->mtype = MEM_RDDR; | |
361 | + dimm->edac_mode = EDAC_SECDED; | |
359 | 362 | |
360 | - switch (csrow->nr_channels) { | |
361 | - case 1: /* Single channel */ | |
362 | - csrow->grain = 32; /* four-beat burst of 32 bytes */ | |
363 | - break; | |
364 | - case 2: /* Dual channel */ | |
365 | - default: | |
366 | - csrow->grain = 64; /* four-beat burst of 64 bytes */ | |
367 | - break; | |
368 | - } | |
363 | + switch (csrow->nr_channels) { | |
364 | + case 1: /* Single channel */ | |
365 | + dimm->grain = 32; /* four-beat burst of 32 bytes */ | |
366 | + break; | |
367 | + case 2: /* Dual channel */ | |
368 | + default: | |
369 | + dimm->grain = 64; /* four-beat burst of 64 bytes */ | |
370 | + break; | |
371 | + } | |
369 | 372 | |
370 | - switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) { | |
371 | - case 6: /* 0110, no way to differentiate X8 VS X16 */ | |
372 | - case 5: /* 0101 */ | |
373 | - case 8: /* 1000 */ | |
374 | - csrow->dtype = DEV_X16; | |
375 | - break; | |
376 | - case 7: /* 0111 */ | |
377 | - case 9: /* 1001 */ | |
378 | - csrow->dtype = DEV_X8; | |
379 | - break; | |
380 | - default: | |
381 | - csrow->dtype = DEV_UNKNOWN; | |
382 | - break; | |
373 | + switch ((mbmr & MBMR_MODE_MASK) >> MBMR_MODE_SHIFT) { | |
374 | + case 6: /* 0110, no way to differentiate X8 VS X16 */ | |
375 | + case 5: /* 0101 */ | |
376 | + case 8: /* 1000 */ | |
377 | + dimm->dtype = DEV_X16; | |
378 | + break; | |
379 | + case 7: /* 0111 */ | |
380 | + case 9: /* 1001 */ | |
381 | + dimm->dtype = DEV_X8; | |
382 | + break; | |
383 | + default: | |
384 | + dimm->dtype = DEV_UNKNOWN; | |
385 | + break; | |
386 | + } | |
383 | 387 | } |
384 | 388 | } |
385 | 389 | } |
386 | 390 | |
... | ... | @@ -962,9 +966,9 @@ |
962 | 966 | goto err2; |
963 | 967 | } |
964 | 968 | |
965 | - nr_channels = cpc925_mc_get_channels(vbase); | |
969 | + nr_channels = cpc925_mc_get_channels(vbase) + 1; | |
966 | 970 | mci = edac_mc_alloc(sizeof(struct cpc925_mc_pdata), |
967 | - CPC925_NR_CSROWS, nr_channels + 1, edac_mc_idx); | |
971 | + CPC925_NR_CSROWS, nr_channels, edac_mc_idx); | |
968 | 972 | if (!mci) { |
969 | 973 | cpc925_printk(KERN_ERR, "No memory for mem_ctl_info\n"); |
970 | 974 | res = -ENOMEM; |
drivers/edac/e752x_edac.c
... | ... | @@ -1044,7 +1044,7 @@ |
1044 | 1044 | int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */ |
1045 | 1045 | int drc_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */ |
1046 | 1046 | u8 value; |
1047 | - u32 dra, drc, cumul_size; | |
1047 | + u32 dra, drc, cumul_size, i; | |
1048 | 1048 | |
1049 | 1049 | dra = 0; |
1050 | 1050 | for (index = 0; index < 4; index++) { |
... | ... | @@ -1053,7 +1053,7 @@ |
1053 | 1053 | dra |= dra_reg << (index * 8); |
1054 | 1054 | } |
1055 | 1055 | pci_read_config_dword(pdev, E752X_DRC, &drc); |
1056 | - drc_chan = dual_channel_active(ddrcsr); | |
1056 | + drc_chan = dual_channel_active(ddrcsr) ? 1 : 0; | |
1057 | 1057 | drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */ |
1058 | 1058 | drc_ddim = (drc >> 20) & 0x3; |
1059 | 1059 | |
1060 | 1060 | |
... | ... | @@ -1080,24 +1080,28 @@ |
1080 | 1080 | csrow->last_page = cumul_size - 1; |
1081 | 1081 | csrow->nr_pages = cumul_size - last_cumul_size; |
1082 | 1082 | last_cumul_size = cumul_size; |
1083 | - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ | |
1084 | - csrow->mtype = MEM_RDDR; /* only one type supported */ | |
1085 | - csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; | |
1086 | 1083 | |
1087 | - /* | |
1088 | - * if single channel or x8 devices then SECDED | |
1089 | - * if dual channel and x4 then S4ECD4ED | |
1090 | - */ | |
1091 | - if (drc_ddim) { | |
1092 | - if (drc_chan && mem_dev) { | |
1093 | - csrow->edac_mode = EDAC_S4ECD4ED; | |
1094 | - mci->edac_cap |= EDAC_FLAG_S4ECD4ED; | |
1095 | - } else { | |
1096 | - csrow->edac_mode = EDAC_SECDED; | |
1097 | - mci->edac_cap |= EDAC_FLAG_SECDED; | |
1098 | - } | |
1099 | - } else | |
1100 | - csrow->edac_mode = EDAC_NONE; | |
1084 | + for (i = 0; i < drc_chan + 1; i++) { | |
1085 | + struct dimm_info *dimm = csrow->channels[i].dimm; | |
1086 | + dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */ | |
1087 | + dimm->mtype = MEM_RDDR; /* only one type supported */ | |
1088 | + dimm->dtype = mem_dev ? DEV_X4 : DEV_X8; | |
1089 | + | |
1090 | + /* | |
1091 | + * if single channel or x8 devices then SECDED | |
1092 | + * if dual channel and x4 then S4ECD4ED | |
1093 | + */ | |
1094 | + if (drc_ddim) { | |
1095 | + if (drc_chan && mem_dev) { | |
1096 | + dimm->edac_mode = EDAC_S4ECD4ED; | |
1097 | + mci->edac_cap |= EDAC_FLAG_S4ECD4ED; | |
1098 | + } else { | |
1099 | + dimm->edac_mode = EDAC_SECDED; | |
1100 | + mci->edac_cap |= EDAC_FLAG_SECDED; | |
1101 | + } | |
1102 | + } else | |
1103 | + dimm->edac_mode = EDAC_NONE; | |
1104 | + } | |
1101 | 1105 | } |
1102 | 1106 | } |
1103 | 1107 |
drivers/edac/e7xxx_edac.c
... | ... | @@ -347,11 +347,12 @@ |
347 | 347 | int dev_idx, u32 drc) |
348 | 348 | { |
349 | 349 | unsigned long last_cumul_size; |
350 | - int index; | |
350 | + int index, j; | |
351 | 351 | u8 value; |
352 | 352 | u32 dra, cumul_size; |
353 | 353 | int drc_chan, drc_drbg, drc_ddim, mem_dev; |
354 | 354 | struct csrow_info *csrow; |
355 | + struct dimm_info *dimm; | |
355 | 356 | |
356 | 357 | pci_read_config_dword(pdev, E7XXX_DRA, &dra); |
357 | 358 | drc_chan = dual_channel_active(drc, dev_idx); |
358 | 359 | |
... | ... | @@ -381,24 +382,29 @@ |
381 | 382 | csrow->last_page = cumul_size - 1; |
382 | 383 | csrow->nr_pages = cumul_size - last_cumul_size; |
383 | 384 | last_cumul_size = cumul_size; |
384 | - csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */ | |
385 | - csrow->mtype = MEM_RDDR; /* only one type supported */ | |
386 | - csrow->dtype = mem_dev ? DEV_X4 : DEV_X8; | |
387 | 385 | |
388 | - /* | |
389 | - * if single channel or x8 devices then SECDED | |
390 | - * if dual channel and x4 then S4ECD4ED | |
391 | - */ | |
392 | - if (drc_ddim) { | |
393 | - if (drc_chan && mem_dev) { | |
394 | - csrow->edac_mode = EDAC_S4ECD4ED; | |
395 | - mci->edac_cap |= EDAC_FLAG_S4ECD4ED; | |
396 | - } else { | |
397 | - csrow->edac_mode = EDAC_SECDED; | |
398 | - mci->edac_cap |= EDAC_FLAG_SECDED; | |
399 | - } | |
400 | - } else | |
401 | - csrow->edac_mode = EDAC_NONE; | |
386 | + for (j = 0; j < drc_chan + 1; j++) { | |
387 | + dimm = csrow->channels[j].dimm; | |
388 | + | |
389 | + dimm->grain = 1 << 12; /* 4KiB - resolution of CELOG */ | |
390 | + dimm->mtype = MEM_RDDR; /* only one type supported */ | |
391 | + dimm->dtype = mem_dev ? DEV_X4 : DEV_X8; | |
392 | + | |
393 | + /* | |
394 | + * if single channel or x8 devices then SECDED | |
395 | + * if dual channel and x4 then S4ECD4ED | |
396 | + */ | |
397 | + if (drc_ddim) { | |
398 | + if (drc_chan && mem_dev) { | |
399 | + dimm->edac_mode = EDAC_S4ECD4ED; | |
400 | + mci->edac_cap |= EDAC_FLAG_S4ECD4ED; | |
401 | + } else { | |
402 | + dimm->edac_mode = EDAC_SECDED; | |
403 | + mci->edac_cap |= EDAC_FLAG_SECDED; | |
404 | + } | |
405 | + } else | |
406 | + dimm->edac_mode = EDAC_NONE; | |
407 | + } | |
402 | 408 | } |
403 | 409 | } |
404 | 410 |
drivers/edac/edac_mc.c
... | ... | @@ -43,7 +43,7 @@ |
43 | 43 | { |
44 | 44 | debugf4("\tchannel = %p\n", chan); |
45 | 45 | debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx); |
46 | - debugf4("\tchannel->ce_count = %d\n", chan->ce_count); | |
46 | + debugf4("\tchannel->ce_count = %d\n", chan->dimm->ce_count); | |
47 | 47 | debugf4("\tchannel->label = '%s'\n", chan->dimm->label); |
48 | 48 | debugf4("\tchannel->csrow = %p\n\n", chan->csrow); |
49 | 49 | } |
... | ... | @@ -695,6 +695,7 @@ |
695 | 695 | { |
696 | 696 | unsigned long remapped_page; |
697 | 697 | char *label = NULL; |
698 | + u32 grain; | |
698 | 699 | |
699 | 700 | debugf3("MC%d: %s()\n", mci->mc_idx, __func__); |
700 | 701 | |
... | ... | @@ -719,6 +720,7 @@ |
719 | 720 | } |
720 | 721 | |
721 | 722 | label = mci->csrows[row].channels[channel].dimm->label; |
723 | + grain = mci->csrows[row].channels[channel].dimm->grain; | |
722 | 724 | |
723 | 725 | if (edac_mc_get_log_ce()) |
724 | 726 | /* FIXME - put in DIMM location */ |
725 | 727 | |
... | ... | @@ -726,11 +728,12 @@ |
726 | 728 | "CE page 0x%lx, offset 0x%lx, grain %d, syndrome " |
727 | 729 | "0x%lx, row %d, channel %d, label \"%s\": %s\n", |
728 | 730 | page_frame_number, offset_in_page, |
729 | - mci->csrows[row].grain, syndrome, row, channel, | |
731 | + grain, syndrome, row, channel, | |
730 | 732 | label, msg); |
731 | 733 | |
732 | 734 | mci->ce_count++; |
733 | 735 | mci->csrows[row].ce_count++; |
736 | + mci->csrows[row].channels[channel].dimm->ce_count++; | |
734 | 737 | mci->csrows[row].channels[channel].ce_count++; |
735 | 738 | |
736 | 739 | if (mci->scrub_mode & SCRUB_SW_SRC) { |
... | ... | @@ -747,8 +750,7 @@ |
747 | 750 | mci->ctl_page_to_phys(mci, page_frame_number) : |
748 | 751 | page_frame_number; |
749 | 752 | |
750 | - edac_mc_scrub_block(remapped_page, offset_in_page, | |
751 | - mci->csrows[row].grain); | |
753 | + edac_mc_scrub_block(remapped_page, offset_in_page, grain); | |
752 | 754 | } |
753 | 755 | } |
754 | 756 | EXPORT_SYMBOL_GPL(edac_mc_handle_ce); |
... | ... | @@ -774,6 +776,7 @@ |
774 | 776 | int chan; |
775 | 777 | int chars; |
776 | 778 | char *label = NULL; |
779 | + u32 grain; | |
777 | 780 | |
778 | 781 | debugf3("MC%d: %s()\n", mci->mc_idx, __func__); |
779 | 782 | |
... | ... | @@ -787,6 +790,7 @@ |
787 | 790 | return; |
788 | 791 | } |
789 | 792 | |
793 | + grain = mci->csrows[row].channels[0].dimm->grain; | |
790 | 794 | label = mci->csrows[row].channels[0].dimm->label; |
791 | 795 | chars = snprintf(pos, len + 1, "%s", label); |
792 | 796 | len -= chars; |
793 | 797 | |
... | ... | @@ -804,14 +808,13 @@ |
804 | 808 | edac_mc_printk(mci, KERN_EMERG, |
805 | 809 | "UE page 0x%lx, offset 0x%lx, grain %d, row %d, " |
806 | 810 | "labels \"%s\": %s\n", page_frame_number, |
807 | - offset_in_page, mci->csrows[row].grain, row, | |
808 | - labels, msg); | |
811 | + offset_in_page, grain, row, labels, msg); | |
809 | 812 | |
810 | 813 | if (edac_mc_get_panic_on_ue()) |
811 | 814 | panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, " |
812 | 815 | "row %d, labels \"%s\": %s\n", mci->mc_idx, |
813 | 816 | page_frame_number, offset_in_page, |
814 | - mci->csrows[row].grain, row, labels, msg); | |
817 | + grain, row, labels, msg); | |
815 | 818 | |
816 | 819 | mci->ue_count++; |
817 | 820 | mci->csrows[row].ue_count++; |
... | ... | @@ -883,6 +886,7 @@ |
883 | 886 | chars = snprintf(pos, len + 1, "%s", label); |
884 | 887 | len -= chars; |
885 | 888 | pos += chars; |
889 | + | |
886 | 890 | chars = snprintf(pos, len + 1, "-%s", |
887 | 891 | mci->csrows[csrow].channels[channelb].dimm->label); |
888 | 892 | |
... | ... | @@ -936,6 +940,7 @@ |
936 | 940 | |
937 | 941 | mci->ce_count++; |
938 | 942 | mci->csrows[csrow].ce_count++; |
943 | + mci->csrows[csrow].channels[channel].dimm->ce_count++; | |
939 | 944 | mci->csrows[csrow].channels[channel].ce_count++; |
940 | 945 | } |
941 | 946 | EXPORT_SYMBOL(edac_mc_handle_fbd_ce); |
drivers/edac/edac_mc_sysfs.c
... | ... | @@ -150,19 +150,19 @@ |
150 | 150 | static ssize_t csrow_mem_type_show(struct csrow_info *csrow, char *data, |
151 | 151 | int private) |
152 | 152 | { |
153 | - return sprintf(data, "%s\n", mem_types[csrow->mtype]); | |
153 | + return sprintf(data, "%s\n", mem_types[csrow->channels[0].dimm->mtype]); | |
154 | 154 | } |
155 | 155 | |
156 | 156 | static ssize_t csrow_dev_type_show(struct csrow_info *csrow, char *data, |
157 | 157 | int private) |
158 | 158 | { |
159 | - return sprintf(data, "%s\n", dev_types[csrow->dtype]); | |
159 | + return sprintf(data, "%s\n", dev_types[csrow->channels[0].dimm->dtype]); | |
160 | 160 | } |
161 | 161 | |
162 | 162 | static ssize_t csrow_edac_mode_show(struct csrow_info *csrow, char *data, |
163 | 163 | int private) |
164 | 164 | { |
165 | - return sprintf(data, "%s\n", edac_caps[csrow->edac_mode]); | |
165 | + return sprintf(data, "%s\n", edac_caps[csrow->channels[0].dimm->edac_mode]); | |
166 | 166 | } |
167 | 167 | |
168 | 168 | /* show/store functions for DIMM Label attributes */ |
drivers/edac/i3000_edac.c
... | ... | @@ -304,7 +304,7 @@ |
304 | 304 | static int i3000_probe1(struct pci_dev *pdev, int dev_idx) |
305 | 305 | { |
306 | 306 | int rc; |
307 | - int i; | |
307 | + int i, j; | |
308 | 308 | struct mem_ctl_info *mci = NULL; |
309 | 309 | unsigned long last_cumul_size; |
310 | 310 | int interleaved, nr_channels; |
311 | 311 | |
312 | 312 | |
... | ... | @@ -386,19 +386,21 @@ |
386 | 386 | cumul_size <<= 1; |
387 | 387 | debugf3("MC: %s(): (%d) cumul_size 0x%x\n", |
388 | 388 | __func__, i, cumul_size); |
389 | - if (cumul_size == last_cumul_size) { | |
390 | - csrow->mtype = MEM_EMPTY; | |
389 | + if (cumul_size == last_cumul_size) | |
391 | 390 | continue; |
392 | - } | |
393 | 391 | |
394 | 392 | csrow->first_page = last_cumul_size; |
395 | 393 | csrow->last_page = cumul_size - 1; |
396 | 394 | csrow->nr_pages = cumul_size - last_cumul_size; |
397 | 395 | last_cumul_size = cumul_size; |
398 | - csrow->grain = I3000_DEAP_GRAIN; | |
399 | - csrow->mtype = MEM_DDR2; | |
400 | - csrow->dtype = DEV_UNKNOWN; | |
401 | - csrow->edac_mode = EDAC_UNKNOWN; | |
396 | + | |
397 | + for (j = 0; j < nr_channels; j++) { | |
398 | + struct dimm_info *dimm = csrow->channels[j].dimm; | |
399 | + dimm->grain = I3000_DEAP_GRAIN; | |
400 | + dimm->mtype = MEM_DDR2; | |
401 | + dimm->dtype = DEV_UNKNOWN; | |
402 | + dimm->edac_mode = EDAC_UNKNOWN; | |
403 | + } | |
402 | 404 | } |
403 | 405 | |
404 | 406 | /* |
drivers/edac/i3200_edac.c
... | ... | @@ -319,7 +319,7 @@ |
319 | 319 | static int i3200_probe1(struct pci_dev *pdev, int dev_idx) |
320 | 320 | { |
321 | 321 | int rc; |
322 | - int i; | |
322 | + int i, j; | |
323 | 323 | struct mem_ctl_info *mci = NULL; |
324 | 324 | unsigned long last_page; |
325 | 325 | u16 drbs[I3200_CHANNELS][I3200_RANKS_PER_CHANNEL]; |
326 | 326 | |
327 | 327 | |
... | ... | @@ -375,20 +375,22 @@ |
375 | 375 | i / I3200_RANKS_PER_CHANNEL, |
376 | 376 | i % I3200_RANKS_PER_CHANNEL); |
377 | 377 | |
378 | - if (nr_pages == 0) { | |
379 | - csrow->mtype = MEM_EMPTY; | |
378 | + if (nr_pages == 0) | |
380 | 379 | continue; |
381 | - } | |
382 | 380 | |
383 | 381 | csrow->first_page = last_page + 1; |
384 | 382 | last_page += nr_pages; |
385 | 383 | csrow->last_page = last_page; |
386 | 384 | csrow->nr_pages = nr_pages; |
387 | 385 | |
388 | - csrow->grain = nr_pages << PAGE_SHIFT; | |
389 | - csrow->mtype = MEM_DDR2; | |
390 | - csrow->dtype = DEV_UNKNOWN; | |
391 | - csrow->edac_mode = EDAC_UNKNOWN; | |
386 | + for (j = 0; j < nr_channels; j++) { | |
387 | + struct dimm_info *dimm = csrow->channels[j].dimm; | |
388 | + | |
389 | + dimm->grain = nr_pages << PAGE_SHIFT; | |
390 | + dimm->mtype = MEM_DDR2; | |
391 | + dimm->dtype = DEV_UNKNOWN; | |
392 | + dimm->edac_mode = EDAC_UNKNOWN; | |
393 | + } | |
392 | 394 | } |
393 | 395 | |
394 | 396 | i3200_clear_error_info(mci); |
drivers/edac/i5000_edac.c
... | ... | @@ -1268,25 +1268,23 @@ |
1268 | 1268 | p_csrow->last_page = 9 + csrow * 20; |
1269 | 1269 | p_csrow->page_mask = 0xFFF; |
1270 | 1270 | |
1271 | - p_csrow->grain = 8; | |
1272 | - | |
1273 | 1271 | csrow_megs = 0; |
1274 | 1272 | for (channel = 0; channel < pvt->maxch; channel++) { |
1275 | 1273 | csrow_megs += pvt->dimm_info[csrow][channel].megabytes; |
1276 | - } | |
1274 | + p_csrow->channels[channel].dimm->grain = 8; | |
1277 | 1275 | |
1278 | - p_csrow->nr_pages = csrow_megs << 8; | |
1276 | + /* Assume DDR2 for now */ | |
1277 | + p_csrow->channels[channel].dimm->mtype = MEM_FB_DDR2; | |
1279 | 1278 | |
1280 | - /* Assume DDR2 for now */ | |
1281 | - p_csrow->mtype = MEM_FB_DDR2; | |
1279 | + /* ask what device type on this row */ | |
1280 | + if (MTR_DRAM_WIDTH(mtr)) | |
1281 | + p_csrow->channels[channel].dimm->dtype = DEV_X8; | |
1282 | + else | |
1283 | + p_csrow->channels[channel].dimm->dtype = DEV_X4; | |
1282 | 1284 | |
1283 | - /* ask what device type on this row */ | |
1284 | - if (MTR_DRAM_WIDTH(mtr)) | |
1285 | - p_csrow->dtype = DEV_X8; | |
1286 | - else | |
1287 | - p_csrow->dtype = DEV_X4; | |
1288 | - | |
1289 | - p_csrow->edac_mode = EDAC_S8ECD8ED; | |
1285 | + p_csrow->channels[channel].dimm->edac_mode = EDAC_S8ECD8ED; | |
1286 | + } | |
1287 | + p_csrow->nr_pages = csrow_megs << 8; | |
1290 | 1288 | |
1291 | 1289 | empty = 0; |
1292 | 1290 | } |
drivers/edac/i5100_edac.c
... | ... | @@ -428,12 +428,16 @@ |
428 | 428 | const char *msg) |
429 | 429 | { |
430 | 430 | const int csrow = i5100_rank_to_csrow(mci, chan, rank); |
431 | + char *label = NULL; | |
431 | 432 | |
433 | + if (mci->csrows[csrow].channels[0].dimm) | |
434 | + label = mci->csrows[csrow].channels[0].dimm->label; | |
435 | + | |
432 | 436 | printk(KERN_ERR |
433 | 437 | "CE chan %d, bank %u, rank %u, syndrome 0x%lx, " |
434 | 438 | "cas %u, ras %u, csrow %u, label \"%s\": %s\n", |
435 | 439 | chan, bank, rank, syndrome, cas, ras, |
436 | - csrow, mci->csrows[csrow].channels[0].dimm->label, msg); | |
440 | + csrow, label, msg); | |
437 | 441 | |
438 | 442 | mci->ce_count++; |
439 | 443 | mci->csrows[csrow].ce_count++; |
440 | 444 | |
441 | 445 | |
... | ... | @@ -450,12 +454,16 @@ |
450 | 454 | const char *msg) |
451 | 455 | { |
452 | 456 | const int csrow = i5100_rank_to_csrow(mci, chan, rank); |
457 | + char *label = NULL; | |
453 | 458 | |
459 | + if (mci->csrows[csrow].channels[0].dimm) | |
460 | + label = mci->csrows[csrow].channels[0].dimm->label; | |
461 | + | |
454 | 462 | printk(KERN_ERR |
455 | 463 | "UE chan %d, bank %u, rank %u, syndrome 0x%lx, " |
456 | 464 | "cas %u, ras %u, csrow %u, label \"%s\": %s\n", |
457 | 465 | chan, bank, rank, syndrome, cas, ras, |
458 | - csrow, mci->csrows[csrow].channels[0].dimm->label, msg); | |
466 | + csrow, label, msg); | |
459 | 467 | |
460 | 468 | mci->ue_count++; |
461 | 469 | mci->csrows[csrow].ue_count++; |
... | ... | @@ -837,6 +845,7 @@ |
837 | 845 | int i; |
838 | 846 | unsigned long total_pages = 0UL; |
839 | 847 | struct i5100_priv *priv = mci->pvt_info; |
848 | + struct dimm_info *dimm; | |
840 | 849 | |
841 | 850 | for (i = 0; i < mci->nr_csrows; i++) { |
842 | 851 | const unsigned long npages = i5100_npages(mci, i); |
843 | 852 | |
844 | 853 | |
845 | 854 | |
846 | 855 | |
847 | 856 | |
... | ... | @@ -852,27 +861,22 @@ |
852 | 861 | */ |
853 | 862 | mci->csrows[i].first_page = total_pages; |
854 | 863 | mci->csrows[i].last_page = total_pages + npages - 1; |
855 | - mci->csrows[i].page_mask = 0UL; | |
856 | - | |
857 | 864 | mci->csrows[i].nr_pages = npages; |
858 | - mci->csrows[i].grain = 32; | |
859 | 865 | mci->csrows[i].csrow_idx = i; |
860 | - mci->csrows[i].dtype = | |
861 | - (priv->mtr[chan][rank].width == 4) ? DEV_X4 : DEV_X8; | |
862 | - mci->csrows[i].ue_count = 0; | |
863 | - mci->csrows[i].ce_count = 0; | |
864 | - mci->csrows[i].mtype = MEM_RDDR2; | |
865 | - mci->csrows[i].edac_mode = EDAC_SECDED; | |
866 | 866 | mci->csrows[i].mci = mci; |
867 | 867 | mci->csrows[i].nr_channels = 1; |
868 | - mci->csrows[i].channels[0].chan_idx = 0; | |
869 | - mci->csrows[i].channels[0].ce_count = 0; | |
870 | 868 | mci->csrows[i].channels[0].csrow = mci->csrows + i; |
871 | - snprintf(mci->csrows[i].channels[0].dimm->label, | |
872 | - sizeof(mci->csrows[i].channels[0].dimm->label), | |
873 | - "DIMM%u", i5100_rank_to_slot(mci, chan, rank)); | |
874 | - | |
875 | 869 | total_pages += npages; |
870 | + | |
871 | + dimm = mci->csrows[i].channels[0].dimm; | |
872 | + dimm->grain = 32; | |
873 | + dimm->dtype = (priv->mtr[chan][rank].width == 4) ? | |
874 | + DEV_X4 : DEV_X8; | |
875 | + dimm->mtype = MEM_RDDR2; | |
876 | + dimm->edac_mode = EDAC_SECDED; | |
877 | + snprintf(dimm->label, sizeof(dimm->label), | |
878 | + "DIMM%u", | |
879 | + i5100_rank_to_slot(mci, chan, rank)); | |
876 | 880 | } |
877 | 881 | } |
878 | 882 |
drivers/edac/i5400_edac.c
... | ... | @@ -1159,6 +1159,7 @@ |
1159 | 1159 | int csrow_megs; |
1160 | 1160 | int channel; |
1161 | 1161 | int csrow; |
1162 | + struct dimm_info *dimm; | |
1162 | 1163 | |
1163 | 1164 | pvt = mci->pvt_info; |
1164 | 1165 | |
1165 | 1166 | |
1166 | 1167 | |
... | ... | @@ -1184,24 +1185,17 @@ |
1184 | 1185 | p_csrow->last_page = 9 + csrow * 20; |
1185 | 1186 | p_csrow->page_mask = 0xFFF; |
1186 | 1187 | |
1187 | - p_csrow->grain = 8; | |
1188 | - | |
1189 | 1188 | csrow_megs = 0; |
1190 | - for (channel = 0; channel < pvt->maxch; channel++) | |
1189 | + for (channel = 0; channel < pvt->maxch; channel++) { | |
1191 | 1190 | csrow_megs += pvt->dimm_info[csrow][channel].megabytes; |
1192 | 1191 | |
1193 | - p_csrow->nr_pages = csrow_megs << 8; | |
1194 | - | |
1195 | - /* Assume DDR2 for now */ | |
1196 | - p_csrow->mtype = MEM_FB_DDR2; | |
1197 | - | |
1198 | - /* ask what device type on this row */ | |
1199 | - if (MTR_DRAM_WIDTH(mtr)) | |
1200 | - p_csrow->dtype = DEV_X8; | |
1201 | - else | |
1202 | - p_csrow->dtype = DEV_X4; | |
1203 | - | |
1204 | - p_csrow->edac_mode = EDAC_S8ECD8ED; | |
1192 | + p_csrow->nr_pages = csrow_megs << 8; | |
1193 | + dimm = p_csrow->channels[channel].dimm; | |
1194 | + dimm->grain = 8; | |
1195 | + dimm->dtype = MTR_DRAM_WIDTH(mtr) ? DEV_X8 : DEV_X4; | |
1196 | + dimm->mtype = MEM_RDDR2; | |
1197 | + dimm->edac_mode = EDAC_SECDED; | |
1198 | + } | |
1205 | 1199 | |
1206 | 1200 | empty = 0; |
1207 | 1201 | } |
drivers/edac/i7300_edac.c
... | ... | @@ -618,6 +618,7 @@ |
618 | 618 | int slot, int ch, int branch, |
619 | 619 | struct i7300_dimm_info *dinfo, |
620 | 620 | struct csrow_info *p_csrow, |
621 | + struct dimm_info *dimm, | |
621 | 622 | u32 *nr_pages) |
622 | 623 | { |
623 | 624 | int mtr, ans, addrBits, channel; |
624 | 625 | |
... | ... | @@ -663,10 +664,7 @@ |
663 | 664 | debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]); |
664 | 665 | debugf2("\t\tSIZE: %d MB\n", dinfo->megabytes); |
665 | 666 | |
666 | - p_csrow->grain = 8; | |
667 | - p_csrow->mtype = MEM_FB_DDR2; | |
668 | 667 | p_csrow->csrow_idx = slot; |
669 | - p_csrow->page_mask = 0; | |
670 | 668 | |
671 | 669 | /* |
672 | 670 | * The type of error detection actually depends of the |
673 | 671 | |
674 | 672 | |
675 | 673 | |
... | ... | @@ -677,15 +675,17 @@ |
677 | 675 | * See datasheet Sections 7.3.6 to 7.3.8 |
678 | 676 | */ |
679 | 677 | |
678 | + dimm->grain = 8; | |
679 | + dimm->mtype = MEM_FB_DDR2; | |
680 | 680 | if (IS_SINGLE_MODE(pvt->mc_settings_a)) { |
681 | - p_csrow->edac_mode = EDAC_SECDED; | |
681 | + dimm->edac_mode = EDAC_SECDED; | |
682 | 682 | debugf2("\t\tECC code is 8-byte-over-32-byte SECDED+ code\n"); |
683 | 683 | } else { |
684 | 684 | debugf2("\t\tECC code is on Lockstep mode\n"); |
685 | 685 | if (MTR_DRAM_WIDTH(mtr) == 8) |
686 | - p_csrow->edac_mode = EDAC_S8ECD8ED; | |
686 | + dimm->edac_mode = EDAC_S8ECD8ED; | |
687 | 687 | else |
688 | - p_csrow->edac_mode = EDAC_S4ECD4ED; | |
688 | + dimm->edac_mode = EDAC_S4ECD4ED; | |
689 | 689 | } |
690 | 690 | |
691 | 691 | /* ask what device type on this row */ |
692 | 692 | |
... | ... | @@ -694,9 +694,9 @@ |
694 | 694 | IS_SCRBALGO_ENHANCED(pvt->mc_settings) ? |
695 | 695 | "enhanced" : "normal"); |
696 | 696 | |
697 | - p_csrow->dtype = DEV_X8; | |
697 | + dimm->dtype = DEV_X8; | |
698 | 698 | } else |
699 | - p_csrow->dtype = DEV_X4; | |
699 | + dimm->dtype = DEV_X4; | |
700 | 700 | |
701 | 701 | return mtr; |
702 | 702 | } |
... | ... | @@ -779,6 +779,7 @@ |
779 | 779 | int mtr; |
780 | 780 | int ch, branch, slot, channel; |
781 | 781 | u32 last_page = 0, nr_pages; |
782 | + struct dimm_info *dimm; | |
782 | 783 | |
783 | 784 | pvt = mci->pvt_info; |
784 | 785 | |
785 | 786 | |
786 | 787 | |
787 | 788 | |
... | ... | @@ -803,20 +804,24 @@ |
803 | 804 | } |
804 | 805 | |
805 | 806 | /* Get the set of MTR[0-7] regs by each branch */ |
807 | + nr_pages = 0; | |
806 | 808 | for (slot = 0; slot < MAX_SLOTS; slot++) { |
807 | 809 | int where = mtr_regs[slot]; |
808 | 810 | for (branch = 0; branch < MAX_BRANCHES; branch++) { |
809 | 811 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], |
810 | 812 | where, |
811 | 813 | &pvt->mtr[slot][branch]); |
812 | - for (ch = 0; ch < MAX_BRANCHES; ch++) { | |
814 | + for (ch = 0; ch < MAX_CH_PER_BRANCH; ch++) { | |
813 | 815 | int channel = to_channel(ch, branch); |
814 | 816 | |
815 | 817 | dinfo = &pvt->dimm_info[slot][channel]; |
816 | 818 | p_csrow = &mci->csrows[slot]; |
817 | 819 | |
820 | + dimm = p_csrow->channels[branch * MAX_CH_PER_BRANCH + ch].dimm; | |
821 | + | |
818 | 822 | mtr = decode_mtr(pvt, slot, ch, branch, |
819 | - dinfo, p_csrow, &nr_pages); | |
823 | + dinfo, p_csrow, dimm, | |
824 | + &nr_pages); | |
820 | 825 | /* if no DIMMS on this row, continue */ |
821 | 826 | if (!MTR_DIMMS_PRESENT(mtr)) |
822 | 827 | continue; |
drivers/edac/i7core_edac.c
... | ... | @@ -592,7 +592,7 @@ |
592 | 592 | return 0; |
593 | 593 | } |
594 | 594 | |
595 | -static int get_dimm_config(const struct mem_ctl_info *mci) | |
595 | +static int get_dimm_config(struct mem_ctl_info *mci) | |
596 | 596 | { |
597 | 597 | struct i7core_pvt *pvt = mci->pvt_info; |
598 | 598 | struct csrow_info *csr; |
... | ... | @@ -602,6 +602,7 @@ |
602 | 602 | unsigned long last_page = 0; |
603 | 603 | enum edac_type mode; |
604 | 604 | enum mem_type mtype; |
605 | + struct dimm_info *dimm; | |
605 | 606 | |
606 | 607 | /* Get data from the MC register, function 0 */ |
607 | 608 | pdev = pvt->pci_mcr[0]; |
... | ... | @@ -721,7 +722,6 @@ |
721 | 722 | csr->nr_pages = npages; |
722 | 723 | |
723 | 724 | csr->page_mask = 0; |
724 | - csr->grain = 8; | |
725 | 725 | csr->csrow_idx = csrow; |
726 | 726 | csr->nr_channels = 1; |
727 | 727 | |
728 | 728 | |
729 | 729 | |
730 | 730 | |
731 | 731 | |
732 | 732 | |
... | ... | @@ -730,28 +730,27 @@ |
730 | 730 | |
731 | 731 | pvt->csrow_map[i][j] = csrow; |
732 | 732 | |
733 | + dimm = csr->channels[0].dimm; | |
733 | 734 | switch (banks) { |
734 | 735 | case 4: |
735 | - csr->dtype = DEV_X4; | |
736 | + dimm->dtype = DEV_X4; | |
736 | 737 | break; |
737 | 738 | case 8: |
738 | - csr->dtype = DEV_X8; | |
739 | + dimm->dtype = DEV_X8; | |
739 | 740 | break; |
740 | 741 | case 16: |
741 | - csr->dtype = DEV_X16; | |
742 | + dimm->dtype = DEV_X16; | |
742 | 743 | break; |
743 | 744 | default: |
744 | - csr->dtype = DEV_UNKNOWN; | |
745 | + dimm->dtype = DEV_UNKNOWN; | |
745 | 746 | } |
746 | 747 | |
747 | - csr->edac_mode = mode; | |
748 | - csr->mtype = mtype; | |
749 | - snprintf(csr->channels[0].dimm->label, | |
750 | - sizeof(csr->channels[0].dimm->label), | |
751 | - "CPU#%uChannel#%u_DIMM#%u", | |
752 | - pvt->i7core_dev->socket, i, j); | |
753 | - | |
754 | - csrow++; | |
748 | + snprintf(dimm->label, sizeof(dimm->label), | |
749 | + "CPU#%uChannel#%u_DIMM#%u", | |
750 | + pvt->i7core_dev->socket, i, j); | |
751 | + dimm->grain = 8; | |
752 | + dimm->edac_mode = mode; | |
753 | + dimm->mtype = mtype; | |
755 | 754 | } |
756 | 755 | |
757 | 756 | pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]); |
drivers/edac/i82443bxgx_edac.c
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | * 440GX fix by Jason Uhlenkott <juhlenko@akamai.com>. |
13 | 13 | * |
14 | 14 | * Written with reference to 82443BX Host Bridge Datasheet: |
15 | - * http://download.intel.com/design/chipsets/datashts/29063301.pdf | |
15 | + * http://download.intel.com/design/chipsets/datashts/29063301.pdf | |
16 | 16 | * references to this document given in []. |
17 | 17 | * |
18 | 18 | * This module doesn't support the 440LX, but it may be possible to |
... | ... | @@ -189,6 +189,7 @@ |
189 | 189 | enum mem_type mtype) |
190 | 190 | { |
191 | 191 | struct csrow_info *csrow; |
192 | + struct dimm_info *dimm; | |
192 | 193 | int index; |
193 | 194 | u8 drbar, dramc; |
194 | 195 | u32 row_base, row_high_limit, row_high_limit_last; |
... | ... | @@ -197,6 +198,8 @@ |
197 | 198 | row_high_limit_last = 0; |
198 | 199 | for (index = 0; index < mci->nr_csrows; index++) { |
199 | 200 | csrow = &mci->csrows[index]; |
201 | + dimm = csrow->channels[0].dimm; | |
202 | + | |
200 | 203 | pci_read_config_byte(pdev, I82443BXGX_DRB + index, &drbar); |
201 | 204 | debugf1("MC%d: %s: %s() Row=%d DRB = %#0x\n", |
202 | 205 | mci->mc_idx, __FILE__, __func__, index, drbar); |
203 | 206 | |
204 | 207 | |
... | ... | @@ -219,12 +222,12 @@ |
219 | 222 | csrow->last_page = (row_high_limit >> PAGE_SHIFT) - 1; |
220 | 223 | csrow->nr_pages = csrow->last_page - csrow->first_page + 1; |
221 | 224 | /* EAP reports in 4kilobyte granularity [61] */ |
222 | - csrow->grain = 1 << 12; | |
223 | - csrow->mtype = mtype; | |
225 | + dimm->grain = 1 << 12; | |
226 | + dimm->mtype = mtype; | |
224 | 227 | /* I don't think 440BX can tell you device type? FIXME? */ |
225 | - csrow->dtype = DEV_UNKNOWN; | |
228 | + dimm->dtype = DEV_UNKNOWN; | |
226 | 229 | /* Mode is global to all rows on 440BX */ |
227 | - csrow->edac_mode = edac_mode; | |
230 | + dimm->edac_mode = edac_mode; | |
228 | 231 | row_high_limit_last = row_high_limit; |
229 | 232 | } |
230 | 233 | } |
drivers/edac/i82860_edac.c
... | ... | @@ -140,6 +140,7 @@ |
140 | 140 | u16 value; |
141 | 141 | u32 cumul_size; |
142 | 142 | struct csrow_info *csrow; |
143 | + struct dimm_info *dimm; | |
143 | 144 | int index; |
144 | 145 | |
145 | 146 | pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim); |
... | ... | @@ -153,6 +154,8 @@ |
153 | 154 | */ |
154 | 155 | for (index = 0; index < mci->nr_csrows; index++) { |
155 | 156 | csrow = &mci->csrows[index]; |
157 | + dimm = csrow->channels[0].dimm; | |
158 | + | |
156 | 159 | pci_read_config_word(pdev, I82860_GBA + index * 2, &value); |
157 | 160 | cumul_size = (value & I82860_GBA_MASK) << |
158 | 161 | (I82860_GBA_SHIFT - PAGE_SHIFT); |
... | ... | @@ -166,10 +169,10 @@ |
166 | 169 | csrow->last_page = cumul_size - 1; |
167 | 170 | csrow->nr_pages = cumul_size - last_cumul_size; |
168 | 171 | last_cumul_size = cumul_size; |
169 | - csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ | |
170 | - csrow->mtype = MEM_RMBS; | |
171 | - csrow->dtype = DEV_UNKNOWN; | |
172 | - csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; | |
172 | + dimm->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ | |
173 | + dimm->mtype = MEM_RMBS; | |
174 | + dimm->dtype = DEV_UNKNOWN; | |
175 | + dimm->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; | |
173 | 176 | } |
174 | 177 | } |
175 | 178 |
drivers/edac/i82875p_edac.c
... | ... | @@ -342,11 +342,13 @@ |
342 | 342 | void __iomem * ovrfl_window, u32 drc) |
343 | 343 | { |
344 | 344 | struct csrow_info *csrow; |
345 | + struct dimm_info *dimm; | |
346 | + unsigned nr_chans = dual_channel_active(drc) + 1; | |
345 | 347 | unsigned long last_cumul_size; |
346 | 348 | u8 value; |
347 | 349 | u32 drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ |
348 | 350 | u32 cumul_size; |
349 | - int index; | |
351 | + int index, j; | |
350 | 352 | |
351 | 353 | drc_ddim = (drc >> 18) & 0x1; |
352 | 354 | last_cumul_size = 0; |
... | ... | @@ -371,10 +373,15 @@ |
371 | 373 | csrow->last_page = cumul_size - 1; |
372 | 374 | csrow->nr_pages = cumul_size - last_cumul_size; |
373 | 375 | last_cumul_size = cumul_size; |
374 | - csrow->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ | |
375 | - csrow->mtype = MEM_DDR; | |
376 | - csrow->dtype = DEV_UNKNOWN; | |
377 | - csrow->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE; | |
376 | + | |
377 | + for (j = 0; j < nr_chans; j++) { | |
378 | + dimm = csrow->channels[j].dimm; | |
379 | + | |
380 | + dimm->grain = 1 << 12; /* I82875P_EAP has 4KiB reolution */ | |
381 | + dimm->mtype = MEM_DDR; | |
382 | + dimm->dtype = DEV_UNKNOWN; | |
383 | + dimm->edac_mode = drc_ddim ? EDAC_SECDED : EDAC_NONE; | |
384 | + } | |
378 | 385 | } |
379 | 386 | } |
380 | 387 |
drivers/edac/i82975x_edac.c
... | ... | @@ -309,7 +309,7 @@ |
309 | 309 | chan = (mci->csrows[row].nr_channels == 1) ? 0 : info->eap & 1; |
310 | 310 | offst = info->eap |
311 | 311 | & ((1 << PAGE_SHIFT) - |
312 | - (1 << mci->csrows[row].grain)); | |
312 | + (1 << mci->csrows[row].channels[chan].dimm->grain)); | |
313 | 313 | |
314 | 314 | if (info->errsts & 0x0002) |
315 | 315 | edac_mc_handle_ue(mci, page, offst , row, "i82975x UE"); |
... | ... | @@ -372,6 +372,8 @@ |
372 | 372 | u8 value; |
373 | 373 | u32 cumul_size; |
374 | 374 | int index, chan; |
375 | + struct dimm_info *dimm; | |
376 | + enum dev_type dtype; | |
375 | 377 | |
376 | 378 | last_cumul_size = 0; |
377 | 379 | |
378 | 380 | |
... | ... | @@ -406,10 +408,17 @@ |
406 | 408 | * [0-7] for single-channel; i.e. csrow->nr_channels = 1 |
407 | 409 | * [0-3] for dual-channel; i.e. csrow->nr_channels = 2 |
408 | 410 | */ |
409 | - for (chan = 0; chan < csrow->nr_channels; chan++) | |
411 | + dtype = i82975x_dram_type(mch_window, index); | |
412 | + for (chan = 0; chan < csrow->nr_channels; chan++) { | |
413 | + dimm = mci->csrows[index].channels[chan].dimm; | |
410 | 414 | strncpy(csrow->channels[chan].dimm->label, |
411 | 415 | labels[(index >> 1) + (chan * 2)], |
412 | 416 | EDAC_MC_LABEL_LEN); |
417 | + dimm->grain = 1 << 7; /* 128Byte cache-line resolution */ | |
418 | + dimm->dtype = i82975x_dram_type(mch_window, index); | |
419 | + dimm->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ | |
420 | + dimm->edac_mode = EDAC_SECDED; /* only supported */ | |
421 | + } | |
413 | 422 | |
414 | 423 | if (cumul_size == last_cumul_size) |
415 | 424 | continue; /* not populated */ |
... | ... | @@ -418,10 +427,6 @@ |
418 | 427 | csrow->last_page = cumul_size - 1; |
419 | 428 | csrow->nr_pages = cumul_size - last_cumul_size; |
420 | 429 | last_cumul_size = cumul_size; |
421 | - csrow->grain = 1 << 7; /* 128Byte cache-line resolution */ | |
422 | - csrow->mtype = MEM_DDR2; /* I82975x supports only DDR2 */ | |
423 | - csrow->dtype = i82975x_dram_type(mch_window, index); | |
424 | - csrow->edac_mode = EDAC_SECDED; /* only supported */ | |
425 | 430 | } |
426 | 431 | } |
427 | 432 |
drivers/edac/mpc85xx_edac.c
... | ... | @@ -883,6 +883,7 @@ |
883 | 883 | { |
884 | 884 | struct mpc85xx_mc_pdata *pdata = mci->pvt_info; |
885 | 885 | struct csrow_info *csrow; |
886 | + struct dimm_info *dimm; | |
886 | 887 | u32 sdram_ctl; |
887 | 888 | u32 sdtype; |
888 | 889 | enum mem_type mtype; |
... | ... | @@ -929,6 +930,8 @@ |
929 | 930 | u32 end; |
930 | 931 | |
931 | 932 | csrow = &mci->csrows[index]; |
933 | + dimm = csrow->channels[0].dimm; | |
934 | + | |
932 | 935 | cs_bnds = in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 + |
933 | 936 | (index * MPC85XX_MC_CS_BNDS_OFS)); |
934 | 937 | |
935 | 938 | |
... | ... | @@ -945,12 +948,12 @@ |
945 | 948 | csrow->first_page = start; |
946 | 949 | csrow->last_page = end; |
947 | 950 | csrow->nr_pages = end + 1 - start; |
948 | - csrow->grain = 8; | |
949 | - csrow->mtype = mtype; | |
950 | - csrow->dtype = DEV_UNKNOWN; | |
951 | + dimm->grain = 8; | |
952 | + dimm->mtype = mtype; | |
953 | + dimm->dtype = DEV_UNKNOWN; | |
951 | 954 | if (sdram_ctl & DSC_X32_EN) |
952 | - csrow->dtype = DEV_X32; | |
953 | - csrow->edac_mode = EDAC_SECDED; | |
955 | + dimm->dtype = DEV_X32; | |
956 | + dimm->edac_mode = EDAC_SECDED; | |
954 | 957 | } |
955 | 958 | } |
956 | 959 |
drivers/edac/mv64x60_edac.c
... | ... | @@ -656,6 +656,8 @@ |
656 | 656 | struct mv64x60_mc_pdata *pdata) |
657 | 657 | { |
658 | 658 | struct csrow_info *csrow; |
659 | + struct dimm_info *dimm; | |
660 | + | |
659 | 661 | u32 devtype; |
660 | 662 | u32 ctl; |
661 | 663 | |
662 | 664 | |
663 | 665 | |
664 | 666 | |
665 | 667 | |
666 | 668 | |
667 | 669 | |
668 | 670 | |
... | ... | @@ -664,30 +666,30 @@ |
664 | 666 | ctl = in_le32(pdata->mc_vbase + MV64X60_SDRAM_CONFIG); |
665 | 667 | |
666 | 668 | csrow = &mci->csrows[0]; |
667 | - csrow->first_page = 0; | |
669 | + dimm = csrow->channels[0].dimm; | |
668 | 670 | csrow->nr_pages = pdata->total_mem >> PAGE_SHIFT; |
669 | 671 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
670 | - csrow->grain = 8; | |
672 | + dimm->grain = 8; | |
671 | 673 | |
672 | - csrow->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR; | |
674 | + dimm->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR; | |
673 | 675 | |
674 | 676 | devtype = (ctl >> 20) & 0x3; |
675 | 677 | switch (devtype) { |
676 | 678 | case 0x0: |
677 | - csrow->dtype = DEV_X32; | |
679 | + dimm->dtype = DEV_X32; | |
678 | 680 | break; |
679 | 681 | case 0x2: /* could be X8 too, but no way to tell */ |
680 | - csrow->dtype = DEV_X16; | |
682 | + dimm->dtype = DEV_X16; | |
681 | 683 | break; |
682 | 684 | case 0x3: |
683 | - csrow->dtype = DEV_X4; | |
685 | + dimm->dtype = DEV_X4; | |
684 | 686 | break; |
685 | 687 | default: |
686 | - csrow->dtype = DEV_UNKNOWN; | |
688 | + dimm->dtype = DEV_UNKNOWN; | |
687 | 689 | break; |
688 | 690 | } |
689 | 691 | |
690 | - csrow->edac_mode = EDAC_SECDED; | |
692 | + dimm->edac_mode = EDAC_SECDED; | |
691 | 693 | } |
692 | 694 | |
693 | 695 | static int __devinit mv64x60_mc_err_probe(struct platform_device *pdev) |
drivers/edac/pasemi_edac.c
... | ... | @@ -135,11 +135,13 @@ |
135 | 135 | enum edac_type edac_mode) |
136 | 136 | { |
137 | 137 | struct csrow_info *csrow; |
138 | + struct dimm_info *dimm; | |
138 | 139 | u32 rankcfg; |
139 | 140 | int index; |
140 | 141 | |
141 | 142 | for (index = 0; index < mci->nr_csrows; index++) { |
142 | 143 | csrow = &mci->csrows[index]; |
144 | + dimm = csrow->channels[0].dimm; | |
143 | 145 | |
144 | 146 | pci_read_config_dword(pdev, |
145 | 147 | MCDRAM_RANKCFG + (index * 12), |
... | ... | @@ -177,10 +179,10 @@ |
177 | 179 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
178 | 180 | last_page_in_mmc += csrow->nr_pages; |
179 | 181 | csrow->page_mask = 0; |
180 | - csrow->grain = PASEMI_EDAC_ERROR_GRAIN; | |
181 | - csrow->mtype = MEM_DDR; | |
182 | - csrow->dtype = DEV_UNKNOWN; | |
183 | - csrow->edac_mode = edac_mode; | |
182 | + dimm->grain = PASEMI_EDAC_ERROR_GRAIN; | |
183 | + dimm->mtype = MEM_DDR; | |
184 | + dimm->dtype = DEV_UNKNOWN; | |
185 | + dimm->edac_mode = edac_mode; | |
184 | 186 | } |
185 | 187 | return 0; |
186 | 188 | } |
drivers/edac/ppc4xx_edac.c
... | ... | @@ -895,7 +895,7 @@ |
895 | 895 | enum mem_type mtype; |
896 | 896 | enum dev_type dtype; |
897 | 897 | enum edac_type edac_mode; |
898 | - int row; | |
898 | + int row, j; | |
899 | 899 | u32 mbxcf, size; |
900 | 900 | static u32 ppc4xx_last_page; |
901 | 901 | |
902 | 902 | |
903 | 903 | |
904 | 904 | |
905 | 905 | |
... | ... | @@ -975,15 +975,18 @@ |
975 | 975 | * possible values would be the PLB width (16), the |
976 | 976 | * page size (PAGE_SIZE) or the memory width (2 or 4). |
977 | 977 | */ |
978 | + for (j = 0; j < csi->nr_channels; j++) { | |
979 | + struct dimm_info *dimm = csi->channels[j].dimm; | |
978 | 980 | |
979 | - csi->grain = 1; | |
981 | + dimm->grain = 1; | |
980 | 982 | |
981 | - csi->mtype = mtype; | |
982 | - csi->dtype = dtype; | |
983 | + dimm->mtype = mtype; | |
984 | + dimm->dtype = dtype; | |
983 | 985 | |
984 | - csi->edac_mode = edac_mode; | |
986 | + dimm->edac_mode = edac_mode; | |
985 | 987 | |
986 | 988 | ppc4xx_last_page += csi->nr_pages; |
989 | + } | |
987 | 990 | } |
988 | 991 | |
989 | 992 | done: |
drivers/edac/r82600_edac.c
... | ... | @@ -216,6 +216,7 @@ |
216 | 216 | u8 dramcr) |
217 | 217 | { |
218 | 218 | struct csrow_info *csrow; |
219 | + struct dimm_info *dimm; | |
219 | 220 | int index; |
220 | 221 | u8 drbar; /* SDRAM Row Boundary Address Register */ |
221 | 222 | u32 row_high_limit, row_high_limit_last; |
... | ... | @@ -227,6 +228,7 @@ |
227 | 228 | |
228 | 229 | for (index = 0; index < mci->nr_csrows; index++) { |
229 | 230 | csrow = &mci->csrows[index]; |
231 | + dimm = csrow->channels[0].dimm; | |
230 | 232 | |
231 | 233 | /* find the DRAM Chip Select Base address and mask */ |
232 | 234 | pci_read_config_byte(pdev, R82600_DRBA + index, &drbar); |
233 | 235 | |
234 | 236 | |
... | ... | @@ -250,13 +252,13 @@ |
250 | 252 | csrow->nr_pages = csrow->last_page - csrow->first_page + 1; |
251 | 253 | /* Error address is top 19 bits - so granularity is * |
252 | 254 | * 14 bits */ |
253 | - csrow->grain = 1 << 14; | |
254 | - csrow->mtype = reg_sdram ? MEM_RDDR : MEM_DDR; | |
255 | + dimm->grain = 1 << 14; | |
256 | + dimm->mtype = reg_sdram ? MEM_RDDR : MEM_DDR; | |
255 | 257 | /* FIXME - check that this is unknowable with this chipset */ |
256 | - csrow->dtype = DEV_UNKNOWN; | |
258 | + dimm->dtype = DEV_UNKNOWN; | |
257 | 259 | |
258 | 260 | /* Mode is global on 82600 */ |
259 | - csrow->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE; | |
261 | + dimm->edac_mode = ecc_on ? EDAC_SECDED : EDAC_NONE; | |
260 | 262 | row_high_limit_last = row_high_limit; |
261 | 263 | } |
262 | 264 | } |
drivers/edac/sb_edac.c
... | ... | @@ -551,7 +551,7 @@ |
551 | 551 | return 0; |
552 | 552 | } |
553 | 553 | |
554 | -static int get_dimm_config(const struct mem_ctl_info *mci) | |
554 | +static int get_dimm_config(struct mem_ctl_info *mci) | |
555 | 555 | { |
556 | 556 | struct sbridge_pvt *pvt = mci->pvt_info; |
557 | 557 | struct csrow_info *csr; |
... | ... | @@ -561,6 +561,7 @@ |
561 | 561 | u32 reg; |
562 | 562 | enum edac_type mode; |
563 | 563 | enum mem_type mtype; |
564 | + struct dimm_info *dimm; | |
564 | 565 | |
565 | 566 | pci_read_config_dword(pvt->pci_br, SAD_TARGET, ®); |
566 | 567 | pvt->sbridge_dev->source_id = SOURCE_ID(reg); |
... | ... | @@ -612,6 +613,7 @@ |
612 | 613 | /* On all supported DDR3 DIMM types, there are 8 banks available */ |
613 | 614 | banks = 8; |
614 | 615 | |
616 | + dimm = mci->dimms; | |
615 | 617 | for (i = 0; i < NUM_CHANNELS; i++) { |
616 | 618 | u32 mtr; |
617 | 619 | |
618 | 620 | |
619 | 621 | |
620 | 622 | |
621 | 623 | |
622 | 624 | |
623 | 625 | |
624 | 626 | |
... | ... | @@ -634,29 +636,30 @@ |
634 | 636 | pvt->sbridge_dev->mc, i, j, |
635 | 637 | size, npages, |
636 | 638 | banks, ranks, rows, cols); |
637 | - csr = &mci->csrows[csrow]; | |
638 | 639 | |
640 | + /* | |
641 | + * Fake stuff. This controller doesn't see | |
642 | + * csrows. | |
643 | + */ | |
644 | + csr = &mci->csrows[csrow]; | |
639 | 645 | csr->first_page = last_page; |
640 | 646 | csr->last_page = last_page + npages - 1; |
641 | - csr->page_mask = 0UL; /* Unused */ | |
642 | 647 | csr->nr_pages = npages; |
643 | - csr->grain = 32; | |
644 | 648 | csr->csrow_idx = csrow; |
645 | - csr->dtype = (banks == 8) ? DEV_X8 : DEV_X4; | |
646 | - csr->ce_count = 0; | |
647 | - csr->ue_count = 0; | |
648 | - csr->mtype = mtype; | |
649 | - csr->edac_mode = mode; | |
650 | 649 | csr->nr_channels = 1; |
651 | 650 | csr->channels[0].chan_idx = i; |
652 | - csr->channels[0].ce_count = 0; | |
653 | 651 | pvt->csrow_map[i][j] = csrow; |
654 | - snprintf(csr->channels[0].dimm->label, | |
655 | - sizeof(csr->channels[0].dimm->label), | |
656 | - "CPU_SrcID#%u_Channel#%u_DIMM#%u", | |
657 | - pvt->sbridge_dev->source_id, i, j); | |
658 | 652 | last_page += npages; |
659 | 653 | csrow++; |
654 | + | |
655 | + csr->channels[0].dimm = dimm; | |
656 | + dimm->grain = 32; | |
657 | + dimm->dtype = (banks == 8) ? DEV_X8 : DEV_X4; | |
658 | + dimm->mtype = mtype; | |
659 | + dimm->edac_mode = mode; | |
660 | + snprintf(dimm->label, sizeof(dimm->label), | |
661 | + "CPU_SrcID#%u_Channel#%u_DIMM#%u", | |
662 | + pvt->sbridge_dev->source_id, i, j); | |
660 | 663 | } |
661 | 664 | } |
662 | 665 | } |
drivers/edac/tile_edac.c
... | ... | @@ -84,6 +84,7 @@ |
84 | 84 | struct csrow_info *csrow = &mci->csrows[0]; |
85 | 85 | struct tile_edac_priv *priv = mci->pvt_info; |
86 | 86 | struct mshim_mem_info mem_info; |
87 | + struct dimm_info *dimm = csrow->channels[0].dimm; | |
87 | 88 | |
88 | 89 | if (hv_dev_pread(priv->hv_devhdl, 0, (HV_VirtAddr)&mem_info, |
89 | 90 | sizeof(struct mshim_mem_info), MSHIM_MEM_INFO_OFF) != |
90 | 91 | |
91 | 92 | |
92 | 93 | |
... | ... | @@ -93,16 +94,16 @@ |
93 | 94 | } |
94 | 95 | |
95 | 96 | if (mem_info.mem_ecc) |
96 | - csrow->edac_mode = EDAC_SECDED; | |
97 | + dimm->edac_mode = EDAC_SECDED; | |
97 | 98 | else |
98 | - csrow->edac_mode = EDAC_NONE; | |
99 | + dimm->edac_mode = EDAC_NONE; | |
99 | 100 | switch (mem_info.mem_type) { |
100 | 101 | case DDR2: |
101 | - csrow->mtype = MEM_DDR2; | |
102 | + dimm->mtype = MEM_DDR2; | |
102 | 103 | break; |
103 | 104 | |
104 | 105 | case DDR3: |
105 | - csrow->mtype = MEM_DDR3; | |
106 | + dimm->mtype = MEM_DDR3; | |
106 | 107 | break; |
107 | 108 | |
108 | 109 | default: |
... | ... | @@ -112,8 +113,8 @@ |
112 | 113 | csrow->first_page = 0; |
113 | 114 | csrow->nr_pages = mem_info.mem_size >> PAGE_SHIFT; |
114 | 115 | csrow->last_page = csrow->first_page + csrow->nr_pages - 1; |
115 | - csrow->grain = TILE_EDAC_ERROR_GRAIN; | |
116 | - csrow->dtype = DEV_UNKNOWN; | |
116 | + dimm->grain = TILE_EDAC_ERROR_GRAIN; | |
117 | + dimm->dtype = DEV_UNKNOWN; | |
117 | 118 | |
118 | 119 | return 0; |
119 | 120 | } |
drivers/edac/x38_edac.c
... | ... | @@ -317,7 +317,7 @@ |
317 | 317 | static int x38_probe1(struct pci_dev *pdev, int dev_idx) |
318 | 318 | { |
319 | 319 | int rc; |
320 | - int i; | |
320 | + int i, j; | |
321 | 321 | struct mem_ctl_info *mci = NULL; |
322 | 322 | unsigned long last_page; |
323 | 323 | u16 drbs[X38_CHANNELS][X38_RANKS_PER_CHANNEL]; |
324 | 324 | |
325 | 325 | |
... | ... | @@ -372,20 +372,21 @@ |
372 | 372 | i / X38_RANKS_PER_CHANNEL, |
373 | 373 | i % X38_RANKS_PER_CHANNEL); |
374 | 374 | |
375 | - if (nr_pages == 0) { | |
376 | - csrow->mtype = MEM_EMPTY; | |
375 | + if (nr_pages == 0) | |
377 | 376 | continue; |
378 | - } | |
379 | 377 | |
380 | 378 | csrow->first_page = last_page + 1; |
381 | 379 | last_page += nr_pages; |
382 | 380 | csrow->last_page = last_page; |
383 | 381 | csrow->nr_pages = nr_pages; |
384 | 382 | |
385 | - csrow->grain = nr_pages << PAGE_SHIFT; | |
386 | - csrow->mtype = MEM_DDR2; | |
387 | - csrow->dtype = DEV_UNKNOWN; | |
388 | - csrow->edac_mode = EDAC_UNKNOWN; | |
383 | + for (j = 0; j < x38_channel_num; j++) { | |
384 | + struct dimm_info *dimm = csrow->channels[j].dimm; | |
385 | + dimm->grain = nr_pages << PAGE_SHIFT; | |
386 | + dimm->mtype = MEM_DDR2; | |
387 | + dimm->dtype = DEV_UNKNOWN; | |
388 | + dimm->edac_mode = EDAC_UNKNOWN; | |
389 | + } | |
389 | 390 | } |
390 | 391 | |
391 | 392 | x38_clear_error_info(mci); |
include/linux/edac.h
... | ... | @@ -318,6 +318,13 @@ |
318 | 318 | unsigned memory_controller; |
319 | 319 | unsigned csrow; |
320 | 320 | unsigned csrow_channel; |
321 | + | |
322 | + u32 grain; /* granularity of reported error in bytes */ | |
323 | + enum dev_type dtype; /* memory device type */ | |
324 | + enum mem_type mtype; /* memory dimm type */ | |
325 | + enum edac_type edac_mode; /* EDAC mode for this dimm */ | |
326 | + | |
327 | + u32 ce_count; /* Correctable Errors for this dimm */ | |
321 | 328 | }; |
322 | 329 | |
323 | 330 | /** |
324 | 331 | |
325 | 332 | |
... | ... | @@ -343,19 +350,17 @@ |
343 | 350 | }; |
344 | 351 | |
345 | 352 | struct csrow_info { |
346 | - unsigned long first_page; /* first page number in dimm */ | |
347 | - unsigned long last_page; /* last page number in dimm */ | |
353 | + unsigned long first_page; /* first page number in csrow */ | |
354 | + unsigned long last_page; /* last page number in csrow */ | |
355 | + u32 nr_pages; /* number of pages in csrow */ | |
348 | 356 | unsigned long page_mask; /* used for interleaving - |
349 | 357 | * 0UL for non intlv |
350 | 358 | */ |
351 | - u32 nr_pages; /* number of pages in csrow */ | |
352 | - u32 grain; /* granularity of reported error in bytes */ | |
353 | - int csrow_idx; /* the chip-select row */ | |
354 | - enum dev_type dtype; /* memory device type */ | |
359 | + int csrow_idx; /* the chip-select row */ | |
360 | + | |
355 | 361 | u32 ue_count; /* Uncorrectable Errors for this csrow */ |
356 | 362 | u32 ce_count; /* Correctable Errors for this csrow */ |
357 | - enum mem_type mtype; /* memory csrow type */ | |
358 | - enum edac_type edac_mode; /* EDAC mode for this csrow */ | |
363 | + | |
359 | 364 | struct mem_ctl_info *mci; /* the parent */ |
360 | 365 | |
361 | 366 | struct kobject kobj; /* sysfs kobject for this csrow */ |