aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/edac/i7300_edac.c220
1 files changed, 104 insertions, 116 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index 6278209fec07..a2a9ad499b6b 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -122,14 +122,6 @@ static struct edac_pci_ctl_info *i7300_pci;
122 ***************************************************/ 122 ***************************************************/
123 123
124/* 124/*
125 * I7300 devices:
126 * All 3 functions of Device 16 (0,1,2) share the SAME DID and
127 * uses PCI_DEVICE_ID_INTEL_I7300_MCH_ERR for device 16 (0,1,2).
128 * PCI_DEVICE_ID_INTEL_I7300_MCH_FB0 is used for device 21 (0,1)
129 * and PCI_DEVICE_ID_INTEL_I7300_MCH_FB1 is used for device 21 (0,1).
130 */
131
132/*
133 * Device 16, 125 * Device 16,
134 * Function 0: System Address (not documented) 126 * Function 0: System Address (not documented)
135 * Function 1: Memory Branch Map, Control, Errors Register 127 * Function 1: Memory Branch Map, Control, Errors Register
@@ -345,9 +337,24 @@ static const char *ferr_global_lo_name[] = {
345 * i7300 Functions related to error detection 337 * i7300 Functions related to error detection
346 ********************************************/ 338 ********************************************/
347 339
348const char *get_err_from_table(const char *table[], int size, int pos) 340/**
341 * get_err_from_table() - Gets the error message from a table
342 * @table: table name (array of char *)
343 * @size: number of elements at the table
344 * @pos: position of the element to be returned
345 *
346 * This is a small routine that gets the pos-th element of a table. If the
347 * element doesn't exist (or it is empty), it returns "reserved".
348 * Instead of calling it directly, the better is to call via the macro
349 * GET_ERR_FROM_TABLE(), that automatically checks the table size via
350 * ARRAY_SIZE() macro
351 */
352static const char *get_err_from_table(const char *table[], int size, int pos)
349{ 353{
350 if (pos >= size) 354 if (unlikely(pos >= size))
355 return "Reserved";
356
357 if (unlikely(!table[pos]))
351 return "Reserved"; 358 return "Reserved";
352 359
353 return table[pos]; 360 return table[pos];
@@ -356,10 +363,11 @@ const char *get_err_from_table(const char *table[], int size, int pos)
356#define GET_ERR_FROM_TABLE(table, pos) \ 363#define GET_ERR_FROM_TABLE(table, pos) \
357 get_err_from_table(table, ARRAY_SIZE(table), pos) 364 get_err_from_table(table, ARRAY_SIZE(table), pos)
358 365
359/* 366/**
360 * i7300_process_error_global Retrieve the hardware error information from 367 * i7300_process_error_global() - Retrieve the hardware error information from
361 * the hardware and cache it in the 'info' 368 * the hardware global error registers and
362 * structure 369 * sends it to dmesg
370 * @mci: struct mem_ctl_info pointer
363 */ 371 */
364static void i7300_process_error_global(struct mem_ctl_info *mci) 372static void i7300_process_error_global(struct mem_ctl_info *mci)
365{ 373{
@@ -410,10 +418,11 @@ error_global:
410 is_fatal ? "Fatal" : "NOT fatal", specific); 418 is_fatal ? "Fatal" : "NOT fatal", specific);
411} 419}
412 420
413/* 421/**
414 * i7300_process_fbd_error Retrieve the hardware error information from 422 * i7300_process_fbd_error() - Retrieve the hardware error information from
415 * the hardware and cache it in the 'info' 423 * the FBD error registers and sends it via
416 * structure 424 * EDAC error API calls
425 * @mci: struct mem_ctl_info pointer
417 */ 426 */
418static void i7300_process_fbd_error(struct mem_ctl_info *mci) 427static void i7300_process_fbd_error(struct mem_ctl_info *mci)
419{ 428{
@@ -524,10 +533,9 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci)
524 return; 533 return;
525} 534}
526 535
527/* 536/**
528 * i7300_check_error Retrieve the hardware error information from 537 * i7300_check_error() - Calls the error checking subroutines
529 * the hardware and cache it in the 'info' 538 * @mci: struct mem_ctl_info pointer
530 * structure
531 */ 539 */
532static void i7300_check_error(struct mem_ctl_info *mci) 540static void i7300_check_error(struct mem_ctl_info *mci)
533{ 541{
@@ -535,11 +543,9 @@ static void i7300_check_error(struct mem_ctl_info *mci)
535 i7300_process_fbd_error(mci); 543 i7300_process_fbd_error(mci);
536}; 544};
537 545
538/* 546/**
539 * i7300_clear_error Retrieve any error from the hardware 547 * i7300_clear_error() - Clears the error registers
540 * but do NOT process that error. 548 * @mci: struct mem_ctl_info pointer
541 * Used for 'clearing' out of previous errors
542 * Called by the Core module.
543 */ 549 */
544static void i7300_clear_error(struct mem_ctl_info *mci) 550static void i7300_clear_error(struct mem_ctl_info *mci)
545{ 551{
@@ -573,9 +579,10 @@ static void i7300_clear_error(struct mem_ctl_info *mci)
573 FERR_NF_FBD, value); 579 FERR_NF_FBD, value);
574} 580}
575 581
576/* 582/**
577 * i7300_enable_error_reporting 583 * i7300_enable_error_reporting() - Enable the memory reporting logic at the
578 * Turn on the memory reporting features of the hardware 584 * hardware
585 * @mci: struct mem_ctl_info pointer
579 */ 586 */
580static void i7300_enable_error_reporting(struct mem_ctl_info *mci) 587static void i7300_enable_error_reporting(struct mem_ctl_info *mci)
581{ 588{
@@ -597,10 +604,14 @@ static void i7300_enable_error_reporting(struct mem_ctl_info *mci)
597 * i7300 Functions related to memory enumberation 604 * i7300 Functions related to memory enumberation
598 ************************************************/ 605 ************************************************/
599 606
600/* 607/**
601 * determine_mtr(pvt, csrow, channel) 608 * decode_mtr() - Decodes the MTR descriptor, filling the edac structs
602 * 609 * @pvt: pointer to the private data struct used by i7300 driver
603 * return the proper MTR register as determine by the csrow and desired channel 610 * @slot: DIMM slot (0 to 7)
611 * @ch: Channel number within the branch (0 or 1)
612 * @branch: Branch number (0 or 1)
613 * @dinfo: Pointer to DIMM info where dimm size is stored
614 * @p_csrow: Pointer to the struct csrow_info that corresponds to that element
604 */ 615 */
605static int decode_mtr(struct i7300_pvt *pvt, 616static int decode_mtr(struct i7300_pvt *pvt,
606 int slot, int ch, int branch, 617 int slot, int ch, int branch,
@@ -619,14 +630,8 @@ static int decode_mtr(struct i7300_pvt *pvt,
619 ans ? "Present" : "NOT Present"); 630 ans ? "Present" : "NOT Present");
620 631
621 /* Determine if there is a DIMM present in this DIMM slot */ 632 /* Determine if there is a DIMM present in this DIMM slot */
622
623#if 0
624 if (!amb_present || !ans)
625 return 0;
626#else
627 if (!ans) 633 if (!ans)
628 return 0; 634 return 0;
629#endif
630 635
631 /* Start with the number of bits for a Bank 636 /* Start with the number of bits for a Bank
632 * on the DRAM */ 637 * on the DRAM */
@@ -692,14 +697,15 @@ static int decode_mtr(struct i7300_pvt *pvt,
692 return mtr; 697 return mtr;
693} 698}
694 699
695/* 700/**
696 * print_dimm_size 701 * print_dimm_size() - Prints dump of the memory organization
702 * @pvt: pointer to the private data struct used by i7300 driver
697 * 703 *
698 * also will output a DIMM matrix map, if debug is enabled, for viewing 704 * Useful for debug. If debug is disabled, this routine do nothing
699 * how the DIMMs are populated
700 */ 705 */
701static void print_dimm_size(struct i7300_pvt *pvt) 706static void print_dimm_size(struct i7300_pvt *pvt)
702{ 707{
708#ifdef CONFIG_EDAC_DEBUG
703 struct i7300_dimm_info *dinfo; 709 struct i7300_dimm_info *dinfo;
704 char *p; 710 char *p;
705 int space, n; 711 int space, n;
@@ -751,30 +757,26 @@ static void print_dimm_size(struct i7300_pvt *pvt)
751 debugf2("%s\n", pvt->tmp_prt_buffer); 757 debugf2("%s\n", pvt->tmp_prt_buffer);
752 p = pvt->tmp_prt_buffer; 758 p = pvt->tmp_prt_buffer;
753 space = PAGE_SIZE; 759 space = PAGE_SIZE;
760#endif
754} 761}
755 762
756/* 763/**
757 * i7300_init_csrows Initialize the 'csrows' table within 764 * i7300_init_csrows() - Initialize the 'csrows' table within
758 * the mci control structure with the 765 * the mci control structure with the
759 * addressing of memory. 766 * addressing of memory.
760 * 767 * @mci: struct mem_ctl_info pointer
761 * return:
762 * 0 success
763 * 1 no actual memory found on this MC
764 */ 768 */
765static int i7300_init_csrows(struct mem_ctl_info *mci) 769static int i7300_init_csrows(struct mem_ctl_info *mci)
766{ 770{
767 struct i7300_pvt *pvt; 771 struct i7300_pvt *pvt;
768 struct i7300_dimm_info *dinfo; 772 struct i7300_dimm_info *dinfo;
769 struct csrow_info *p_csrow; 773 struct csrow_info *p_csrow;
770 int empty; 774 int rc = -ENODEV;
771 int mtr; 775 int mtr;
772 int ch, branch, slot, channel; 776 int ch, branch, slot, channel;
773 777
774 pvt = mci->pvt_info; 778 pvt = mci->pvt_info;
775 779
776 empty = 1; /* Assume NO memory */
777
778 debugf2("Memory Technology Registers:\n"); 780 debugf2("Memory Technology Registers:\n");
779 781
780 /* Get the AMB present registers for the four channels */ 782 /* Get the AMB present registers for the four channels */
@@ -819,14 +821,19 @@ static int i7300_init_csrows(struct mem_ctl_info *mci)
819 p_csrow->last_page = 9 + slot * 20; 821 p_csrow->last_page = 9 + slot * 20;
820 p_csrow->page_mask = 0xfff; 822 p_csrow->page_mask = 0xfff;
821 823
822 empty = 0; 824 rc = 0;
823 } 825 }
824 } 826 }
825 } 827 }
826 828
827 return empty; 829 return rc;
828} 830}
829 831
832/**
833 * decode_mir() - Decodes Memory Interleave Register (MIR) info
834 * @int mir_no: number of the MIR register to decode
835 * @mir: array with the MIR data cached on the driver
836 */
830static void decode_mir(int mir_no, u16 mir[MAX_MIR]) 837static void decode_mir(int mir_no, u16 mir[MAX_MIR])
831{ 838{
832 if (mir[mir_no] & 3) 839 if (mir[mir_no] & 3)
@@ -837,11 +844,11 @@ static void decode_mir(int mir_no, u16 mir[MAX_MIR])
837 (mir[mir_no] & 2) ? "B1": ""); 844 (mir[mir_no] & 2) ? "B1": "");
838} 845}
839 846
840/* 847/**
841 * i7300_get_mc_regs read in the necessary registers and 848 * i7300_get_mc_regs() - Get the contents of the MC enumeration registers
842 * cache locally 849 * @mci: struct mem_ctl_info pointer
843 * 850 *
844 * Fills in the private data members 851 * Data read is cached internally for its usage when needed
845 */ 852 */
846static int i7300_get_mc_regs(struct mem_ctl_info *mci) 853static int i7300_get_mc_regs(struct mem_ctl_info *mci)
847{ 854{
@@ -907,9 +914,9 @@ static int i7300_get_mc_regs(struct mem_ctl_info *mci)
907 * i7300 Functions related to device probe/release 914 * i7300 Functions related to device probe/release
908 *************************************************/ 915 *************************************************/
909 916
910/* 917/**
911 * i7300_put_devices 'put' all the devices that we have 918 * i7300_put_devices() - Release the PCI devices
912 * reserved via 'get' 919 * @mci: struct mem_ctl_info pointer
913 */ 920 */
914static void i7300_put_devices(struct mem_ctl_info *mci) 921static void i7300_put_devices(struct mem_ctl_info *mci)
915{ 922{
@@ -925,13 +932,18 @@ static void i7300_put_devices(struct mem_ctl_info *mci)
925 pci_dev_put(pvt->pci_dev_16_1_fsb_addr_map); 932 pci_dev_put(pvt->pci_dev_16_1_fsb_addr_map);
926} 933}
927 934
928/* 935/**
929 * i7300_get_devices Find and perform 'get' operation on the MCH's 936 * i7300_get_devices() - Find and perform 'get' operation on the MCH's
930 * device/functions we want to reference for this driver 937 * device/functions we want to reference for this driver
938 * @mci: struct mem_ctl_info pointer
931 * 939 *
932 * Need to 'get' device 16 func 1 and func 2 940 * Access and prepare the several devices for usage:
941 * I7300 devices used by this driver:
942 * Device 16, functions 0,1 and 2: PCI_DEVICE_ID_INTEL_I7300_MCH_ERR
943 * Device 21 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB0
944 * Device 22 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB1
933 */ 945 */
934static int i7300_get_devices(struct mem_ctl_info *mci, int dev_idx) 946static int __devinit i7300_get_devices(struct mem_ctl_info *mci)
935{ 947{
936 struct i7300_pvt *pvt; 948 struct i7300_pvt *pvt;
937 struct pci_dev *pdev; 949 struct pci_dev *pdev;
@@ -1007,23 +1019,25 @@ error:
1007 return -ENODEV; 1019 return -ENODEV;
1008} 1020}
1009 1021
1010/* 1022/**
1011 * i7300_probe1 Probe for ONE instance of device to see if it is 1023 * i7300_init_one() - Probe for one instance of the device
1012 * present. 1024 * @pdev: struct pci_dev pointer
1013 * return: 1025 * @id: struct pci_device_id pointer - currently unused
1014 * 0 for FOUND a device
1015 * < 0 for error code
1016 */ 1026 */
1017static int i7300_probe1(struct pci_dev *pdev, int dev_idx) 1027static int __devinit i7300_init_one(struct pci_dev *pdev,
1028 const struct pci_device_id *id)
1018{ 1029{
1019 struct mem_ctl_info *mci; 1030 struct mem_ctl_info *mci;
1020 struct i7300_pvt *pvt; 1031 struct i7300_pvt *pvt;
1021 int num_channels; 1032 int num_channels;
1022 int num_dimms_per_channel; 1033 int num_dimms_per_channel;
1023 int num_csrows; 1034 int num_csrows;
1035 int rc;
1024 1036
1025 if (dev_idx >= ARRAY_SIZE(i7300_devs)) 1037 /* wake up device */
1026 return -EINVAL; 1038 rc = pci_enable_device(pdev);
1039 if (rc == -EIO)
1040 return rc;
1027 1041
1028 debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n", 1042 debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n",
1029 __func__, 1043 __func__,
@@ -1068,7 +1082,7 @@ static int i7300_probe1(struct pci_dev *pdev, int dev_idx)
1068 } 1082 }
1069 1083
1070 /* 'get' the pci devices we want to reserve for our use */ 1084 /* 'get' the pci devices we want to reserve for our use */
1071 if (i7300_get_devices(mci, dev_idx)) 1085 if (i7300_get_devices(mci))
1072 goto fail0; 1086 goto fail0;
1073 1087
1074 mci->mc_idx = 0; 1088 mci->mc_idx = 0;
@@ -1077,7 +1091,7 @@ static int i7300_probe1(struct pci_dev *pdev, int dev_idx)
1077 mci->edac_cap = EDAC_FLAG_NONE; 1091 mci->edac_cap = EDAC_FLAG_NONE;
1078 mci->mod_name = "i7300_edac.c"; 1092 mci->mod_name = "i7300_edac.c";
1079 mci->mod_ver = I7300_REVISION; 1093 mci->mod_ver = I7300_REVISION;
1080 mci->ctl_name = i7300_devs[dev_idx].ctl_name; 1094 mci->ctl_name = i7300_devs[0].ctl_name;
1081 mci->dev_name = pci_name(pdev); 1095 mci->dev_name = pci_name(pdev);
1082 mci->ctl_page_to_phys = NULL; 1096 mci->ctl_page_to_phys = NULL;
1083 1097
@@ -1132,32 +1146,9 @@ fail0:
1132 return -ENODEV; 1146 return -ENODEV;
1133} 1147}
1134 1148
1135/* 1149/**
1136 * i7300_init_one constructor for one instance of device 1150 * i7300_remove_one() - Remove the driver
1137 * 1151 * @pdev: struct pci_dev pointer
1138 * returns:
1139 * negative on error
1140 * count (>= 0)
1141 */
1142static int __devinit i7300_init_one(struct pci_dev *pdev,
1143 const struct pci_device_id *id)
1144{
1145 int rc;
1146
1147 debugf0("MC: " __FILE__ ": %s()\n", __func__);
1148
1149 /* wake up device */
1150 rc = pci_enable_device(pdev);
1151 if (rc == -EIO)
1152 return rc;
1153
1154 /* now probe and enable the device */
1155 return i7300_probe1(pdev, id->driver_data);
1156}
1157
1158/*
1159 * i7300_remove_one destructor for one instance of device
1160 *
1161 */ 1152 */
1162static void __devexit i7300_remove_one(struct pci_dev *pdev) 1153static void __devexit i7300_remove_one(struct pci_dev *pdev)
1163{ 1154{
@@ -1183,9 +1174,9 @@ static void __devexit i7300_remove_one(struct pci_dev *pdev)
1183} 1174}
1184 1175
1185/* 1176/*
1186 * pci_device_id table for which devices we are looking for 1177 * pci_device_id: table for which devices we are looking for
1187 * 1178 *
1188 * The "E500P" device is the first device supported. 1179 * Has only 8086:360c PCI ID
1189 */ 1180 */
1190static const struct pci_device_id i7300_pci_tbl[] __devinitdata = { 1181static const struct pci_device_id i7300_pci_tbl[] __devinitdata = {
1191 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_ERR)}, 1182 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_ERR)},
@@ -1195,8 +1186,7 @@ static const struct pci_device_id i7300_pci_tbl[] __devinitdata = {
1195MODULE_DEVICE_TABLE(pci, i7300_pci_tbl); 1186MODULE_DEVICE_TABLE(pci, i7300_pci_tbl);
1196 1187
1197/* 1188/*
1198 * i7300_driver pci_driver structure for this module 1189 * i7300_driver: pci_driver structure for this module
1199 *
1200 */ 1190 */
1201static struct pci_driver i7300_driver = { 1191static struct pci_driver i7300_driver = {
1202 .name = "i7300_edac", 1192 .name = "i7300_edac",
@@ -1205,9 +1195,8 @@ static struct pci_driver i7300_driver = {
1205 .id_table = i7300_pci_tbl, 1195 .id_table = i7300_pci_tbl,
1206}; 1196};
1207 1197
1208/* 1198/**
1209 * i7300_init Module entry function 1199 * i7300_init() - Registers the driver
1210 * Try to initialize this module for its devices
1211 */ 1200 */
1212static int __init i7300_init(void) 1201static int __init i7300_init(void)
1213{ 1202{
@@ -1223,9 +1212,8 @@ static int __init i7300_init(void)
1223 return (pci_rc < 0) ? pci_rc : 0; 1212 return (pci_rc < 0) ? pci_rc : 0;
1224} 1213}
1225 1214
1226/* 1215/**
1227 * i7300_exit() Module exit function 1216 * i7300_init() - Unregisters the driver
1228 * Unregister the driver
1229 */ 1217 */
1230static void __exit i7300_exit(void) 1218static void __exit i7300_exit(void)
1231{ 1219{