aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/e752x_edac.c
diff options
context:
space:
mode:
authorDoug Thompson <norsk5@xmission.com>2006-06-30 04:56:08 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-30 14:25:39 -0400
commit1318952514d5651c453d89989595a9df3b37267b (patch)
treedf793132fa7e24e53c68897d4302d964eb07b526 /drivers/edac/e752x_edac.c
parent2d7bbb91c8df26c60d223205a087507430024177 (diff)
[PATCH] EDAC: probe1 cleanup 1-of-2
- Add lower-level functions that handle various parts of the initialization done by the xxx_probe1() functions. Some of the xxx_probe1() functions are much too long and complicated (see "Chapter 5: Functions" in Documentation/CodingStyle). - Cleanup of probe1() functions in EDAC Signed-off-by: Doug Thompson <norsk5@xmission.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/edac/e752x_edac.c')
-rw-r--r--drivers/edac/e752x_edac.c322
1 files changed, 177 insertions, 145 deletions
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c
index 5e773e382e8a..5351a76739e5 100644
--- a/drivers/edac/e752x_edac.c
+++ b/drivers/edac/e752x_edac.c
@@ -765,22 +765,174 @@ static void e752x_check(struct mem_ctl_info *mci)
765 e752x_process_error_info(mci, &info, 1); 765 e752x_process_error_info(mci, &info, 1);
766} 766}
767 767
768static int e752x_probe1(struct pci_dev *pdev, int dev_idx) 768/* Return 1 if dual channel mode is active. Else return 0. */
769static inline int dual_channel_active(u16 ddrcsr)
770{
771 return (((ddrcsr >> 12) & 3) == 3);
772}
773
774static void e752x_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev,
775 u16 ddrcsr)
776{
777 struct csrow_info *csrow;
778 unsigned long last_cumul_size;
779 int index, mem_dev, drc_chan;
780 int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */
781 int drc_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */
782 u8 value;
783 u32 dra, drc, cumul_size;
784
785 pci_read_config_dword(pdev, E752X_DRA, &dra);
786 pci_read_config_dword(pdev, E752X_DRC, &drc);
787 drc_chan = dual_channel_active(ddrcsr);
788 drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */
789 drc_ddim = (drc >> 20) & 0x3;
790
791 /* The dram row boundary (DRB) reg values are boundary address for
792 * each DRAM row with a granularity of 64 or 128MB (single/dual
793 * channel operation). DRB regs are cumulative; therefore DRB7 will
794 * contain the total memory contained in all eight rows.
795 */
796 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
797 /* mem_dev 0=x8, 1=x4 */
798 mem_dev = (dra >> (index * 4 + 2)) & 0x3;
799 csrow = &mci->csrows[index];
800
801 mem_dev = (mem_dev == 2);
802 pci_read_config_byte(pdev, E752X_DRB + index, &value);
803 /* convert a 128 or 64 MiB DRB to a page size. */
804 cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
805 debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
806 cumul_size);
807 if (cumul_size == last_cumul_size)
808 continue; /* not populated */
809
810 csrow->first_page = last_cumul_size;
811 csrow->last_page = cumul_size - 1;
812 csrow->nr_pages = cumul_size - last_cumul_size;
813 last_cumul_size = cumul_size;
814 csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
815 csrow->mtype = MEM_RDDR; /* only one type supported */
816 csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
817
818 /*
819 * if single channel or x8 devices then SECDED
820 * if dual channel and x4 then S4ECD4ED
821 */
822 if (drc_ddim) {
823 if (drc_chan && mem_dev) {
824 csrow->edac_mode = EDAC_S4ECD4ED;
825 mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
826 } else {
827 csrow->edac_mode = EDAC_SECDED;
828 mci->edac_cap |= EDAC_FLAG_SECDED;
829 }
830 } else
831 csrow->edac_mode = EDAC_NONE;
832 }
833}
834
835static void e752x_init_mem_map_table(struct pci_dev *pdev,
836 struct e752x_pvt *pvt)
769{ 837{
770 int rc = -ENODEV;
771 int index; 838 int index;
839 u8 value, last, row, stat8;
840
841 last = 0;
842 row = 0;
843
844 for (index = 0; index < 8; index += 2) {
845 pci_read_config_byte(pdev, E752X_DRB + index, &value);
846 /* test if there is a dimm in this slot */
847 if (value == last) {
848 /* no dimm in the slot, so flag it as empty */
849 pvt->map[index] = 0xff;
850 pvt->map[index + 1] = 0xff;
851 } else { /* there is a dimm in the slot */
852 pvt->map[index] = row;
853 row++;
854 last = value;
855 /* test the next value to see if the dimm is double
856 * sided
857 */
858 pci_read_config_byte(pdev, E752X_DRB + index + 1,
859 &value);
860 pvt->map[index + 1] = (value == last) ?
861 0xff : /* the dimm is single sided,
862 so flag as empty */
863 row; /* this is a double sided dimm
864 to save the next row # */
865 row++;
866 last = value;
867 }
868 }
869
870 /* set the map type. 1 = normal, 0 = reversed */
871 pci_read_config_byte(pdev, E752X_DRM, &stat8);
872 pvt->map_type = ((stat8 & 0x0f) > ((stat8 >> 4) & 0x0f));
873}
874
875/* Return 0 on success or 1 on failure. */
876static int e752x_get_devs(struct pci_dev *pdev, int dev_idx,
877 struct e752x_pvt *pvt)
878{
879 struct pci_dev *dev;
880
881 pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL,
882 pvt->dev_info->err_dev,
883 pvt->bridge_ck);
884
885 if (pvt->bridge_ck == NULL)
886 pvt->bridge_ck = pci_scan_single_device(pdev->bus,
887 PCI_DEVFN(0, 1));
888
889 if (pvt->bridge_ck == NULL) {
890 e752x_printk(KERN_ERR, "error reporting device not found:"
891 "vendor %x device 0x%x (broken BIOS?)\n",
892 PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
893 return 1;
894 }
895
896 dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev,
897 NULL);
898
899 if (dev == NULL)
900 goto fail;
901
902 pvt->dev_d0f0 = dev;
903 pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);
904
905 return 0;
906
907fail:
908 pci_dev_put(pvt->bridge_ck);
909 return 1;
910}
911
912static void e752x_init_error_reporting_regs(struct e752x_pvt *pvt)
913{
914 struct pci_dev *dev;
915
916 dev = pvt->dev_d0f1;
917 /* Turn off error disable & SMI in case the BIOS turned it on */
918 pci_write_config_byte(dev, E752X_HI_ERRMASK, 0x00);
919 pci_write_config_byte(dev, E752X_HI_SMICMD, 0x00);
920 pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x00);
921 pci_write_config_word(dev, E752X_SYSBUS_SMICMD, 0x00);
922 pci_write_config_byte(dev, E752X_BUF_ERRMASK, 0x00);
923 pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00);
924 pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00);
925 pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00);
926}
927
928static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
929{
772 u16 pci_data; 930 u16 pci_data;
773 u8 stat8; 931 u8 stat8;
774 struct mem_ctl_info *mci = NULL; 932 struct mem_ctl_info *mci;
775 struct e752x_pvt *pvt = NULL; 933 struct e752x_pvt *pvt;
776 u16 ddrcsr; 934 u16 ddrcsr;
777 u32 drc;
778 int drc_chan; /* Number of channels 0=1chan,1=2chan */ 935 int drc_chan; /* Number of channels 0=1chan,1=2chan */
779 int drc_drbg; /* DRB granularity 0=64mb, 1=128mb */
780 int drc_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */
781 u32 dra;
782 unsigned long last_cumul_size;
783 struct pci_dev *dev = NULL;
784 struct e752x_error_info discard; 936 struct e752x_error_info discard;
785 937
786 debugf0("%s(): mci\n", __func__); 938 debugf0("%s(): mci\n", __func__);
@@ -794,25 +946,20 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
794 if (!force_function_unhide && !(stat8 & (1 << 5))) { 946 if (!force_function_unhide && !(stat8 & (1 << 5))) {
795 printk(KERN_INFO "Contact your BIOS vendor to see if the " 947 printk(KERN_INFO "Contact your BIOS vendor to see if the "
796 "E752x error registers can be safely un-hidden\n"); 948 "E752x error registers can be safely un-hidden\n");
797 goto fail; 949 return -ENOMEM;
798 } 950 }
799 stat8 |= (1 << 5); 951 stat8 |= (1 << 5);
800 pci_write_config_byte(pdev, E752X_DEVPRES1, stat8); 952 pci_write_config_byte(pdev, E752X_DEVPRES1, stat8);
801 953
802 /* need to find out the number of channels */
803 pci_read_config_dword(pdev, E752X_DRC, &drc);
804 pci_read_config_word(pdev, E752X_DDRCSR, &ddrcsr); 954 pci_read_config_word(pdev, E752X_DDRCSR, &ddrcsr);
805 /* FIXME: should check >>12 or 0xf, true for all? */ 955 /* FIXME: should check >>12 or 0xf, true for all? */
806 /* Dual channel = 1, Single channel = 0 */ 956 /* Dual channel = 1, Single channel = 0 */
807 drc_chan = (((ddrcsr >> 12) & 3) == 3); 957 drc_chan = dual_channel_active(ddrcsr);
808 drc_drbg = drc_chan + 1; /* 128 in dual mode, 64 in single */
809 drc_ddim = (drc >> 20) & 0x3;
810 958
811 mci = edac_mc_alloc(sizeof(*pvt), E752X_NR_CSROWS, drc_chan + 1); 959 mci = edac_mc_alloc(sizeof(*pvt), E752X_NR_CSROWS, drc_chan + 1);
812 960
813 if (mci == NULL) { 961 if (mci == NULL) {
814 rc = -ENOMEM; 962 return -ENOMEM;
815 goto fail;
816 } 963 }
817 964
818 debugf3("%s(): init mci\n", __func__); 965 debugf3("%s(): init mci\n", __func__);
@@ -827,113 +974,20 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
827 debugf3("%s(): init pvt\n", __func__); 974 debugf3("%s(): init pvt\n", __func__);
828 pvt = (struct e752x_pvt *) mci->pvt_info; 975 pvt = (struct e752x_pvt *) mci->pvt_info;
829 pvt->dev_info = &e752x_devs[dev_idx]; 976 pvt->dev_info = &e752x_devs[dev_idx];
830 pvt->bridge_ck = pci_get_device(PCI_VENDOR_ID_INTEL, 977 pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
831 pvt->dev_info->err_dev,
832 pvt->bridge_ck);
833
834 if (pvt->bridge_ck == NULL)
835 pvt->bridge_ck = pci_scan_single_device(pdev->bus,
836 PCI_DEVFN(0, 1));
837 978
838 if (pvt->bridge_ck == NULL) { 979 if (e752x_get_devs(pdev, dev_idx, pvt)) {
839 e752x_printk(KERN_ERR, "error reporting device not found:" 980 edac_mc_free(mci);
840 "vendor %x device 0x%x (broken BIOS?)\n", 981 return -ENODEV;
841 PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].err_dev);
842 goto fail;
843 } 982 }
844 983
845 pvt->mc_symmetric = ((ddrcsr & 0x10) != 0);
846 debugf3("%s(): more mci init\n", __func__); 984 debugf3("%s(): more mci init\n", __func__);
847 mci->ctl_name = pvt->dev_info->ctl_name; 985 mci->ctl_name = pvt->dev_info->ctl_name;
848 mci->edac_check = e752x_check; 986 mci->edac_check = e752x_check;
849 mci->ctl_page_to_phys = ctl_page_to_phys; 987 mci->ctl_page_to_phys = ctl_page_to_phys;
850 988
851 /* find out the device types */ 989 e752x_init_csrows(mci, pdev, ddrcsr);
852 pci_read_config_dword(pdev, E752X_DRA, &dra); 990 e752x_init_mem_map_table(pdev, pvt);
853
854 /*
855 * The dram row boundary (DRB) reg values are boundary address for
856 * each DRAM row with a granularity of 64 or 128MB (single/dual
857 * channel operation). DRB regs are cumulative; therefore DRB7 will
858 * contain the total memory contained in all eight rows.
859 */
860 for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) {
861 u8 value;
862 u32 cumul_size;
863
864 /* mem_dev 0=x8, 1=x4 */
865 int mem_dev = (dra >> (index * 4 + 2)) & 0x3;
866 struct csrow_info *csrow = &mci->csrows[index];
867
868 mem_dev = (mem_dev == 2);
869 pci_read_config_byte(pdev, E752X_DRB + index, &value);
870 /* convert a 128 or 64 MiB DRB to a page size. */
871 cumul_size = value << (25 + drc_drbg - PAGE_SHIFT);
872 debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index,
873 cumul_size);
874
875 if (cumul_size == last_cumul_size)
876 continue; /* not populated */
877
878 csrow->first_page = last_cumul_size;
879 csrow->last_page = cumul_size - 1;
880 csrow->nr_pages = cumul_size - last_cumul_size;
881 last_cumul_size = cumul_size;
882 csrow->grain = 1 << 12; /* 4KiB - resolution of CELOG */
883 csrow->mtype = MEM_RDDR; /* only one type supported */
884 csrow->dtype = mem_dev ? DEV_X4 : DEV_X8;
885
886 /*
887 * if single channel or x8 devices then SECDED
888 * if dual channel and x4 then S4ECD4ED
889 */
890 if (drc_ddim) {
891 if (drc_chan && mem_dev) {
892 csrow->edac_mode = EDAC_S4ECD4ED;
893 mci->edac_cap |= EDAC_FLAG_S4ECD4ED;
894 } else {
895 csrow->edac_mode = EDAC_SECDED;
896 mci->edac_cap |= EDAC_FLAG_SECDED;
897 }
898 } else
899 csrow->edac_mode = EDAC_NONE;
900 }
901
902 /* Fill in the memory map table */
903 {
904 u8 value;
905 u8 last = 0;
906 u8 row = 0;
907
908 for (index = 0; index < 8; index += 2) {
909 pci_read_config_byte(pdev, E752X_DRB + index, &value);
910
911 /* test if there is a dimm in this slot */
912 if (value == last) {
913 /* no dimm in the slot, so flag it as empty */
914 pvt->map[index] = 0xff;
915 pvt->map[index + 1] = 0xff;
916 } else { /* there is a dimm in the slot */
917 pvt->map[index] = row;
918 row++;
919 last = value;
920 /* test the next value to see if the dimm is
921 double sided */
922 pci_read_config_byte(pdev,
923 E752X_DRB + index + 1,
924 &value);
925 pvt->map[index + 1] = (value == last) ?
926 0xff : /* the dimm is single sided,
927 * so flag as empty
928 */
929 row; /* this is a double sided dimm
930 * to save the next row #
931 */
932 row++;
933 last = value;
934 }
935 }
936 }
937 991
938 /* set the map type. 1 = normal, 0 = reversed */ 992 /* set the map type. 1 = normal, 0 = reversed */
939 pci_read_config_byte(pdev, E752X_DRM, &stat8); 993 pci_read_config_byte(pdev, E752X_DRM, &stat8);
@@ -961,21 +1015,7 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
961 goto fail; 1015 goto fail;
962 } 1016 }
963 1017
964 dev = pci_get_device(PCI_VENDOR_ID_INTEL, e752x_devs[dev_idx].ctl_dev, 1018 e752x_init_error_reporting_regs(pvt);
965 NULL);
966 pvt->dev_d0f0 = dev;
967 /* find the error reporting device and clear errors */
968 dev = pvt->dev_d0f1 = pci_dev_get(pvt->bridge_ck);
969 /* Turn off error disable & SMI in case the BIOS turned it on */
970 pci_write_config_byte(dev, E752X_HI_ERRMASK, 0x00);
971 pci_write_config_byte(dev, E752X_HI_SMICMD, 0x00);
972 pci_write_config_word(dev, E752X_SYSBUS_ERRMASK, 0x00);
973 pci_write_config_word(dev, E752X_SYSBUS_SMICMD, 0x00);
974 pci_write_config_byte(dev, E752X_BUF_ERRMASK, 0x00);
975 pci_write_config_byte(dev, E752X_BUF_SMICMD, 0x00);
976 pci_write_config_byte(dev, E752X_DRAM_ERRMASK, 0x00);
977 pci_write_config_byte(dev, E752X_DRAM_SMICMD, 0x00);
978
979 e752x_get_error_info(mci, &discard); /* clear other MCH errors */ 1019 e752x_get_error_info(mci, &discard); /* clear other MCH errors */
980 1020
981 /* get this far and it's successful */ 1021 /* get this far and it's successful */
@@ -983,20 +1023,12 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx)
983 return 0; 1023 return 0;
984 1024
985fail: 1025fail:
986 if (mci) { 1026 pci_dev_put(pvt->dev_d0f0);
987 if (pvt->dev_d0f0) 1027 pci_dev_put(pvt->dev_d0f1);
988 pci_dev_put(pvt->dev_d0f0); 1028 pci_dev_put(pvt->bridge_ck);
989 1029 edac_mc_free(mci);
990 if (pvt->dev_d0f1)
991 pci_dev_put(pvt->dev_d0f1);
992
993 if (pvt->bridge_ck)
994 pci_dev_put(pvt->bridge_ck);
995
996 edac_mc_free(mci);
997 }
998 1030
999 return rc; 1031 return -ENODEV;
1000} 1032}
1001 1033
1002/* returns count (>= 0), or negative on error */ 1034/* returns count (>= 0), or negative on error */