aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Grondona <mgrondona@llnl.gov>2007-07-19 04:50:23 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-19 13:04:56 -0400
commit7297c2617f6465d7862e156d4db5d812744280f1 (patch)
treef055b3d9b3fb7e35cec15e46689954dd049fbbfc
parent0ca84761faeb9d49301d45b39859411c7a124690 (diff)
drivers/edac: fix e752x reversed csrows
Found a 'reversal' decoding bug in the driver. This patch fixes that mapping to correctly display the CSROW entries in their proper order. Users will be enable to correctly identifiy the failing DIMM with this fix. [akpm@linux-foundation.org: unneeded (and undesirable) cast of void*] Cc: Alan Cox alan@lxorguk.ukuu.org.uk Signed-off-by: Mark Grondona <mgrondona@llnl.gov> Signed-off-by: Doug Thompson <dougthompson@xmission.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/edac/e752x_edac.c34
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
index a041218370f9..f5168a593e93 100644
--- a/drivers/edac/e752x_edac.c
+++ b/drivers/edac/e752x_edac.c
@@ -284,9 +284,6 @@ static void do_process_ce(struct mem_ctl_info *mci, u16 error_one,
284 /* 0 = channel A, 1 = channel B */ 284 /* 0 = channel A, 1 = channel B */
285 channel = !(error_one & 1); 285 channel = !(error_one & 1);
286 286
287 if (!pvt->map_type)
288 row = 7 - row;
289
290 /* e752x mc reads 34:6 of the DRAM linear address */ 287 /* e752x mc reads 34:6 of the DRAM linear address */
291 edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4), 288 edac_mc_handle_ce(mci, page, offset_in_page(sec1_add << 4),
292 sec1_syndrome, row, channel, "e752x CE"); 289 sec1_syndrome, row, channel, "e752x CE");
@@ -774,6 +771,18 @@ static inline int dual_channel_active(u16 ddrcsr)
774 return (((ddrcsr >> 12) & 3) == 3); 771 return (((ddrcsr >> 12) & 3) == 3);
775} 772}
776 773
774/* Remap csrow index numbers if map_type is "reverse"
775 */
776static inline int remap_csrow_index(struct mem_ctl_info *mci, int index)
777{
778 struct e752x_pvt *pvt = mci->pvt_info;
779
780 if (!pvt->map_type)
781 return (7 - index);
782
783 return (index);
784}
785
777static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, 786static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
778 u16 ddrcsr) 787 u16 ddrcsr)
779{ 788{
@@ -804,7 +813,7 @@ static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
804 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { 813 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
805 /* mem_dev 0=x8, 1=x4 */ 814 /* mem_dev 0=x8, 1=x4 */
806 mem_dev = (dra >> (index * 4 + 2)) & 0x3; 815 mem_dev = (dra >> (index * 4 + 2)) & 0x3;
807 csrow = &mci->csrows[index]; 816 csrow = &mci->csrows[remap_csrow_index(mci, index)];
808 817
809 mem_dev = (mem_dev == 2); 818 mem_dev = (mem_dev == 2);
810 pci_read_config_byte(pdev, E752X_DRB + index, &value); 819 pci_read_config_byte(pdev, E752X_DRB + index, &value);
@@ -844,7 +853,7 @@ static void e752x_init_mem_map_table(struct pci_dev *pdev,
844 struct e752x_pvt *pvt) 853 struct e752x_pvt *pvt)
845{ 854{
846 int index; 855 int index;
847 u8 value, last, row, stat8; 856 u8 value, last, row;
848 857
849 last = 0; 858 last = 0;
850 row = 0; 859 row = 0;
@@ -873,10 +882,6 @@ static void e752x_init_mem_map_table(struct pci_dev *pdev,
873 last = value; 882 last = value;
874 } 883 }
875 } 884 }
876
877 /* set the map type. 1 = normal, 0 = reversed */
878 pci_read_config_byte(pdev, E752X_DRM, &stat8);
879 pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
880} 885}
881 886
882/* Return 0 on success or 1 on failure. */ 887/* Return 0 on success or 1 on failure. */
@@ -1003,13 +1008,16 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
1003 mci->edac_check = e752x_check; 1008 mci->edac_check = e752x_check;
1004 mci->ctl_page_to_phys = ctl_page_to_phys; 1009 mci->ctl_page_to_phys = ctl_page_to_phys;
1005 1010
1006 e752x_init_csrows(mci, pdev, ddrcsr); 1011 /* set the map type. 1 = normal, 0 = reversed
1007 e752x_init_mem_map_table(pdev, pvt); 1012 * Must be set before e752x_init_csrows in case csrow mapping
1008 1013 * is reversed.
1009 /* set the map type. 1 = normal, 0 = reversed */ 1014 */
1010 pci_read_config_byte(pdev, E752X_DRM, &stat8); 1015 pci_read_config_byte(pdev, E752X_DRM, &stat8);
1011 pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f)); 1016 pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
1012 1017
1018 e752x_init_csrows(mci, pdev, ddrcsr);
1019 e752x_init_mem_map_table(pdev, pvt);
1020
1013 mci->edac_cap |= EDAC_FLAG_NONE; 1021 mci->edac_cap |= EDAC_FLAG_NONE;
1014 debugf3("%s(): tolm, remapbase, remaplimit\n", __func__); 1022 debugf3("%s(): tolm, remapbase, remaplimit\n", __func__);
1015 1023