edac_mc.c (a7d7d2e1a07e3811dc49af2962c940fd8bbb6c8f) | edac_mc.c (084a4fccef39ac7abb039511f32380f28d0b67e6) |
---|---|
1/* 2 * edac_mc kernel module 3 * (C) 2005, 2006 Linux Networx (http://lnxi.com) 4 * This file may be distributed under the terms of the 5 * GNU General Public License. 6 * 7 * Written by Thayne Harbaugh 8 * Based on work by Dan Hollis <goemon at anime dot net> and others. --- 29 unchanged lines hidden (view full) --- 38static LIST_HEAD(mc_devices); 39 40#ifdef CONFIG_EDAC_DEBUG 41 42static void edac_mc_dump_channel(struct rank_info *chan) 43{ 44 debugf4("\tchannel = %p\n", chan); 45 debugf4("\tchannel->chan_idx = %d\n", chan->chan_idx); | 1/* 2 * edac_mc kernel module 3 * (C) 2005, 2006 Linux Networx (http://lnxi.com) 4 * This file may be distributed under the terms of the 5 * GNU General Public License. 6 * 7 * Written by Thayne Harbaugh 8 * Based on work by Dan Hollis <goemon at anime dot net> and others. --- 29 unchanged lines hidden (view full) --- 38static LIST_HEAD(mc_devices); 39 40#ifdef CONFIG_EDAC_DEBUG 41 42static void edac_mc_dump_channel(struct rank_info *chan) 43{ 44 debugf4("\tchannel = %p\n", chan); 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 debugf4("\tchannel->label = '%s'\n", chan->dimm->label); 48 debugf4("\tchannel->csrow = %p\n\n", chan->csrow); 49} 50 51static void edac_mc_dump_csrow(struct csrow_info *csrow) 52{ 53 debugf4("\tcsrow = %p\n", csrow); 54 debugf4("\tcsrow->csrow_idx = %d\n", csrow->csrow_idx); --- 635 unchanged lines hidden (view full) --- 690/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ 691void edac_mc_handle_ce(struct mem_ctl_info *mci, 692 unsigned long page_frame_number, 693 unsigned long offset_in_page, unsigned long syndrome, 694 int row, int channel, const char *msg) 695{ 696 unsigned long remapped_page; 697 char *label = NULL; | 47 debugf4("\tchannel->label = '%s'\n", chan->dimm->label); 48 debugf4("\tchannel->csrow = %p\n\n", chan->csrow); 49} 50 51static void edac_mc_dump_csrow(struct csrow_info *csrow) 52{ 53 debugf4("\tcsrow = %p\n", csrow); 54 debugf4("\tcsrow->csrow_idx = %d\n", csrow->csrow_idx); --- 635 unchanged lines hidden (view full) --- 690/* FIXME - integrate with evlog: http://evlog.sourceforge.net/ */ 691void edac_mc_handle_ce(struct mem_ctl_info *mci, 692 unsigned long page_frame_number, 693 unsigned long offset_in_page, unsigned long syndrome, 694 int row, int channel, const char *msg) 695{ 696 unsigned long remapped_page; 697 char *label = NULL; |
698 u32 grain; |
|
698 699 debugf3("MC%d: %s()\n", mci->mc_idx, __func__); 700 701 /* FIXME - maybe make panic on INTERNAL ERROR an option */ 702 if (row >= mci->nr_csrows || row < 0) { 703 /* something is wrong */ 704 edac_mc_printk(mci, KERN_ERR, 705 "INTERNAL ERROR: row out of range " --- 8 unchanged lines hidden (view full) --- 714 "INTERNAL ERROR: channel out of range " 715 "(%d >= %d)\n", channel, 716 mci->csrows[row].nr_channels); 717 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); 718 return; 719 } 720 721 label = mci->csrows[row].channels[channel].dimm->label; | 699 700 debugf3("MC%d: %s()\n", mci->mc_idx, __func__); 701 702 /* FIXME - maybe make panic on INTERNAL ERROR an option */ 703 if (row >= mci->nr_csrows || row < 0) { 704 /* something is wrong */ 705 edac_mc_printk(mci, KERN_ERR, 706 "INTERNAL ERROR: row out of range " --- 8 unchanged lines hidden (view full) --- 715 "INTERNAL ERROR: channel out of range " 716 "(%d >= %d)\n", channel, 717 mci->csrows[row].nr_channels); 718 edac_mc_handle_ce_no_info(mci, "INTERNAL ERROR"); 719 return; 720 } 721 722 label = mci->csrows[row].channels[channel].dimm->label; |
723 grain = mci->csrows[row].channels[channel].dimm->grain; |
|
722 723 if (edac_mc_get_log_ce()) 724 /* FIXME - put in DIMM location */ 725 edac_mc_printk(mci, KERN_WARNING, 726 "CE page 0x%lx, offset 0x%lx, grain %d, syndrome " 727 "0x%lx, row %d, channel %d, label \"%s\": %s\n", 728 page_frame_number, offset_in_page, | 724 725 if (edac_mc_get_log_ce()) 726 /* FIXME - put in DIMM location */ 727 edac_mc_printk(mci, KERN_WARNING, 728 "CE page 0x%lx, offset 0x%lx, grain %d, syndrome " 729 "0x%lx, row %d, channel %d, label \"%s\": %s\n", 730 page_frame_number, offset_in_page, |
729 mci->csrows[row].grain, syndrome, row, channel, | 731 grain, syndrome, row, channel, |
730 label, msg); 731 732 mci->ce_count++; 733 mci->csrows[row].ce_count++; | 732 label, msg); 733 734 mci->ce_count++; 735 mci->csrows[row].ce_count++; |
736 mci->csrows[row].channels[channel].dimm->ce_count++; |
|
734 mci->csrows[row].channels[channel].ce_count++; 735 736 if (mci->scrub_mode & SCRUB_SW_SRC) { 737 /* 738 * Some MC's can remap memory so that it is still available 739 * at a different address when PCI devices map into memory. 740 * MC's that can't do this lose the memory where PCI devices 741 * are mapped. This mapping is MC dependent and so we call 742 * back into the MC driver for it to map the MC page to 743 * a physical (CPU) page which can then be mapped to a virtual 744 * page - which can then be scrubbed. 745 */ 746 remapped_page = mci->ctl_page_to_phys ? 747 mci->ctl_page_to_phys(mci, page_frame_number) : 748 page_frame_number; 749 | 737 mci->csrows[row].channels[channel].ce_count++; 738 739 if (mci->scrub_mode & SCRUB_SW_SRC) { 740 /* 741 * Some MC's can remap memory so that it is still available 742 * at a different address when PCI devices map into memory. 743 * MC's that can't do this lose the memory where PCI devices 744 * are mapped. This mapping is MC dependent and so we call 745 * back into the MC driver for it to map the MC page to 746 * a physical (CPU) page which can then be mapped to a virtual 747 * page - which can then be scrubbed. 748 */ 749 remapped_page = mci->ctl_page_to_phys ? 750 mci->ctl_page_to_phys(mci, page_frame_number) : 751 page_frame_number; 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 } 753} 754EXPORT_SYMBOL_GPL(edac_mc_handle_ce); 755 756void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) 757{ 758 if (edac_mc_get_log_ce()) 759 edac_mc_printk(mci, KERN_WARNING, --- 9 unchanged lines hidden (view full) --- 769 unsigned long offset_in_page, int row, const char *msg) 770{ 771 int len = EDAC_MC_LABEL_LEN * 4; 772 char labels[len + 1]; 773 char *pos = labels; 774 int chan; 775 int chars; 776 char *label = NULL; | 754 } 755} 756EXPORT_SYMBOL_GPL(edac_mc_handle_ce); 757 758void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, const char *msg) 759{ 760 if (edac_mc_get_log_ce()) 761 edac_mc_printk(mci, KERN_WARNING, --- 9 unchanged lines hidden (view full) --- 771 unsigned long offset_in_page, int row, const char *msg) 772{ 773 int len = EDAC_MC_LABEL_LEN * 4; 774 char labels[len + 1]; 775 char *pos = labels; 776 int chan; 777 int chars; 778 char *label = NULL; |
779 u32 grain; |
|
777 778 debugf3("MC%d: %s()\n", mci->mc_idx, __func__); 779 780 /* FIXME - maybe make panic on INTERNAL ERROR an option */ 781 if (row >= mci->nr_csrows || row < 0) { 782 /* something is wrong */ 783 edac_mc_printk(mci, KERN_ERR, 784 "INTERNAL ERROR: row out of range " 785 "(%d >= %d)\n", row, mci->nr_csrows); 786 edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR"); 787 return; 788 } 789 | 780 781 debugf3("MC%d: %s()\n", mci->mc_idx, __func__); 782 783 /* FIXME - maybe make panic on INTERNAL ERROR an option */ 784 if (row >= mci->nr_csrows || row < 0) { 785 /* something is wrong */ 786 edac_mc_printk(mci, KERN_ERR, 787 "INTERNAL ERROR: row out of range " 788 "(%d >= %d)\n", row, mci->nr_csrows); 789 edac_mc_handle_ue_no_info(mci, "INTERNAL ERROR"); 790 return; 791 } 792 |
793 grain = mci->csrows[row].channels[0].dimm->grain; |
|
790 label = mci->csrows[row].channels[0].dimm->label; 791 chars = snprintf(pos, len + 1, "%s", label); 792 len -= chars; 793 pos += chars; 794 795 for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0); 796 chan++) { 797 label = mci->csrows[row].channels[chan].dimm->label; 798 chars = snprintf(pos, len + 1, ":%s", label); 799 len -= chars; 800 pos += chars; 801 } 802 803 if (edac_mc_get_log_ue()) 804 edac_mc_printk(mci, KERN_EMERG, 805 "UE page 0x%lx, offset 0x%lx, grain %d, row %d, " 806 "labels \"%s\": %s\n", page_frame_number, | 794 label = mci->csrows[row].channels[0].dimm->label; 795 chars = snprintf(pos, len + 1, "%s", label); 796 len -= chars; 797 pos += chars; 798 799 for (chan = 1; (chan < mci->csrows[row].nr_channels) && (len > 0); 800 chan++) { 801 label = mci->csrows[row].channels[chan].dimm->label; 802 chars = snprintf(pos, len + 1, ":%s", label); 803 len -= chars; 804 pos += chars; 805 } 806 807 if (edac_mc_get_log_ue()) 808 edac_mc_printk(mci, KERN_EMERG, 809 "UE page 0x%lx, offset 0x%lx, grain %d, row %d, " 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 810 if (edac_mc_get_panic_on_ue()) 811 panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, " 812 "row %d, labels \"%s\": %s\n", mci->mc_idx, 813 page_frame_number, offset_in_page, | 812 813 if (edac_mc_get_panic_on_ue()) 814 panic("EDAC MC%d: UE page 0x%lx, offset 0x%lx, grain %d, " 815 "row %d, labels \"%s\": %s\n", mci->mc_idx, 816 page_frame_number, offset_in_page, |
814 mci->csrows[row].grain, row, labels, msg); | 817 grain, row, labels, msg); |
815 816 mci->ue_count++; 817 mci->csrows[row].ue_count++; 818} 819EXPORT_SYMBOL_GPL(edac_mc_handle_ue); 820 821void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) 822{ --- 55 unchanged lines hidden (view full) --- 878 mci->ue_count++; 879 mci->csrows[csrow].ue_count++; 880 881 /* Generate the DIMM labels from the specified channels */ 882 label = mci->csrows[csrow].channels[channela].dimm->label; 883 chars = snprintf(pos, len + 1, "%s", label); 884 len -= chars; 885 pos += chars; | 818 819 mci->ue_count++; 820 mci->csrows[row].ue_count++; 821} 822EXPORT_SYMBOL_GPL(edac_mc_handle_ue); 823 824void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, const char *msg) 825{ --- 55 unchanged lines hidden (view full) --- 881 mci->ue_count++; 882 mci->csrows[csrow].ue_count++; 883 884 /* Generate the DIMM labels from the specified channels */ 885 label = mci->csrows[csrow].channels[channela].dimm->label; 886 chars = snprintf(pos, len + 1, "%s", label); 887 len -= chars; 888 pos += chars; |
889 |
|
886 chars = snprintf(pos, len + 1, "-%s", 887 mci->csrows[csrow].channels[channelb].dimm->label); 888 889 if (edac_mc_get_log_ue()) 890 edac_mc_printk(mci, KERN_EMERG, 891 "UE row %d, channel-a= %d channel-b= %d " 892 "labels \"%s\": %s\n", csrow, channela, channelb, 893 labels, msg); --- 37 unchanged lines hidden (view full) --- 931 if (edac_mc_get_log_ce()) 932 /* FIXME - put in DIMM location */ 933 edac_mc_printk(mci, KERN_WARNING, 934 "CE row %d, channel %d, label \"%s\": %s\n", 935 csrow, channel, label, msg); 936 937 mci->ce_count++; 938 mci->csrows[csrow].ce_count++; | 890 chars = snprintf(pos, len + 1, "-%s", 891 mci->csrows[csrow].channels[channelb].dimm->label); 892 893 if (edac_mc_get_log_ue()) 894 edac_mc_printk(mci, KERN_EMERG, 895 "UE row %d, channel-a= %d channel-b= %d " 896 "labels \"%s\": %s\n", csrow, channela, channelb, 897 labels, msg); --- 37 unchanged lines hidden (view full) --- 935 if (edac_mc_get_log_ce()) 936 /* FIXME - put in DIMM location */ 937 edac_mc_printk(mci, KERN_WARNING, 938 "CE row %d, channel %d, label \"%s\": %s\n", 939 csrow, channel, label, msg); 940 941 mci->ce_count++; 942 mci->csrows[csrow].ce_count++; |
943 mci->csrows[csrow].channels[channel].dimm->ce_count++; |
|
939 mci->csrows[csrow].channels[channel].ce_count++; 940} 941EXPORT_SYMBOL(edac_mc_handle_fbd_ce); | 944 mci->csrows[csrow].channels[channel].ce_count++; 945} 946EXPORT_SYMBOL(edac_mc_handle_fbd_ce); |