]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/edac/i7core_edac.c
914914759690a1e529fd3a8d3d74b6fef041b59d
[karo-tx-linux.git] / drivers / edac / i7core_edac.c
1 /* Intel 7 core  Memory Controller kernel module (Nehalem)
2  *
3  * This file may be distributed under the terms of the
4  * GNU General Public License version 2 only.
5  *
6  * Copyright (c) 2009 by:
7  *       Mauro Carvalho Chehab <mchehab@redhat.com>
8  *
9  * Red Hat Inc. http://www.redhat.com
10  *
11  * Forked and adapted from the i5400_edac driver
12  *
13  * Based on the following public Intel datasheets:
14  * Intel Core i7 Processor Extreme Edition and Intel Core i7 Processor
15  * Datasheet, Volume 2:
16  *      http://download.intel.com/design/processor/datashts/320835.pdf
17  * Intel Xeon Processor 5500 Series Datasheet Volume 2
18  *      http://www.intel.com/Assets/PDF/datasheet/321322.pdf
19  * also available at:
20  *      http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
21  */
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <linux/pci.h>
26 #include <linux/pci_ids.h>
27 #include <linux/slab.h>
28 #include <linux/edac.h>
29 #include <linux/mmzone.h>
30
31 #include "edac_core.h"
32
33 /* To use the new pci_[read/write]_config_qword instead of two dword */
34 #define USE_QWORD 1
35
36 /*
37  * Alter this version for the module when modifications are made
38  */
39 #define I7CORE_REVISION    " Ver: 1.0.0 " __DATE__
40 #define EDAC_MOD_STR      "i7core_edac"
41
42 /* HACK: temporary, just to enable all logs, for now */
43 #undef debugf0
44 #define debugf0(fmt, arg...)  edac_printk(KERN_INFO, "i7core", fmt, ##arg)
45
46 /*
47  * Debug macros
48  */
49 #define i7core_printk(level, fmt, arg...)                       \
50         edac_printk(level, "i7core", fmt, ##arg)
51
52 #define i7core_mc_printk(mci, level, fmt, arg...)               \
53         edac_mc_chipset_printk(mci, level, "i7core", fmt, ##arg)
54
55 /*
56  * i7core Memory Controller Registers
57  */
58
59         /* OFFSETS for Device 3 Function 0 */
60
61 #define MC_CONTROL      0x48
62 #define MC_STATUS       0x4c
63 #define MC_MAX_DOD      0x64
64
65 /*
66  * OFFSETS for Device 3 Function 4, as inicated on Xeon 5500 datasheet:
67  * http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
68  */
69
70 #define MC_TEST_ERR_RCV1        0x60
71   #define DIMM2_COR_ERR(r)                      ((r) & 0x7fff)
72
73 #define MC_TEST_ERR_RCV0        0x64
74   #define DIMM1_COR_ERR(r)                      (((r) >> 16) & 0x7fff)
75   #define DIMM0_COR_ERR(r)                      ((r) & 0x7fff)
76
77         /* OFFSETS for Devices 4,5 and 6 Function 0 */
78
79 #define MC_CHANNEL_DIMM_INIT_PARAMS 0x58
80   #define THREE_DIMMS_PRESENT           (1 << 24)
81   #define SINGLE_QUAD_RANK_PRESENT      (1 << 23)
82   #define QUAD_RANK_PRESENT             (1 << 22)
83   #define REGISTERED_DIMM               (1 << 15)
84
85 #define MC_CHANNEL_MAPPER       0x60
86   #define RDLCH(r, ch)          ((((r) >> (3 + (ch * 6))) & 0x07) - 1)
87   #define WRLCH(r, ch)          ((((r) >> (ch * 6)) & 0x07) - 1)
88
89 #define MC_CHANNEL_RANK_PRESENT 0x7c
90   #define RANK_PRESENT_MASK             0xffff
91
92 #define MC_CHANNEL_ADDR_MATCH   0xf0
93 #define MC_CHANNEL_ERROR_MASK   0xf8
94 #define MC_CHANNEL_ERROR_INJECT 0xfc
95   #define INJECT_ADDR_PARITY    0x10
96   #define INJECT_ECC            0x08
97   #define MASK_CACHELINE        0x06
98   #define MASK_FULL_CACHELINE   0x06
99   #define MASK_MSB32_CACHELINE  0x04
100   #define MASK_LSB32_CACHELINE  0x02
101   #define NO_MASK_CACHELINE     0x00
102   #define REPEAT_EN             0x01
103
104         /* OFFSETS for Devices 4,5 and 6 Function 1 */
105 #define MC_DOD_CH_DIMM0         0x48
106 #define MC_DOD_CH_DIMM1         0x4c
107 #define MC_DOD_CH_DIMM2         0x50
108   #define RANKOFFSET_MASK       ((1 << 12) | (1 << 11) | (1 << 10))
109   #define RANKOFFSET(x)         ((x & RANKOFFSET_MASK) >> 10)
110   #define DIMM_PRESENT_MASK     (1 << 9)
111   #define DIMM_PRESENT(x)       (((x) & DIMM_PRESENT_MASK) >> 9)
112   #define MC_DOD_NUMBANK_MASK           ((1 << 8) | (1 << 7))
113   #define MC_DOD_NUMBANK(x)             (((x) & MC_DOD_NUMBANK_MASK) >> 7)
114   #define MC_DOD_NUMRANK_MASK           ((1 << 6) | (1 << 5))
115   #define MC_DOD_NUMRANK(x)             (((x) & MC_DOD_NUMRANK_MASK) >> 5)
116   #define MC_DOD_NUMROW_MASK            ((1 << 4) | (1 << 3) | (1 << 2))
117   #define MC_DOD_NUMROW(x)              (((x) & MC_DOD_NUMROW_MASK) >> 2)
118   #define MC_DOD_NUMCOL_MASK            3
119   #define MC_DOD_NUMCOL(x)              ((x) & MC_DOD_NUMCOL_MASK)
120
121 #define MC_RANK_PRESENT         0x7c
122
123 #define MC_SAG_CH_0     0x80
124 #define MC_SAG_CH_1     0x84
125 #define MC_SAG_CH_2     0x88
126 #define MC_SAG_CH_3     0x8c
127 #define MC_SAG_CH_4     0x90
128 #define MC_SAG_CH_5     0x94
129 #define MC_SAG_CH_6     0x98
130 #define MC_SAG_CH_7     0x9c
131
132 #define MC_RIR_LIMIT_CH_0       0x40
133 #define MC_RIR_LIMIT_CH_1       0x44
134 #define MC_RIR_LIMIT_CH_2       0x48
135 #define MC_RIR_LIMIT_CH_3       0x4C
136 #define MC_RIR_LIMIT_CH_4       0x50
137 #define MC_RIR_LIMIT_CH_5       0x54
138 #define MC_RIR_LIMIT_CH_6       0x58
139 #define MC_RIR_LIMIT_CH_7       0x5C
140 #define MC_RIR_LIMIT_MASK       ((1 << 10) - 1)
141
142 #define MC_RIR_WAY_CH           0x80
143   #define MC_RIR_WAY_OFFSET_MASK        (((1 << 14) - 1) & ~0x7)
144   #define MC_RIR_WAY_RANK_MASK          0x7
145
146 /*
147  * i7core structs
148  */
149
150 #define NUM_CHANS 3
151 #define MAX_DIMMS 3             /* Max DIMMS per channel */
152 #define MAX_MCR_FUNC  4
153 #define MAX_CHAN_FUNC 3
154
155 struct i7core_info {
156         u32     mc_control;
157         u32     mc_status;
158         u32     max_dod;
159         u32     ch_map;
160 };
161
162
163 struct i7core_inject {
164         int     enable;
165
166         u32     section;
167         u32     type;
168         u32     eccmask;
169
170         /* Error address mask */
171         int channel, dimm, rank, bank, page, col;
172 };
173
174 struct i7core_channel {
175         u32             ranks;
176         u32             dimms;
177 };
178
179 struct pci_id_descr {
180         int             dev;
181         int             func;
182         int             dev_id;
183         struct pci_dev  *pdev;
184 };
185
186 struct i7core_pvt {
187         struct pci_dev          *pci_mcr[MAX_MCR_FUNC + 1];
188         struct pci_dev          *pci_ch[NUM_CHANS][MAX_CHAN_FUNC + 1];
189         struct i7core_info      info;
190         struct i7core_inject    inject;
191         struct i7core_channel   channel[NUM_CHANS];
192         int                     channels; /* Number of active channels */
193
194         int             ce_count_available;
195         unsigned long   ce_count[MAX_DIMMS];    /* ECC corrected errors counts per dimm */
196         int             last_ce_count[MAX_DIMMS];
197
198 };
199
200 /* Device name and register DID (Device ID) */
201 struct i7core_dev_info {
202         const char *ctl_name;   /* name for this device */
203         u16 fsb_mapping_errors; /* DID for the branchmap,control */
204 };
205
206 #define PCI_DESCR(device, function, device_id)  \
207         .dev = (device),                        \
208         .func = (function),                     \
209         .dev_id = (device_id)
210
211 struct pci_id_descr pci_devs[] = {
212                 /* Memory controller */
213         { PCI_DESCR(3, 0, PCI_DEVICE_ID_INTEL_I7_MCR)     },
214         { PCI_DESCR(3, 1, PCI_DEVICE_ID_INTEL_I7_MC_TAD)  },
215         { PCI_DESCR(3, 2, PCI_DEVICE_ID_INTEL_I7_MC_RAS)  }, /* if RDIMM is supported */
216         { PCI_DESCR(3, 4, PCI_DEVICE_ID_INTEL_I7_MC_TEST) },
217
218                 /* Channel 0 */
219         { PCI_DESCR(4, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH0_CTRL) },
220         { PCI_DESCR(4, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH0_ADDR) },
221         { PCI_DESCR(4, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH0_RANK) },
222         { PCI_DESCR(4, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH0_TC)   },
223
224                 /* Channel 1 */
225         { PCI_DESCR(5, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH1_CTRL) },
226         { PCI_DESCR(5, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH1_ADDR) },
227         { PCI_DESCR(5, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH1_RANK) },
228         { PCI_DESCR(5, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH1_TC)   },
229
230                 /* Channel 2 */
231         { PCI_DESCR(6, 0, PCI_DEVICE_ID_INTEL_I7_MC_CH2_CTRL) },
232         { PCI_DESCR(6, 1, PCI_DEVICE_ID_INTEL_I7_MC_CH2_ADDR) },
233         { PCI_DESCR(6, 2, PCI_DEVICE_ID_INTEL_I7_MC_CH2_RANK) },
234         { PCI_DESCR(6, 3, PCI_DEVICE_ID_INTEL_I7_MC_CH2_TC)   },
235 };
236 #define N_DEVS ARRAY_SIZE(pci_devs)
237
238 /*
239  *      pci_device_id   table for which devices we are looking for
240  * This should match the first device at pci_devs table
241  */
242 static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
243         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7_MCR)},
244         {0,}                    /* 0 terminated list. */
245 };
246
247
248 /* Table of devices attributes supported by this driver */
249 static const struct i7core_dev_info i7core_devs[] = {
250         {
251                 .ctl_name = "i7 Core",
252                 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7_MCR,
253         },
254 };
255
256 static struct edac_pci_ctl_info *i7core_pci;
257
258 /****************************************************************************
259                         Anciliary status routines
260  ****************************************************************************/
261
262         /* MC_CONTROL bits */
263 #define CH_ACTIVE(pvt, ch)      ((pvt)->info.mc_control & (1 << (8 + ch)))
264 #define ECCx8(pvt)              ((pvt)->info.mc_control & (1 << 1))
265
266         /* MC_STATUS bits */
267 #define ECC_ENABLED(pvt)        ((pvt)->info.mc_status & (1 << 3))
268 #define CH_DISABLED(pvt, ch)    ((pvt)->info.mc_status & (1 << ch))
269
270         /* MC_MAX_DOD read functions */
271 static inline int numdimms(u32 dimms)
272 {
273         return (dimms & 0x3) + 1;
274 }
275
276 static inline int numrank(u32 rank)
277 {
278         static int ranks[4] = { 1, 2, 4, -EINVAL };
279
280         return ranks[rank & 0x3];
281 }
282
283 static inline int numbank(u32 bank)
284 {
285         static int banks[4] = { 4, 8, 16, -EINVAL };
286
287         return banks[bank & 0x3];
288 }
289
290 static inline int numrow(u32 row)
291 {
292         static int rows[8] = {
293                 1 << 12, 1 << 13, 1 << 14, 1 << 15,
294                 1 << 16, -EINVAL, -EINVAL, -EINVAL,
295         };
296
297         return rows[row & 0x7];
298 }
299
300 static inline int numcol(u32 col)
301 {
302         static int cols[8] = {
303                 1 << 10, 1 << 11, 1 << 12, -EINVAL,
304         };
305         return cols[col & 0x3];
306 }
307
308
309 /****************************************************************************
310                         Memory check routines
311  ****************************************************************************/
312 static struct pci_dev *get_pdev_slot_func(int slot, int func)
313 {
314         int i;
315
316         for (i = 0; i < N_DEVS; i++) {
317                 if (!pci_devs[i].pdev)
318                         continue;
319
320                 if (PCI_SLOT(pci_devs[i].pdev->devfn) == slot &&
321                     PCI_FUNC(pci_devs[i].pdev->devfn) == func) {
322                         return pci_devs[i].pdev;
323                 }
324         }
325
326         return NULL;
327 }
328
329 static int i7core_get_active_channels(int *channels, int *csrows)
330 {
331         struct pci_dev *pdev = NULL;
332         int i, j;
333         u32 status, control;
334
335         *channels = 0;
336         *csrows = 0;
337
338         pdev = get_pdev_slot_func(3, 0);
339         if (!pdev) {
340                 i7core_printk(KERN_ERR, "Couldn't find fn 3.0!!!\n");
341                 return -ENODEV;
342         }
343
344         /* Device 3 function 0 reads */
345         pci_read_config_dword(pdev, MC_STATUS, &status);
346         pci_read_config_dword(pdev, MC_CONTROL, &control);
347
348         for (i = 0; i < NUM_CHANS; i++) {
349                 u32 dimm_dod[3];
350                 /* Check if the channel is active */
351                 if (!(control & (1 << (8 + i))))
352                         continue;
353
354                 /* Check if the channel is disabled */
355                 if (status & (1 << i))
356                         continue;
357
358                 pdev = get_pdev_slot_func(i + 4, 1);
359                 if (!pdev) {
360                         i7core_printk(KERN_ERR, "Couldn't find fn %d.%d!!!\n",
361                                       i + 4, 1);
362                         return -ENODEV;
363                 }
364                 /* Devices 4-6 function 1 */
365                 pci_read_config_dword(pdev,
366                                 MC_DOD_CH_DIMM0, &dimm_dod[0]);
367                 pci_read_config_dword(pdev,
368                                 MC_DOD_CH_DIMM1, &dimm_dod[1]);
369                 pci_read_config_dword(pdev,
370                                 MC_DOD_CH_DIMM2, &dimm_dod[2]);
371
372                 (*channels)++;
373
374                 for (j = 0; j < 3; j++) {
375                         if (!DIMM_PRESENT(dimm_dod[j]))
376                                 continue;
377                         (*csrows)++;
378                 }
379         }
380
381         debugf0("Number of active channels: %d\n", *channels);
382
383         return 0;
384 }
385
386 static int get_dimm_config(struct mem_ctl_info *mci)
387 {
388         struct i7core_pvt *pvt = mci->pvt_info;
389         struct csrow_info *csr;
390         struct pci_dev *pdev;
391         int i, j, csrow = 0;
392         unsigned long last_page = 0;
393         enum edac_type mode;
394         enum mem_type mtype;
395
396         /* Get data from the MC register, function 0 */
397         pdev = pvt->pci_mcr[0];
398         if (!pdev)
399                 return -ENODEV;
400
401         /* Device 3 function 0 reads */
402         pci_read_config_dword(pdev, MC_CONTROL, &pvt->info.mc_control);
403         pci_read_config_dword(pdev, MC_STATUS, &pvt->info.mc_status);
404         pci_read_config_dword(pdev, MC_MAX_DOD, &pvt->info.max_dod);
405         pci_read_config_dword(pdev, MC_CHANNEL_MAPPER, &pvt->info.ch_map);
406
407         debugf0("MC control=0x%08x status=0x%08x dod=0x%08x map=0x%08x\n",
408                 pvt->info.mc_control, pvt->info.mc_status,
409                 pvt->info.max_dod, pvt->info.ch_map);
410
411         if (ECC_ENABLED(pvt)) {
412                 debugf0("ECC enabled with x%d SDCC\n", ECCx8(pvt) ? 8 : 4);
413                 if (ECCx8(pvt))
414                         mode = EDAC_S8ECD8ED;
415                 else
416                         mode = EDAC_S4ECD4ED;
417         } else {
418                 debugf0("ECC disabled\n");
419                 mode = EDAC_NONE;
420         }
421
422         /* FIXME: need to handle the error codes */
423         debugf0("DOD Max limits: DIMMS: %d, %d-ranked, %d-banked\n",
424                 numdimms(pvt->info.max_dod),
425                 numrank(pvt->info.max_dod >> 2),
426                 numbank(pvt->info.max_dod >> 4));
427         debugf0("DOD Max rows x colums = 0x%x x 0x%x\n",
428                 numrow(pvt->info.max_dod >> 6),
429                 numcol(pvt->info.max_dod >> 9));
430
431         debugf0("Memory channel configuration:\n");
432
433         for (i = 0; i < NUM_CHANS; i++) {
434                 u32 data, dimm_dod[3], value[8];
435
436                 if (!CH_ACTIVE(pvt, i)) {
437                         debugf0("Channel %i is not active\n", i);
438                         continue;
439                 }
440                 if (CH_DISABLED(pvt, i)) {
441                         debugf0("Channel %i is disabled\n", i);
442                         continue;
443                 }
444
445                 /* Devices 4-6 function 0 */
446                 pci_read_config_dword(pvt->pci_ch[i][0],
447                                 MC_CHANNEL_DIMM_INIT_PARAMS, &data);
448
449                 pvt->channel[i].ranks = (data & QUAD_RANK_PRESENT) ? 4 : 2;
450
451                 if (data & REGISTERED_DIMM)
452                         mtype = MEM_RDDR3;
453                 else
454                         mtype = MEM_DDR3;
455 #if 0
456                 if (data & THREE_DIMMS_PRESENT)
457                         pvt->channel[i].dimms = 3;
458                 else if (data & SINGLE_QUAD_RANK_PRESENT)
459                         pvt->channel[i].dimms = 1;
460                 else
461                         pvt->channel[i].dimms = 2;
462 #endif
463
464                 /* Devices 4-6 function 1 */
465                 pci_read_config_dword(pvt->pci_ch[i][1],
466                                 MC_DOD_CH_DIMM0, &dimm_dod[0]);
467                 pci_read_config_dword(pvt->pci_ch[i][1],
468                                 MC_DOD_CH_DIMM1, &dimm_dod[1]);
469                 pci_read_config_dword(pvt->pci_ch[i][1],
470                                 MC_DOD_CH_DIMM2, &dimm_dod[2]);
471
472                 debugf0("Ch%d phy rd%d, wr%d (0x%08x): "
473                         "%d ranks, %cDIMMs\n",
474                         i,
475                         RDLCH(pvt->info.ch_map, i), WRLCH(pvt->info.ch_map, i),
476                         data,
477                         pvt->channel[i].ranks,
478                         (data & REGISTERED_DIMM) ? 'R' : 'U');
479
480                 for (j = 0; j < 3; j++) {
481                         u32 banks, ranks, rows, cols;
482                         u32 size, npages;
483
484                         if (!DIMM_PRESENT(dimm_dod[j]))
485                                 continue;
486
487                         banks = numbank(MC_DOD_NUMBANK(dimm_dod[j]));
488                         ranks = numrank(MC_DOD_NUMRANK(dimm_dod[j]));
489                         rows = numrow(MC_DOD_NUMROW(dimm_dod[j]));
490                         cols = numcol(MC_DOD_NUMCOL(dimm_dod[j]));
491
492                         /* DDR3 has 8 I/O banks */
493                         size = (rows * cols * banks * ranks) >> (20 - 3);
494
495                         pvt->channel[i].dimms++;
496
497                         debugf0("\tdimm %d (0x%08x) %d Mb offset: %x, "
498                                 "numbank: %d,\n\t\t"
499                                 "numrank: %d, numrow: %#x, numcol: %#x\n",
500                                 j, dimm_dod[j], size,
501                                 RANKOFFSET(dimm_dod[j]),
502                                 banks, ranks, rows, cols);
503
504 #if PAGE_SHIFT > 20
505                         npages = size >> (PAGE_SHIFT - 20);
506 #else
507                         npages = size << (20 - PAGE_SHIFT);
508 #endif
509
510                         csr = &mci->csrows[csrow];
511                         csr->first_page = last_page + 1;
512                         last_page += npages;
513                         csr->last_page = last_page;
514                         csr->nr_pages = npages;
515
516                         csr->page_mask = 0;
517                         csr->grain = 8;
518                         csr->csrow_idx = csrow;
519                         csr->nr_channels = 1;
520
521                         csr->channels[0].chan_idx = i;
522                         csr->channels[0].ce_count = 0;
523
524                         switch (banks) {
525                         case 4:
526                                 csr->dtype = DEV_X4;
527                                 break;
528                         case 8:
529                                 csr->dtype = DEV_X8;
530                                 break;
531                         case 16:
532                                 csr->dtype = DEV_X16;
533                                 break;
534                         default:
535                                 csr->dtype = DEV_UNKNOWN;
536                         }
537
538                         csr->edac_mode = mode;
539                         csr->mtype = mtype;
540
541                         csrow++;
542                 }
543
544                 pci_read_config_dword(pdev, MC_SAG_CH_0, &value[0]);
545                 pci_read_config_dword(pdev, MC_SAG_CH_1, &value[1]);
546                 pci_read_config_dword(pdev, MC_SAG_CH_2, &value[2]);
547                 pci_read_config_dword(pdev, MC_SAG_CH_3, &value[3]);
548                 pci_read_config_dword(pdev, MC_SAG_CH_4, &value[4]);
549                 pci_read_config_dword(pdev, MC_SAG_CH_5, &value[5]);
550                 pci_read_config_dword(pdev, MC_SAG_CH_6, &value[6]);
551                 pci_read_config_dword(pdev, MC_SAG_CH_7, &value[7]);
552                 debugf0("\t[%i] DIVBY3\tREMOVED\tOFFSET\n", i);
553                 for (j = 0; j < 8; j++)
554                         debugf0("\t\t%#x\t%#x\t%#x\n",
555                                 (value[j] >> 27) & 0x1,
556                                 (value[j] >> 24) & 0x7,
557                                 (value[j] && ((1 << 24) - 1)));
558         }
559
560         return 0;
561 }
562
563 /****************************************************************************
564                         Error insertion routines
565  ****************************************************************************/
566
567 /* The i7core has independent error injection features per channel.
568    However, to have a simpler code, we don't allow enabling error injection
569    on more than one channel.
570    Also, since a change at an inject parameter will be applied only at enable,
571    we're disabling error injection on all write calls to the sysfs nodes that
572    controls the error code injection.
573  */
574 static int disable_inject(struct mem_ctl_info *mci)
575 {
576         struct i7core_pvt *pvt = mci->pvt_info;
577
578         pvt->inject.enable = 0;
579
580         if (!pvt->pci_ch[pvt->inject.channel][0])
581                 return -ENODEV;
582
583         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
584                                 MC_CHANNEL_ERROR_MASK, 0);
585
586         return 0;
587 }
588
589 /*
590  * i7core inject inject.section
591  *
592  *      accept and store error injection inject.section value
593  *      bit 0 - refers to the lower 32-byte half cacheline
594  *      bit 1 - refers to the upper 32-byte half cacheline
595  */
596 static ssize_t i7core_inject_section_store(struct mem_ctl_info *mci,
597                                            const char *data, size_t count)
598 {
599         struct i7core_pvt *pvt = mci->pvt_info;
600         unsigned long value;
601         int rc;
602
603         if (pvt->inject.enable)
604                 disable_inject(mci);
605
606         rc = strict_strtoul(data, 10, &value);
607         if ((rc < 0) || (value > 3))
608                 return 0;
609
610         pvt->inject.section = (u32) value;
611         return count;
612 }
613
614 static ssize_t i7core_inject_section_show(struct mem_ctl_info *mci,
615                                               char *data)
616 {
617         struct i7core_pvt *pvt = mci->pvt_info;
618         return sprintf(data, "0x%08x\n", pvt->inject.section);
619 }
620
621 /*
622  * i7core inject.type
623  *
624  *      accept and store error injection inject.section value
625  *      bit 0 - repeat enable - Enable error repetition
626  *      bit 1 - inject ECC error
627  *      bit 2 - inject parity error
628  */
629 static ssize_t i7core_inject_type_store(struct mem_ctl_info *mci,
630                                         const char *data, size_t count)
631 {
632         struct i7core_pvt *pvt = mci->pvt_info;
633         unsigned long value;
634         int rc;
635
636         if (pvt->inject.enable)
637                 disable_inject(mci);
638
639         rc = strict_strtoul(data, 10, &value);
640         if ((rc < 0) || (value > 7))
641                 return 0;
642
643         pvt->inject.type = (u32) value;
644         return count;
645 }
646
647 static ssize_t i7core_inject_type_show(struct mem_ctl_info *mci,
648                                               char *data)
649 {
650         struct i7core_pvt *pvt = mci->pvt_info;
651         return sprintf(data, "0x%08x\n", pvt->inject.type);
652 }
653
654 /*
655  * i7core_inject_inject.eccmask_store
656  *
657  * The type of error (UE/CE) will depend on the inject.eccmask value:
658  *   Any bits set to a 1 will flip the corresponding ECC bit
659  *   Correctable errors can be injected by flipping 1 bit or the bits within
660  *   a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
661  *   23:16 and 31:24). Flipping bits in two symbol pairs will cause an
662  *   uncorrectable error to be injected.
663  */
664 static ssize_t i7core_inject_eccmask_store(struct mem_ctl_info *mci,
665                                         const char *data, size_t count)
666 {
667         struct i7core_pvt *pvt = mci->pvt_info;
668         unsigned long value;
669         int rc;
670
671         if (pvt->inject.enable)
672                 disable_inject(mci);
673
674         rc = strict_strtoul(data, 10, &value);
675         if (rc < 0)
676                 return 0;
677
678         pvt->inject.eccmask = (u32) value;
679         return count;
680 }
681
682 static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
683                                               char *data)
684 {
685         struct i7core_pvt *pvt = mci->pvt_info;
686         return sprintf(data, "0x%08x\n", pvt->inject.eccmask);
687 }
688
689 /*
690  * i7core_addrmatch
691  *
692  * The type of error (UE/CE) will depend on the inject.eccmask value:
693  *   Any bits set to a 1 will flip the corresponding ECC bit
694  *   Correctable errors can be injected by flipping 1 bit or the bits within
695  *   a symbol pair (2 consecutive aligned 8-bit pairs - i.e. 7:0 and 15:8 or
696  *   23:16 and 31:24). Flipping bits in two symbol pairs will cause an
697  *   uncorrectable error to be injected.
698  */
699 static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
700                                         const char *data, size_t count)
701 {
702         struct i7core_pvt *pvt = mci->pvt_info;
703         char *cmd, *val;
704         long value;
705         int rc;
706
707         if (pvt->inject.enable)
708                 disable_inject(mci);
709
710         do {
711                 cmd = strsep((char **) &data, ":");
712                 if (!cmd)
713                         break;
714                 val = strsep((char **) &data, " \n\t");
715                 if (!val)
716                         return cmd - data;
717
718                 if (!strcasecmp(val, "any"))
719                         value = -1;
720                 else {
721                         rc = strict_strtol(val, 10, &value);
722                         if ((rc < 0) || (value < 0))
723                                 return cmd - data;
724                 }
725
726                 if (!strcasecmp(cmd, "channel")) {
727                         if (value < 3)
728                                 pvt->inject.channel = value;
729                         else
730                                 return cmd - data;
731                 } else if (!strcasecmp(cmd, "dimm")) {
732                         if (value < 4)
733                                 pvt->inject.dimm = value;
734                         else
735                                 return cmd - data;
736                 } else if (!strcasecmp(cmd, "rank")) {
737                         if (value < 4)
738                                 pvt->inject.rank = value;
739                         else
740                                 return cmd - data;
741                 } else if (!strcasecmp(cmd, "bank")) {
742                         if (value < 4)
743                                 pvt->inject.bank = value;
744                         else
745                                 return cmd - data;
746                 } else if (!strcasecmp(cmd, "page")) {
747                         if (value <= 0xffff)
748                                 pvt->inject.page = value;
749                         else
750                                 return cmd - data;
751                 } else if (!strcasecmp(cmd, "col") ||
752                            !strcasecmp(cmd, "column")) {
753                         if (value <= 0x3fff)
754                                 pvt->inject.col = value;
755                         else
756                                 return cmd - data;
757                 }
758         } while (1);
759
760         return count;
761 }
762
763 static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
764                                               char *data)
765 {
766         struct i7core_pvt *pvt = mci->pvt_info;
767         char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
768
769         if (pvt->inject.channel < 0)
770                 sprintf(channel, "any");
771         else
772                 sprintf(channel, "%d", pvt->inject.channel);
773         if (pvt->inject.dimm < 0)
774                 sprintf(dimm, "any");
775         else
776                 sprintf(dimm, "%d", pvt->inject.dimm);
777         if (pvt->inject.bank < 0)
778                 sprintf(bank, "any");
779         else
780                 sprintf(bank, "%d", pvt->inject.bank);
781         if (pvt->inject.rank < 0)
782                 sprintf(rank, "any");
783         else
784                 sprintf(rank, "%d", pvt->inject.rank);
785         if (pvt->inject.page < 0)
786                 sprintf(page, "any");
787         else
788                 sprintf(page, "0x%04x", pvt->inject.page);
789         if (pvt->inject.col < 0)
790                 sprintf(col, "any");
791         else
792                 sprintf(col, "0x%04x", pvt->inject.col);
793
794         return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
795                              "rank: %s\npage: %s\ncolumn: %s\n",
796                        channel, dimm, bank, rank, page, col);
797 }
798
799 /*
800  * This routine prepares the Memory Controller for error injection.
801  * The error will be injected when some process tries to write to the
802  * memory that matches the given criteria.
803  * The criteria can be set in terms of a mask where dimm, rank, bank, page
804  * and col can be specified.
805  * A -1 value for any of the mask items will make the MCU to ignore
806  * that matching criteria for error injection.
807  *
808  * It should be noticed that the error will only happen after a write operation
809  * on a memory that matches the condition. if REPEAT_EN is not enabled at
810  * inject mask, then it will produce just one error. Otherwise, it will repeat
811  * until the injectmask would be cleaned.
812  *
813  * FIXME: This routine assumes that MAXNUMDIMMS value of MC_MAX_DOD
814  *    is reliable enough to check if the MC is using the
815  *    three channels. However, this is not clear at the datasheet.
816  */
817 static ssize_t i7core_inject_enable_store(struct mem_ctl_info *mci,
818                                        const char *data, size_t count)
819 {
820         struct i7core_pvt *pvt = mci->pvt_info;
821         u32 injectmask;
822         u64 mask = 0;
823         int  rc;
824         long enable;
825
826         if (!pvt->pci_ch[pvt->inject.channel][0])
827                 return 0;
828
829         rc = strict_strtoul(data, 10, &enable);
830         if ((rc < 0))
831                 return 0;
832
833         if (enable) {
834                 pvt->inject.enable = 1;
835         } else {
836                 disable_inject(mci);
837                 return count;
838         }
839
840         /* Sets pvt->inject.dimm mask */
841         if (pvt->inject.dimm < 0)
842                 mask |= 1L << 41;
843         else {
844                 if (pvt->channel[pvt->inject.channel].dimms > 2)
845                         mask |= (pvt->inject.dimm & 0x3L) << 35;
846                 else
847                         mask |= (pvt->inject.dimm & 0x1L) << 36;
848         }
849
850         /* Sets pvt->inject.rank mask */
851         if (pvt->inject.rank < 0)
852                 mask |= 1L << 40;
853         else {
854                 if (pvt->channel[pvt->inject.channel].dimms > 2)
855                         mask |= (pvt->inject.rank & 0x1L) << 34;
856                 else
857                         mask |= (pvt->inject.rank & 0x3L) << 34;
858         }
859
860         /* Sets pvt->inject.bank mask */
861         if (pvt->inject.bank < 0)
862                 mask |= 1L << 39;
863         else
864                 mask |= (pvt->inject.bank & 0x15L) << 30;
865
866         /* Sets pvt->inject.page mask */
867         if (pvt->inject.page < 0)
868                 mask |= 1L << 38;
869         else
870                 mask |= (pvt->inject.page & 0xffffL) << 14;
871
872         /* Sets pvt->inject.column mask */
873         if (pvt->inject.col < 0)
874                 mask |= 1L << 37;
875         else
876                 mask |= (pvt->inject.col & 0x3fffL);
877
878 #if USE_QWORD
879         pci_write_config_qword(pvt->pci_ch[pvt->inject.channel][0],
880                                MC_CHANNEL_ADDR_MATCH, mask);
881 #else
882         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
883                                MC_CHANNEL_ADDR_MATCH, mask);
884         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
885                                MC_CHANNEL_ADDR_MATCH + 4, mask >> 32L);
886 #endif
887
888 #if 1
889 #if USE_QWORD
890         u64 rdmask;
891         pci_read_config_qword(pvt->pci_ch[pvt->inject.channel][0],
892                                MC_CHANNEL_ADDR_MATCH, &rdmask);
893         debugf0("Inject addr match write 0x%016llx, read: 0x%016llx\n",
894                 mask, rdmask);
895 #else
896         u32 rdmask1, rdmask2;
897
898         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
899                                MC_CHANNEL_ADDR_MATCH, &rdmask1);
900         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
901                                MC_CHANNEL_ADDR_MATCH + 4, &rdmask2);
902
903         debugf0("Inject addr match write 0x%016llx, read: 0x%08x%08x\n",
904                 mask, rdmask1, rdmask2);
905 #endif
906 #endif
907
908         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
909                                MC_CHANNEL_ERROR_MASK, pvt->inject.eccmask);
910
911         /*
912          * bit    0: REPEAT_EN
913          * bits 1-2: MASK_HALF_CACHELINE
914          * bit    3: INJECT_ECC
915          * bit    4: INJECT_ADDR_PARITY
916          */
917
918         injectmask = (pvt->inject.type & 1) |
919                      (pvt->inject.section & 0x3) << 1 |
920                      (pvt->inject.type & 0x6) << (3 - 1);
921
922         pci_write_config_dword(pvt->pci_ch[pvt->inject.channel][0],
923                                MC_CHANNEL_ERROR_MASK, injectmask);
924
925         debugf0("Error inject addr match 0x%016llx, ecc 0x%08x,"
926                 " inject 0x%08x\n",
927                 mask, pvt->inject.eccmask, injectmask);
928
929
930
931         return count;
932 }
933
934 static ssize_t i7core_inject_enable_show(struct mem_ctl_info *mci,
935                                         char *data)
936 {
937         struct i7core_pvt *pvt = mci->pvt_info;
938         u32 injectmask;
939
940         pci_read_config_dword(pvt->pci_ch[pvt->inject.channel][0],
941                                MC_CHANNEL_ERROR_MASK, &injectmask);
942
943         debugf0("Inject error read: 0x%018x\n", injectmask);
944
945         if (injectmask & 0x0c)
946                 pvt->inject.enable = 1;
947
948         return sprintf(data, "%d\n", pvt->inject.enable);
949 }
950
951 static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
952 {
953         struct i7core_pvt *pvt = mci->pvt_info;
954
955         if (!pvt->ce_count_available)
956                 return sprintf(data, "unavailable\n");
957
958         return sprintf(data, "dimm0: %lu\ndimm1: %lu\ndimm2: %lu\n",
959                         pvt->ce_count[0],
960                         pvt->ce_count[1],
961                         pvt->ce_count[2]);
962 }
963
964 /*
965  * Sysfs struct
966  */
967 static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
968
969         {
970                 .attr = {
971                         .name = "inject_section",
972                         .mode = (S_IRUGO | S_IWUSR)
973                 },
974                 .show  = i7core_inject_section_show,
975                 .store = i7core_inject_section_store,
976         }, {
977                 .attr = {
978                         .name = "inject_type",
979                         .mode = (S_IRUGO | S_IWUSR)
980                 },
981                 .show  = i7core_inject_type_show,
982                 .store = i7core_inject_type_store,
983         }, {
984                 .attr = {
985                         .name = "inject_eccmask",
986                         .mode = (S_IRUGO | S_IWUSR)
987                 },
988                 .show  = i7core_inject_eccmask_show,
989                 .store = i7core_inject_eccmask_store,
990         }, {
991                 .attr = {
992                         .name = "inject_addrmatch",
993                         .mode = (S_IRUGO | S_IWUSR)
994                 },
995                 .show  = i7core_inject_addrmatch_show,
996                 .store = i7core_inject_addrmatch_store,
997         }, {
998                 .attr = {
999                         .name = "inject_enable",
1000                         .mode = (S_IRUGO | S_IWUSR)
1001                 },
1002                 .show  = i7core_inject_enable_show,
1003                 .store = i7core_inject_enable_store,
1004         }, {
1005                 .attr = {
1006                         .name = "corrected_error_counts",
1007                         .mode = (S_IRUGO | S_IWUSR)
1008                 },
1009                 .show  = i7core_ce_regs_show,
1010                 .store = NULL,
1011         },
1012 };
1013
1014 /****************************************************************************
1015         Device initialization routines: put/get, init/exit
1016  ****************************************************************************/
1017
1018 /*
1019  *      i7core_put_devices      'put' all the devices that we have
1020  *                              reserved via 'get'
1021  */
1022 static void i7core_put_devices(void)
1023 {
1024         int i;
1025
1026         for (i = 0; i < N_DEVS; i++)
1027                 pci_dev_put(pci_devs[i].pdev);
1028 }
1029
1030 /*
1031  *      i7core_get_devices      Find and perform 'get' operation on the MCH's
1032  *                      device/functions we want to reference for this driver
1033  *
1034  *                      Need to 'get' device 16 func 1 and func 2
1035  */
1036 static int i7core_get_devices(void)
1037 {
1038         int rc, i;
1039         struct pci_dev *pdev = NULL;
1040
1041         for (i = 0; i < N_DEVS; i++) {
1042                 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
1043                                         pci_devs[i].dev_id, NULL);
1044                 if (likely(pdev))
1045                         pci_devs[i].pdev = pdev;
1046                 else {
1047                         i7core_printk(KERN_ERR,
1048                                 "Device not found: PCI ID %04x:%04x "
1049                                 "(dev %d, func %d)\n",
1050                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1051                                 pci_devs[i].dev, pci_devs[i].func);
1052
1053                         /* Dev 3 function 2 only exists on chips with RDIMMs */
1054                         if ((pci_devs[i].dev == 3) && (pci_devs[i].func == 2))
1055                                 continue;
1056
1057                         /* End of list, leave */
1058                         rc = -ENODEV;
1059                         goto error;
1060                 }
1061
1062                 /* Sanity check */
1063                 if (unlikely(PCI_SLOT(pdev->devfn) != pci_devs[i].dev ||
1064                              PCI_FUNC(pdev->devfn) != pci_devs[i].func)) {
1065                         i7core_printk(KERN_ERR,
1066                                 "Device PCI ID %04x:%04x "
1067                                 "has fn %d.%d instead of fn %d.%d\n",
1068                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1069                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
1070                                 pci_devs[i].dev, pci_devs[i].func);
1071                         rc = -EINVAL;
1072                         goto error;
1073                 }
1074
1075                 /* Be sure that the device is enabled */
1076                 rc = pci_enable_device(pdev);
1077                 if (unlikely(rc < 0)) {
1078                         i7core_printk(KERN_ERR,
1079                                 "Couldn't enable PCI ID %04x:%04x "
1080                                 "fn %d.%d\n",
1081                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1082                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1083                         goto error;
1084                 }
1085
1086                 i7core_printk(KERN_INFO,
1087                                 "Registered device %0x:%0x fn %d.%d\n",
1088                                 PCI_VENDOR_ID_INTEL, pci_devs[i].dev_id,
1089                                 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1090         }
1091
1092         return 0;
1093
1094 error:
1095         i7core_put_devices();
1096         return -EINVAL;
1097 }
1098
1099 static int mci_bind_devs(struct mem_ctl_info *mci)
1100 {
1101         struct i7core_pvt *pvt = mci->pvt_info;
1102         struct pci_dev *pdev;
1103         int i, func, slot;
1104
1105         for (i = 0; i < N_DEVS; i++) {
1106                 pdev = pci_devs[i].pdev;
1107                 if (!pdev)
1108                         continue;
1109
1110                 func = PCI_FUNC(pdev->devfn);
1111                 slot = PCI_SLOT(pdev->devfn);
1112                 if (slot == 3) {
1113                         if (unlikely(func > MAX_MCR_FUNC))
1114                                 goto error;
1115                         pvt->pci_mcr[func] = pdev;
1116                 } else if (likely(slot >= 4 && slot < 4 + NUM_CHANS)) {
1117                         if (unlikely(func > MAX_CHAN_FUNC))
1118                                 goto error;
1119                         pvt->pci_ch[slot - 4][func] = pdev;
1120                 } else
1121                         goto error;
1122
1123                 debugf0("Associated fn %d.%d, dev = %p\n",
1124                         PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev);
1125         }
1126         return 0;
1127
1128 error:
1129         i7core_printk(KERN_ERR, "Device %d, function %d "
1130                       "is out of the expected range\n",
1131                       slot, func);
1132         return -EINVAL;
1133 }
1134
1135 /****************************************************************************
1136                         Error check routines
1137  ****************************************************************************/
1138
1139 /* This function is based on the device 3 function 4 registers as described on:
1140  * Intel Xeon Processor 5500 Series Datasheet Volume 2
1141  *      http://www.intel.com/Assets/PDF/datasheet/321322.pdf
1142  * also available at:
1143  *      http://www.arrownac.com/manufacturers/intel/s/nehalem/5500-datasheet-v2.pdf
1144  */
1145 static void check_mc_test_err(struct mem_ctl_info *mci)
1146 {
1147         struct i7core_pvt *pvt = mci->pvt_info;
1148         u32 rcv1, rcv0;
1149         int new0, new1, new2;
1150
1151         if (!pvt->pci_mcr[4]) {
1152                 debugf0("%s MCR registers not found\n",__func__);
1153                 return;
1154         }
1155
1156         /* Corrected error reads */
1157         pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV1, &rcv1);
1158         pci_read_config_dword(pvt->pci_mcr[4], MC_TEST_ERR_RCV0, &rcv0);
1159
1160         /* Store the new values */
1161         new2 = DIMM2_COR_ERR(rcv1);
1162         new1 = DIMM1_COR_ERR(rcv0);
1163         new0 = DIMM0_COR_ERR(rcv0);
1164
1165         debugf2("%s CE rcv1=0x%08x rcv0=0x%08x, %d %d %d\n",
1166                 (pvt->ce_count_available ? "UPDATE" : "READ"),
1167                 rcv1, rcv0, new0, new1, new2);
1168
1169         /* Updates CE counters if it is not the first time here */
1170         if (pvt->ce_count_available) {
1171                 /* Updates CE counters */
1172                 int add0, add1, add2;
1173
1174                 add2 = new2 - pvt->last_ce_count[2];
1175                 add1 = new1 - pvt->last_ce_count[1];
1176                 add0 = new0 - pvt->last_ce_count[0];
1177
1178                 if (add2 < 0)
1179                         add2 += 0x7fff;
1180                 pvt->ce_count[2] += add2;
1181
1182                 if (add1 < 0)
1183                         add1 += 0x7fff;
1184                 pvt->ce_count[1] += add1;
1185
1186                 if (add0 < 0)
1187                         add0 += 0x7fff;
1188                 pvt->ce_count[0] += add0;
1189         } else
1190                 pvt->ce_count_available = 1;
1191
1192         /* Store the new values */
1193         pvt->last_ce_count[2] = new2;
1194         pvt->last_ce_count[1] = new1;
1195         pvt->last_ce_count[0] = new0;
1196 }
1197
1198 /*
1199  *      i7core_check_error      Retrieve and process errors reported by the
1200  *                              hardware. Called by the Core module.
1201  */
1202 static void i7core_check_error(struct mem_ctl_info *mci)
1203 {
1204         check_mc_test_err(mci);
1205 }
1206
1207 /*
1208  *      i7core_probe    Probe for ONE instance of device to see if it is
1209  *                      present.
1210  *      return:
1211  *              0 for FOUND a device
1212  *              < 0 for error code
1213  */
1214 static int __devinit i7core_probe(struct pci_dev *pdev,
1215                                   const struct pci_device_id *id)
1216 {
1217         struct mem_ctl_info *mci;
1218         struct i7core_pvt *pvt;
1219         int num_channels;
1220         int num_csrows;
1221         int dev_idx = id->driver_data;
1222         int rc;
1223
1224         if (unlikely(dev_idx >= ARRAY_SIZE(i7core_devs)))
1225                 return -EINVAL;
1226
1227         /* get the pci devices we want to reserve for our use */
1228         rc = i7core_get_devices();
1229         if (unlikely(rc < 0))
1230                 return rc;
1231
1232         /* Check the number of active and not disabled channels */
1233         rc = i7core_get_active_channels(&num_channels, &num_csrows);
1234         if (unlikely(rc < 0))
1235                 goto fail0;
1236
1237         /* allocate a new MC control structure */
1238         mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1239         if (unlikely(!mci)) {
1240                 rc = -ENOMEM;
1241                 goto fail0;
1242         }
1243
1244         debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1245
1246         mci->dev = &pdev->dev;  /* record ptr to the generic device */
1247
1248         pvt = mci->pvt_info;
1249         memset(pvt, 0, sizeof(*pvt));
1250
1251         mci->mc_idx = 0;
1252         /*
1253          * FIXME: how to handle RDDR3 at MCI level? It is possible to have
1254          * Mixed RDDR3/UDDR3 with Nehalem, provided that they are on different
1255          * memory channels
1256          */
1257         mci->mtype_cap = MEM_FLAG_DDR3;
1258         mci->edac_ctl_cap = EDAC_FLAG_NONE;
1259         mci->edac_cap = EDAC_FLAG_NONE;
1260         mci->mod_name = "i7core_edac.c";
1261         mci->mod_ver = I7CORE_REVISION;
1262         mci->ctl_name = i7core_devs[dev_idx].ctl_name;
1263         mci->dev_name = pci_name(pdev);
1264         mci->ctl_page_to_phys = NULL;
1265         mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
1266         /* Set the function pointer to an actual operation function */
1267         mci->edac_check = i7core_check_error;
1268
1269         /* Store pci devices at mci for faster access */
1270         rc = mci_bind_devs(mci);
1271         if (unlikely(rc < 0))
1272                 goto fail1;
1273
1274         /* Get dimm basic config */
1275         get_dimm_config(mci);
1276
1277         /* add this new MC control structure to EDAC's list of MCs */
1278         if (unlikely(edac_mc_add_mc(mci))) {
1279                 debugf0("MC: " __FILE__
1280                         ": %s(): failed edac_mc_add_mc()\n", __func__);
1281                 /* FIXME: perhaps some code should go here that disables error
1282                  * reporting if we just enabled it
1283                  */
1284
1285                 rc = -EINVAL;
1286                 goto fail1;
1287         }
1288
1289         /* allocating generic PCI control info */
1290         i7core_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1291         if (unlikely(!i7core_pci)) {
1292                 printk(KERN_WARNING
1293                         "%s(): Unable to create PCI control\n",
1294                         __func__);
1295                 printk(KERN_WARNING
1296                         "%s(): PCI error report via EDAC not setup\n",
1297                         __func__);
1298         }
1299
1300         /* Default error mask is any memory */
1301         pvt->inject.channel = 0;
1302         pvt->inject.dimm = -1;
1303         pvt->inject.rank = -1;
1304         pvt->inject.bank = -1;
1305         pvt->inject.page = -1;
1306         pvt->inject.col = -1;
1307
1308         i7core_printk(KERN_INFO, "Driver loaded.\n");
1309
1310         return 0;
1311
1312 fail1:
1313         edac_mc_free(mci);
1314
1315 fail0:
1316         i7core_put_devices();
1317         return rc;
1318 }
1319
1320 /*
1321  *      i7core_remove   destructor for one instance of device
1322  *
1323  */
1324 static void __devexit i7core_remove(struct pci_dev *pdev)
1325 {
1326         struct mem_ctl_info *mci;
1327
1328         debugf0(__FILE__ ": %s()\n", __func__);
1329
1330         if (i7core_pci)
1331                 edac_pci_release_generic_ctl(i7core_pci);
1332
1333         mci = edac_mc_del_mc(&pdev->dev);
1334
1335         if (!mci)
1336                 return;
1337
1338         /* retrieve references to resources, and free those resources */
1339         i7core_put_devices();
1340
1341         edac_mc_free(mci);
1342 }
1343
1344 MODULE_DEVICE_TABLE(pci, i7core_pci_tbl);
1345
1346 /*
1347  *      i7core_driver   pci_driver structure for this module
1348  *
1349  */
1350 static struct pci_driver i7core_driver = {
1351         .name     = "i7core_edac",
1352         .probe    = i7core_probe,
1353         .remove   = __devexit_p(i7core_remove),
1354         .id_table = i7core_pci_tbl,
1355 };
1356
1357 /*
1358  *      i7core_init             Module entry function
1359  *                      Try to initialize this module for its devices
1360  */
1361 static int __init i7core_init(void)
1362 {
1363         int pci_rc;
1364
1365         debugf2("MC: " __FILE__ ": %s()\n", __func__);
1366
1367         /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1368         opstate_init();
1369
1370         pci_rc = pci_register_driver(&i7core_driver);
1371
1372         return (pci_rc < 0) ? pci_rc : 0;
1373 }
1374
1375 /*
1376  *      i7core_exit()   Module exit function
1377  *                      Unregister the driver
1378  */
1379 static void __exit i7core_exit(void)
1380 {
1381         debugf2("MC: " __FILE__ ": %s()\n", __func__);
1382         pci_unregister_driver(&i7core_driver);
1383 }
1384
1385 module_init(i7core_init);
1386 module_exit(i7core_exit);
1387
1388 MODULE_LICENSE("GPL");
1389 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1390 MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1391 MODULE_DESCRIPTION("MC Driver for Intel i7 Core memory controllers - "
1392                    I7CORE_REVISION);
1393
1394 module_param(edac_op_state, int, 0444);
1395 MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");