diff options
author | Mark Grondona <mgrondona@llnl.gov> | 2007-07-19 04:50:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-19 13:04:56 -0400 |
commit | 7297c2617f6465d7862e156d4db5d812744280f1 (patch) | |
tree | f055b3d9b3fb7e35cec15e46689954dd049fbbfc | |
parent | 0ca84761faeb9d49301d45b39859411c7a124690 (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.c | 34 |
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 | */ | ||
776 | static 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 | |||
777 | static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev, | 786 | static 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 | ||