aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-24 16:06:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-24 16:06:57 -0400
commit8de547e1824437f3c6af180d3ed2162fa4b3f389 (patch)
tree1318eea19b4b6a563ea2bbe95cf9b2ad10f92b43
parent76c39e4fef73e42777c27d6b87a04f89ebd0ef66 (diff)
parente6649cc62949f1ed473bf1131fa425cfe72d3f64 (diff)
Merge branch 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/edac
* 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/edac: (25 commits) i7300_edac: Properly initialize per-csrow memory size V4L/DVB: i7300_edac: better initialize page counts MAINTAINERS: Add maintainer for i7300-edac driver i7300-edac: CodingStyle cleanup i7300_edac: Improve comments i7300_edac: Cleanup: reorganize the file contents i7300_edac: Properly detect channel on CE errors i7300_edac: enrich FBD error info for corrected errors i7300_edac: enrich FBD error info for fatal errors i7300_edac: pre-allocate a buffer used to prepare err messages i7300_edac: Fix MTR x4/x8 detection logic i7300_edac: Make the debug messages coherent with the others i7300_edac: Cleanup: remove get_error_info logic i7300_edac: Add a code to cleanup error registers i7300_edac: Add support for reporting FBD errors i7300_edac: Properly detect the type of error correction i7300_edac: Detect if the device is on single mode i7300_edac: Adds detection for enhanced scrub mode on x8 i7300_edac: Clear the error bit after reading i7300_edac: Add error detection code for global errors ...
-rw-r--r--MAINTAINERS7
-rw-r--r--drivers/edac/Kconfig7
-rw-r--r--drivers/edac/Makefile1
-rw-r--r--drivers/edac/i7300_edac.c1247
-rw-r--r--include/linux/pci_ids.h19
5 files changed, 1273 insertions, 8 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0e265fcc103b..23a4ca9e27f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2212,6 +2212,13 @@ W: bluesmoke.sourceforge.net
2212S: Maintained 2212S: Maintained
2213F: drivers/edac/i5400_edac.c 2213F: drivers/edac/i5400_edac.c
2214 2214
2215EDAC-I7300
2216M: Mauro Carvalho Chehab <mchehab@redhat.com>
2217L: linux-edac@vger.kernel.org
2218W: bluesmoke.sourceforge.net
2219S: Maintained
2220F: drivers/edac/i7300_edac.c
2221
2215EDAC-I7CORE 2222EDAC-I7CORE
2216M: Mauro Carvalho Chehab <mchehab@redhat.com> 2223M: Mauro Carvalho Chehab <mchehab@redhat.com>
2217L: linux-edac@vger.kernel.org 2224L: linux-edac@vger.kernel.org
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 9dbb28b9559f..f436a2fa9f38 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -209,6 +209,13 @@ config EDAC_I5100
209 Support for error detection and correction the Intel 209 Support for error detection and correction the Intel
210 San Clemente MCH. 210 San Clemente MCH.
211 211
212config EDAC_I7300
213 tristate "Intel Clarksboro MCH"
214 depends on EDAC_MM_EDAC && X86 && PCI
215 help
216 Support for error detection and correction the Intel
217 Clarksboro MCH (Intel 7300 chipset).
218
212config EDAC_MPC85XX 219config EDAC_MPC85XX
213 tristate "Freescale MPC83xx / MPC85xx" 220 tristate "Freescale MPC83xx / MPC85xx"
214 depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx) 221 depends on EDAC_MM_EDAC && FSL_SOC && (PPC_83xx || PPC_85xx)
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 32c7bc93c525..b3781399b38a 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o
27obj-$(CONFIG_EDAC_I5000) += i5000_edac.o 27obj-$(CONFIG_EDAC_I5000) += i5000_edac.o
28obj-$(CONFIG_EDAC_I5100) += i5100_edac.o 28obj-$(CONFIG_EDAC_I5100) += i5100_edac.o
29obj-$(CONFIG_EDAC_I5400) += i5400_edac.o 29obj-$(CONFIG_EDAC_I5400) += i5400_edac.o
30obj-$(CONFIG_EDAC_I7300) += i7300_edac.o
30obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o 31obj-$(CONFIG_EDAC_I7CORE) += i7core_edac.o
31obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o 32obj-$(CONFIG_EDAC_E7XXX) += e7xxx_edac.o
32obj-$(CONFIG_EDAC_E752X) += e752x_edac.o 33obj-$(CONFIG_EDAC_E752X) += e752x_edac.o
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
new file mode 100644
index 000000000000..05523b504271
--- /dev/null
+++ b/drivers/edac/i7300_edac.c
@@ -0,0 +1,1247 @@
1/*
2 * Intel 7300 class Memory Controllers kernel module (Clarksboro)
3 *
4 * This file may be distributed under the terms of the
5 * GNU General Public License version 2 only.
6 *
7 * Copyright (c) 2010 by:
8 * Mauro Carvalho Chehab <mchehab@redhat.com>
9 *
10 * Red Hat Inc. http://www.redhat.com
11 *
12 * Intel 7300 Chipset Memory Controller Hub (MCH) - Datasheet
13 * http://www.intel.com/Assets/PDF/datasheet/318082.pdf
14 *
15 * TODO: The chipset allow checking for PCI Express errors also. Currently,
16 * the driver covers only memory error errors
17 *
18 * This driver uses "csrows" EDAC attribute to represent DIMM slot#
19 */
20
21#include <linux/module.h>
22#include <linux/init.h>
23#include <linux/pci.h>
24#include <linux/pci_ids.h>
25#include <linux/slab.h>
26#include <linux/edac.h>
27#include <linux/mmzone.h>
28
29#include "edac_core.h"
30
31/*
32 * Alter this version for the I7300 module when modifications are made
33 */
34#define I7300_REVISION " Ver: 1.0.0 " __DATE__
35
36#define EDAC_MOD_STR "i7300_edac"
37
38#define i7300_printk(level, fmt, arg...) \
39 edac_printk(level, "i7300", fmt, ##arg)
40
41#define i7300_mc_printk(mci, level, fmt, arg...) \
42 edac_mc_chipset_printk(mci, level, "i7300", fmt, ##arg)
43
44/***********************************************
45 * i7300 Limit constants Structs and static vars
46 ***********************************************/
47
48/*
49 * Memory topology is organized as:
50 * Branch 0 - 2 channels: channels 0 and 1 (FDB0 PCI dev 21.0)
51 * Branch 1 - 2 channels: channels 2 and 3 (FDB1 PCI dev 22.0)
52 * Each channel can have to 8 DIMM sets (called as SLOTS)
53 * Slots should generally be filled in pairs
54 * Except on Single Channel mode of operation
55 * just slot 0/channel0 filled on this mode
56 * On normal operation mode, the two channels on a branch should be
57 * filled together for the same SLOT#
58 * When in mirrored mode, Branch 1 replicate memory at Branch 0, so, the four
59 * channels on both branches should be filled
60 */
61
62/* Limits for i7300 */
63#define MAX_SLOTS 8
64#define MAX_BRANCHES 2
65#define MAX_CH_PER_BRANCH 2
66#define MAX_CHANNELS (MAX_CH_PER_BRANCH * MAX_BRANCHES)
67#define MAX_MIR 3
68
69#define to_channel(ch, branch) ((((branch)) << 1) | (ch))
70
71#define to_csrow(slot, ch, branch) \
72 (to_channel(ch, branch) | ((slot) << 2))
73
74/* Device name and register DID (Device ID) */
75struct i7300_dev_info {
76 const char *ctl_name; /* name for this device */
77 u16 fsb_mapping_errors; /* DID for the branchmap,control */
78};
79
80/* Table of devices attributes supported by this driver */
81static const struct i7300_dev_info i7300_devs[] = {
82 {
83 .ctl_name = "I7300",
84 .fsb_mapping_errors = PCI_DEVICE_ID_INTEL_I7300_MCH_ERR,
85 },
86};
87
88struct i7300_dimm_info {
89 int megabytes; /* size, 0 means not present */
90};
91
92/* driver private data structure */
93struct i7300_pvt {
94 struct pci_dev *pci_dev_16_0_fsb_ctlr; /* 16.0 */
95 struct pci_dev *pci_dev_16_1_fsb_addr_map; /* 16.1 */
96 struct pci_dev *pci_dev_16_2_fsb_err_regs; /* 16.2 */
97 struct pci_dev *pci_dev_2x_0_fbd_branch[MAX_BRANCHES]; /* 21.0 and 22.0 */
98
99 u16 tolm; /* top of low memory */
100 u64 ambase; /* AMB BAR */
101
102 u32 mc_settings; /* Report several settings */
103 u32 mc_settings_a;
104
105 u16 mir[MAX_MIR]; /* Memory Interleave Reg*/
106
107 u16 mtr[MAX_SLOTS][MAX_BRANCHES]; /* Memory Technlogy Reg */
108 u16 ambpresent[MAX_CHANNELS]; /* AMB present regs */
109
110 /* DIMM information matrix, allocating architecture maximums */
111 struct i7300_dimm_info dimm_info[MAX_SLOTS][MAX_CHANNELS];
112
113 /* Temporary buffer for use when preparing error messages */
114 char *tmp_prt_buffer;
115};
116
117/* FIXME: Why do we need to have this static? */
118static struct edac_pci_ctl_info *i7300_pci;
119
120/***************************************************
121 * i7300 Register definitions for memory enumeration
122 ***************************************************/
123
124/*
125 * Device 16,
126 * Function 0: System Address (not documented)
127 * Function 1: Memory Branch Map, Control, Errors Register
128 */
129
130 /* OFFSETS for Function 0 */
131#define AMBASE 0x48 /* AMB Mem Mapped Reg Region Base */
132#define MAXCH 0x56 /* Max Channel Number */
133#define MAXDIMMPERCH 0x57 /* Max DIMM PER Channel Number */
134
135 /* OFFSETS for Function 1 */
136#define MC_SETTINGS 0x40
137 #define IS_MIRRORED(mc) ((mc) & (1 << 16))
138 #define IS_ECC_ENABLED(mc) ((mc) & (1 << 5))
139 #define IS_RETRY_ENABLED(mc) ((mc) & (1 << 31))
140 #define IS_SCRBALGO_ENHANCED(mc) ((mc) & (1 << 8))
141
142#define MC_SETTINGS_A 0x58
143 #define IS_SINGLE_MODE(mca) ((mca) & (1 << 14))
144
145#define TOLM 0x6C
146
147#define MIR0 0x80
148#define MIR1 0x84
149#define MIR2 0x88
150
151/*
152 * Note: Other Intel EDAC drivers use AMBPRESENT to identify if the available
153 * memory. From datasheet item 7.3.1 (FB-DIMM technology & organization), it
154 * seems that we cannot use this information directly for the same usage.
155 * Each memory slot may have up to 2 AMB interfaces, one for income and another
156 * for outcome interface to the next slot.
157 * For now, the driver just stores the AMB present registers, but rely only at
158 * the MTR info to detect memory.
159 * Datasheet is also not clear about how to map each AMBPRESENT registers to
160 * one of the 4 available channels.
161 */
162#define AMBPRESENT_0 0x64
163#define AMBPRESENT_1 0x66
164
165const static u16 mtr_regs[MAX_SLOTS] = {
166 0x80, 0x84, 0x88, 0x8c,
167 0x82, 0x86, 0x8a, 0x8e
168};
169
170/*
171 * Defines to extract the vaious fields from the
172 * MTRx - Memory Technology Registers
173 */
174#define MTR_DIMMS_PRESENT(mtr) ((mtr) & (1 << 8))
175#define MTR_DIMMS_ETHROTTLE(mtr) ((mtr) & (1 << 7))
176#define MTR_DRAM_WIDTH(mtr) (((mtr) & (1 << 6)) ? 8 : 4)
177#define MTR_DRAM_BANKS(mtr) (((mtr) & (1 << 5)) ? 8 : 4)
178#define MTR_DIMM_RANKS(mtr) (((mtr) & (1 << 4)) ? 1 : 0)
179#define MTR_DIMM_ROWS(mtr) (((mtr) >> 2) & 0x3)
180#define MTR_DRAM_BANKS_ADDR_BITS 2
181#define MTR_DIMM_ROWS_ADDR_BITS(mtr) (MTR_DIMM_ROWS(mtr) + 13)
182#define MTR_DIMM_COLS(mtr) ((mtr) & 0x3)
183#define MTR_DIMM_COLS_ADDR_BITS(mtr) (MTR_DIMM_COLS(mtr) + 10)
184
185#ifdef CONFIG_EDAC_DEBUG
186/* MTR NUMROW */
187static const char *numrow_toString[] = {
188 "8,192 - 13 rows",
189 "16,384 - 14 rows",
190 "32,768 - 15 rows",
191 "65,536 - 16 rows"
192};
193
194/* MTR NUMCOL */
195static const char *numcol_toString[] = {
196 "1,024 - 10 columns",
197 "2,048 - 11 columns",
198 "4,096 - 12 columns",
199 "reserved"
200};
201#endif
202
203/************************************************
204 * i7300 Register definitions for error detection
205 ************************************************/
206
207/*
208 * Device 16.1: FBD Error Registers
209 */
210#define FERR_FAT_FBD 0x98
211static const char *ferr_fat_fbd_name[] = {
212 [22] = "Non-Redundant Fast Reset Timeout",
213 [2] = ">Tmid Thermal event with intelligent throttling disabled",
214 [1] = "Memory or FBD configuration CRC read error",
215 [0] = "Memory Write error on non-redundant retry or "
216 "FBD configuration Write error on retry",
217};
218#define GET_FBD_FAT_IDX(fbderr) (fbderr & (3 << 28))
219#define FERR_FAT_FBD_ERR_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3))
220
221#define FERR_NF_FBD 0xa0
222static const char *ferr_nf_fbd_name[] = {
223 [24] = "DIMM-Spare Copy Completed",
224 [23] = "DIMM-Spare Copy Initiated",
225 [22] = "Redundant Fast Reset Timeout",
226 [21] = "Memory Write error on redundant retry",
227 [18] = "SPD protocol Error",
228 [17] = "FBD Northbound parity error on FBD Sync Status",
229 [16] = "Correctable Patrol Data ECC",
230 [15] = "Correctable Resilver- or Spare-Copy Data ECC",
231 [14] = "Correctable Mirrored Demand Data ECC",
232 [13] = "Correctable Non-Mirrored Demand Data ECC",
233 [11] = "Memory or FBD configuration CRC read error",
234 [10] = "FBD Configuration Write error on first attempt",
235 [9] = "Memory Write error on first attempt",
236 [8] = "Non-Aliased Uncorrectable Patrol Data ECC",
237 [7] = "Non-Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
238 [6] = "Non-Aliased Uncorrectable Mirrored Demand Data ECC",
239 [5] = "Non-Aliased Uncorrectable Non-Mirrored Demand Data ECC",
240 [4] = "Aliased Uncorrectable Patrol Data ECC",
241 [3] = "Aliased Uncorrectable Resilver- or Spare-Copy Data ECC",
242 [2] = "Aliased Uncorrectable Mirrored Demand Data ECC",
243 [1] = "Aliased Uncorrectable Non-Mirrored Demand Data ECC",
244 [0] = "Uncorrectable Data ECC on Replay",
245};
246#define GET_FBD_NF_IDX(fbderr) (fbderr & (3 << 28))
247#define FERR_NF_FBD_ERR_MASK ((1 << 24) | (1 << 23) | (1 << 22) | (1 << 21) |\
248 (1 << 18) | (1 << 17) | (1 << 16) | (1 << 15) |\
249 (1 << 14) | (1 << 13) | (1 << 11) | (1 << 10) |\
250 (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) |\
251 (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) |\
252 (1 << 1) | (1 << 0))
253
254#define EMASK_FBD 0xa8
255#define EMASK_FBD_ERR_MASK ((1 << 27) | (1 << 26) | (1 << 25) | (1 << 24) |\
256 (1 << 22) | (1 << 21) | (1 << 20) | (1 << 19) |\
257 (1 << 18) | (1 << 17) | (1 << 16) | (1 << 14) |\
258 (1 << 13) | (1 << 12) | (1 << 11) | (1 << 10) |\
259 (1 << 9) | (1 << 8) | (1 << 7) | (1 << 6) |\
260 (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) |\
261 (1 << 1) | (1 << 0))
262
263/*
264 * Device 16.2: Global Error Registers
265 */
266
267#define FERR_GLOBAL_HI 0x48
268static const char *ferr_global_hi_name[] = {
269 [3] = "FSB 3 Fatal Error",
270 [2] = "FSB 2 Fatal Error",
271 [1] = "FSB 1 Fatal Error",
272 [0] = "FSB 0 Fatal Error",
273};
274#define ferr_global_hi_is_fatal(errno) 1
275
276#define FERR_GLOBAL_LO 0x40
277static const char *ferr_global_lo_name[] = {
278 [31] = "Internal MCH Fatal Error",
279 [30] = "Intel QuickData Technology Device Fatal Error",
280 [29] = "FSB1 Fatal Error",
281 [28] = "FSB0 Fatal Error",
282 [27] = "FBD Channel 3 Fatal Error",
283 [26] = "FBD Channel 2 Fatal Error",
284 [25] = "FBD Channel 1 Fatal Error",
285 [24] = "FBD Channel 0 Fatal Error",
286 [23] = "PCI Express Device 7Fatal Error",
287 [22] = "PCI Express Device 6 Fatal Error",
288 [21] = "PCI Express Device 5 Fatal Error",
289 [20] = "PCI Express Device 4 Fatal Error",
290 [19] = "PCI Express Device 3 Fatal Error",
291 [18] = "PCI Express Device 2 Fatal Error",
292 [17] = "PCI Express Device 1 Fatal Error",
293 [16] = "ESI Fatal Error",
294 [15] = "Internal MCH Non-Fatal Error",
295 [14] = "Intel QuickData Technology Device Non Fatal Error",
296 [13] = "FSB1 Non-Fatal Error",
297 [12] = "FSB 0 Non-Fatal Error",
298 [11] = "FBD Channel 3 Non-Fatal Error",
299 [10] = "FBD Channel 2 Non-Fatal Error",
300 [9] = "FBD Channel 1 Non-Fatal Error",
301 [8] = "FBD Channel 0 Non-Fatal Error",
302 [7] = "PCI Express Device 7 Non-Fatal Error",
303 [6] = "PCI Express Device 6 Non-Fatal Error",
304 [5] = "PCI Express Device 5 Non-Fatal Error",
305 [4] = "PCI Express Device 4 Non-Fatal Error",
306 [3] = "PCI Express Device 3 Non-Fatal Error",
307 [2] = "PCI Express Device 2 Non-Fatal Error",
308 [1] = "PCI Express Device 1 Non-Fatal Error",
309 [0] = "ESI Non-Fatal Error",
310};
311#define ferr_global_lo_is_fatal(errno) ((errno < 16) ? 0 : 1)
312
313#define NRECMEMA 0xbe
314 #define NRECMEMA_BANK(v) (((v) >> 12) & 7)
315 #define NRECMEMA_RANK(v) (((v) >> 8) & 15)
316
317#define NRECMEMB 0xc0
318 #define NRECMEMB_IS_WR(v) ((v) & (1 << 31))
319 #define NRECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
320 #define NRECMEMB_RAS(v) ((v) & 0xffff)
321
322#define REDMEMA 0xdc
323
324#define REDMEMB 0x7c
325 #define IS_SECOND_CH(v) ((v) * (1 << 17))
326
327#define RECMEMA 0xe0
328 #define RECMEMA_BANK(v) (((v) >> 12) & 7)
329 #define RECMEMA_RANK(v) (((v) >> 8) & 15)
330
331#define RECMEMB 0xe4
332 #define RECMEMB_IS_WR(v) ((v) & (1 << 31))
333 #define RECMEMB_CAS(v) (((v) >> 16) & 0x1fff)
334 #define RECMEMB_RAS(v) ((v) & 0xffff)
335
336/********************************************
337 * i7300 Functions related to error detection
338 ********************************************/
339
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)
353{
354 if (unlikely(pos >= size))
355 return "Reserved";
356
357 if (unlikely(!table[pos]))
358 return "Reserved";
359
360 return table[pos];
361}
362
363#define GET_ERR_FROM_TABLE(table, pos) \
364 get_err_from_table(table, ARRAY_SIZE(table), pos)
365
366/**
367 * i7300_process_error_global() - Retrieve the hardware error information from
368 * the hardware global error registers and
369 * sends it to dmesg
370 * @mci: struct mem_ctl_info pointer
371 */
372static void i7300_process_error_global(struct mem_ctl_info *mci)
373{
374 struct i7300_pvt *pvt;
375 u32 errnum, value;
376 unsigned long errors;
377 const char *specific;
378 bool is_fatal;
379
380 pvt = mci->pvt_info;
381
382 /* read in the 1st FATAL error register */
383 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
384 FERR_GLOBAL_HI, &value);
385 if (unlikely(value)) {
386 errors = value;
387 errnum = find_first_bit(&errors,
388 ARRAY_SIZE(ferr_global_hi_name));
389 specific = GET_ERR_FROM_TABLE(ferr_global_hi_name, errnum);
390 is_fatal = ferr_global_hi_is_fatal(errnum);
391
392 /* Clear the error bit */
393 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
394 FERR_GLOBAL_HI, value);
395
396 goto error_global;
397 }
398
399 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
400 FERR_GLOBAL_LO, &value);
401 if (unlikely(value)) {
402 errors = value;
403 errnum = find_first_bit(&errors,
404 ARRAY_SIZE(ferr_global_lo_name));
405 specific = GET_ERR_FROM_TABLE(ferr_global_lo_name, errnum);
406 is_fatal = ferr_global_lo_is_fatal(errnum);
407
408 /* Clear the error bit */
409 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
410 FERR_GLOBAL_LO, value);
411
412 goto error_global;
413 }
414 return;
415
416error_global:
417 i7300_mc_printk(mci, KERN_EMERG, "%s misc error: %s\n",
418 is_fatal ? "Fatal" : "NOT fatal", specific);
419}
420
421/**
422 * i7300_process_fbd_error() - Retrieve the hardware error information from
423 * the FBD error registers and sends it via
424 * EDAC error API calls
425 * @mci: struct mem_ctl_info pointer
426 */
427static void i7300_process_fbd_error(struct mem_ctl_info *mci)
428{
429 struct i7300_pvt *pvt;
430 u32 errnum, value;
431 u16 val16;
432 unsigned branch, channel, bank, rank, cas, ras;
433 u32 syndrome;
434
435 unsigned long errors;
436 const char *specific;
437 bool is_wr;
438
439 pvt = mci->pvt_info;
440
441 /* read in the 1st FATAL error register */
442 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
443 FERR_FAT_FBD, &value);
444 if (unlikely(value & FERR_FAT_FBD_ERR_MASK)) {
445 errors = value & FERR_FAT_FBD_ERR_MASK ;
446 errnum = find_first_bit(&errors,
447 ARRAY_SIZE(ferr_fat_fbd_name));
448 specific = GET_ERR_FROM_TABLE(ferr_fat_fbd_name, errnum);
449
450 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
451 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
452 NRECMEMA, &val16);
453 bank = NRECMEMA_BANK(val16);
454 rank = NRECMEMA_RANK(val16);
455
456 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
457 NRECMEMB, &value);
458
459 is_wr = NRECMEMB_IS_WR(value);
460 cas = NRECMEMB_CAS(value);
461 ras = NRECMEMB_RAS(value);
462
463 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
464 "FATAL (Branch=%d DRAM-Bank=%d %s "
465 "RAS=%d CAS=%d Err=0x%lx (%s))",
466 branch, bank,
467 is_wr ? "RDWR" : "RD",
468 ras, cas,
469 errors, specific);
470
471 /* Call the helper to output message */
472 edac_mc_handle_fbd_ue(mci, rank, branch << 1,
473 (branch << 1) + 1,
474 pvt->tmp_prt_buffer);
475 }
476
477 /* read in the 1st NON-FATAL error register */
478 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
479 FERR_NF_FBD, &value);
480 if (unlikely(value & FERR_NF_FBD_ERR_MASK)) {
481 errors = value & FERR_NF_FBD_ERR_MASK;
482 errnum = find_first_bit(&errors,
483 ARRAY_SIZE(ferr_nf_fbd_name));
484 specific = GET_ERR_FROM_TABLE(ferr_nf_fbd_name, errnum);
485
486 /* Clear the error bit */
487 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
488 FERR_GLOBAL_LO, value);
489
490 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
491 REDMEMA, &syndrome);
492
493 branch = (GET_FBD_FAT_IDX(value) == 2) ? 1 : 0;
494 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map,
495 RECMEMA, &val16);
496 bank = RECMEMA_BANK(val16);
497 rank = RECMEMA_RANK(val16);
498
499 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
500 RECMEMB, &value);
501
502 is_wr = RECMEMB_IS_WR(value);
503 cas = RECMEMB_CAS(value);
504 ras = RECMEMB_RAS(value);
505
506 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
507 REDMEMB, &value);
508
509 channel = (branch << 1);
510 if (IS_SECOND_CH(value))
511 channel++;
512
513 /* Form out message */
514 snprintf(pvt->tmp_prt_buffer, PAGE_SIZE,
515 "Corrected error (Branch=%d, Channel %d), "
516 " DRAM-Bank=%d %s "
517 "RAS=%d CAS=%d, CE Err=0x%lx, Syndrome=0x%08x(%s))",
518 branch, channel,
519 bank,
520 is_wr ? "RDWR" : "RD",
521 ras, cas,
522 errors, syndrome, specific);
523
524 /*
525 * Call the helper to output message
526 * NOTE: Errors are reported per-branch, and not per-channel
527 * Currently, we don't know how to identify the right
528 * channel.
529 */
530 edac_mc_handle_fbd_ce(mci, rank, channel,
531 pvt->tmp_prt_buffer);
532 }
533 return;
534}
535
536/**
537 * i7300_check_error() - Calls the error checking subroutines
538 * @mci: struct mem_ctl_info pointer
539 */
540static void i7300_check_error(struct mem_ctl_info *mci)
541{
542 i7300_process_error_global(mci);
543 i7300_process_fbd_error(mci);
544};
545
546/**
547 * i7300_clear_error() - Clears the error registers
548 * @mci: struct mem_ctl_info pointer
549 */
550static void i7300_clear_error(struct mem_ctl_info *mci)
551{
552 struct i7300_pvt *pvt = mci->pvt_info;
553 u32 value;
554 /*
555 * All error values are RWC - we need to read and write 1 to the
556 * bit that we want to cleanup
557 */
558
559 /* Clear global error registers */
560 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
561 FERR_GLOBAL_HI, &value);
562 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
563 FERR_GLOBAL_HI, value);
564
565 pci_read_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
566 FERR_GLOBAL_LO, &value);
567 pci_write_config_dword(pvt->pci_dev_16_2_fsb_err_regs,
568 FERR_GLOBAL_LO, value);
569
570 /* Clear FBD error registers */
571 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
572 FERR_FAT_FBD, &value);
573 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
574 FERR_FAT_FBD, value);
575
576 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
577 FERR_NF_FBD, &value);
578 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
579 FERR_NF_FBD, value);
580}
581
582/**
583 * i7300_enable_error_reporting() - Enable the memory reporting logic at the
584 * hardware
585 * @mci: struct mem_ctl_info pointer
586 */
587static void i7300_enable_error_reporting(struct mem_ctl_info *mci)
588{
589 struct i7300_pvt *pvt = mci->pvt_info;
590 u32 fbd_error_mask;
591
592 /* Read the FBD Error Mask Register */
593 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
594 EMASK_FBD, &fbd_error_mask);
595
596 /* Enable with a '0' */
597 fbd_error_mask &= ~(EMASK_FBD_ERR_MASK);
598
599 pci_write_config_dword(pvt->pci_dev_16_1_fsb_addr_map,
600 EMASK_FBD, fbd_error_mask);
601}
602
603/************************************************
604 * i7300 Functions related to memory enumberation
605 ************************************************/
606
607/**
608 * decode_mtr() - Decodes the MTR descriptor, filling the edac structs
609 * @pvt: pointer to the private data struct used by i7300 driver
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
615 */
616static int decode_mtr(struct i7300_pvt *pvt,
617 int slot, int ch, int branch,
618 struct i7300_dimm_info *dinfo,
619 struct csrow_info *p_csrow,
620 u32 *nr_pages)
621{
622 int mtr, ans, addrBits, channel;
623
624 channel = to_channel(ch, branch);
625
626 mtr = pvt->mtr[slot][branch];
627 ans = MTR_DIMMS_PRESENT(mtr) ? 1 : 0;
628
629 debugf2("\tMTR%d CH%d: DIMMs are %s (mtr)\n",
630 slot, channel,
631 ans ? "Present" : "NOT Present");
632
633 /* Determine if there is a DIMM present in this DIMM slot */
634 if (!ans)
635 return 0;
636
637 /* Start with the number of bits for a Bank
638 * on the DRAM */
639 addrBits = MTR_DRAM_BANKS_ADDR_BITS;
640 /* Add thenumber of ROW bits */
641 addrBits += MTR_DIMM_ROWS_ADDR_BITS(mtr);
642 /* add the number of COLUMN bits */
643 addrBits += MTR_DIMM_COLS_ADDR_BITS(mtr);
644 /* add the number of RANK bits */
645 addrBits += MTR_DIMM_RANKS(mtr);
646
647 addrBits += 6; /* add 64 bits per DIMM */
648 addrBits -= 20; /* divide by 2^^20 */
649 addrBits -= 3; /* 8 bits per bytes */
650
651 dinfo->megabytes = 1 << addrBits;
652 *nr_pages = dinfo->megabytes << 8;
653
654 debugf2("\t\tWIDTH: x%d\n", MTR_DRAM_WIDTH(mtr));
655
656 debugf2("\t\tELECTRICAL THROTTLING is %s\n",
657 MTR_DIMMS_ETHROTTLE(mtr) ? "enabled" : "disabled");
658
659 debugf2("\t\tNUMBANK: %d bank(s)\n", MTR_DRAM_BANKS(mtr));
660 debugf2("\t\tNUMRANK: %s\n", MTR_DIMM_RANKS(mtr) ? "double" : "single");
661 debugf2("\t\tNUMROW: %s\n", numrow_toString[MTR_DIMM_ROWS(mtr)]);
662 debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]);
663 debugf2("\t\tSIZE: %d MB\n", dinfo->megabytes);
664
665 p_csrow->grain = 8;
666 p_csrow->mtype = MEM_FB_DDR2;
667 p_csrow->csrow_idx = slot;
668 p_csrow->page_mask = 0;
669
670 /*
671 * The type of error detection actually depends of the
672 * mode of operation. When it is just one single memory chip, at
673 * socket 0, channel 0, it uses 8-byte-over-32-byte SECDED+ code.
674 * In normal or mirrored mode, it uses Lockstep mode,
675 * with the possibility of using an extended algorithm for x8 memories
676 * See datasheet Sections 7.3.6 to 7.3.8
677 */
678
679 if (IS_SINGLE_MODE(pvt->mc_settings_a)) {
680 p_csrow->edac_mode = EDAC_SECDED;
681 debugf2("\t\tECC code is 8-byte-over-32-byte SECDED+ code\n");
682 } else {
683 debugf2("\t\tECC code is on Lockstep mode\n");
684 if (MTR_DRAM_WIDTH(mtr) == 8)
685 p_csrow->edac_mode = EDAC_S8ECD8ED;
686 else
687 p_csrow->edac_mode = EDAC_S4ECD4ED;
688 }
689
690 /* ask what device type on this row */
691 if (MTR_DRAM_WIDTH(mtr) == 8) {
692 debugf2("\t\tScrub algorithm for x8 is on %s mode\n",
693 IS_SCRBALGO_ENHANCED(pvt->mc_settings) ?
694 "enhanced" : "normal");
695
696 p_csrow->dtype = DEV_X8;
697 } else
698 p_csrow->dtype = DEV_X4;
699
700 return mtr;
701}
702
703/**
704 * print_dimm_size() - Prints dump of the memory organization
705 * @pvt: pointer to the private data struct used by i7300 driver
706 *
707 * Useful for debug. If debug is disabled, this routine do nothing
708 */
709static void print_dimm_size(struct i7300_pvt *pvt)
710{
711#ifdef CONFIG_EDAC_DEBUG
712 struct i7300_dimm_info *dinfo;
713 char *p;
714 int space, n;
715 int channel, slot;
716
717 space = PAGE_SIZE;
718 p = pvt->tmp_prt_buffer;
719
720 n = snprintf(p, space, " ");
721 p += n;
722 space -= n;
723 for (channel = 0; channel < MAX_CHANNELS; channel++) {
724 n = snprintf(p, space, "channel %d | ", channel);
725 p += n;
726 space -= n;
727 }
728 debugf2("%s\n", pvt->tmp_prt_buffer);
729 p = pvt->tmp_prt_buffer;
730 space = PAGE_SIZE;
731 n = snprintf(p, space, "-------------------------------"
732 "------------------------------");
733 p += n;
734 space -= n;
735 debugf2("%s\n", pvt->tmp_prt_buffer);
736 p = pvt->tmp_prt_buffer;
737 space = PAGE_SIZE;
738
739 for (slot = 0; slot < MAX_SLOTS; slot++) {
740 n = snprintf(p, space, "csrow/SLOT %d ", slot);
741 p += n;
742 space -= n;
743
744 for (channel = 0; channel < MAX_CHANNELS; channel++) {
745 dinfo = &pvt->dimm_info[slot][channel];
746 n = snprintf(p, space, "%4d MB | ", dinfo->megabytes);
747 p += n;
748 space -= n;
749 }
750
751 debugf2("%s\n", pvt->tmp_prt_buffer);
752 p = pvt->tmp_prt_buffer;
753 space = PAGE_SIZE;
754 }
755
756 n = snprintf(p, space, "-------------------------------"
757 "------------------------------");
758 p += n;
759 space -= n;
760 debugf2("%s\n", pvt->tmp_prt_buffer);
761 p = pvt->tmp_prt_buffer;
762 space = PAGE_SIZE;
763#endif
764}
765
766/**
767 * i7300_init_csrows() - Initialize the 'csrows' table within
768 * the mci control structure with the
769 * addressing of memory.
770 * @mci: struct mem_ctl_info pointer
771 */
772static int i7300_init_csrows(struct mem_ctl_info *mci)
773{
774 struct i7300_pvt *pvt;
775 struct i7300_dimm_info *dinfo;
776 struct csrow_info *p_csrow;
777 int rc = -ENODEV;
778 int mtr;
779 int ch, branch, slot, channel;
780 u32 last_page = 0, nr_pages;
781
782 pvt = mci->pvt_info;
783
784 debugf2("Memory Technology Registers:\n");
785
786 /* Get the AMB present registers for the four channels */
787 for (branch = 0; branch < MAX_BRANCHES; branch++) {
788 /* Read and dump branch 0's MTRs */
789 channel = to_channel(0, branch);
790 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch],
791 AMBPRESENT_0,
792 &pvt->ambpresent[channel]);
793 debugf2("\t\tAMB-present CH%d = 0x%x:\n",
794 channel, pvt->ambpresent[channel]);
795
796 channel = to_channel(1, branch);
797 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch],
798 AMBPRESENT_1,
799 &pvt->ambpresent[channel]);
800 debugf2("\t\tAMB-present CH%d = 0x%x:\n",
801 channel, pvt->ambpresent[channel]);
802 }
803
804 /* Get the set of MTR[0-7] regs by each branch */
805 for (slot = 0; slot < MAX_SLOTS; slot++) {
806 int where = mtr_regs[slot];
807 for (branch = 0; branch < MAX_BRANCHES; branch++) {
808 pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch],
809 where,
810 &pvt->mtr[slot][branch]);
811 for (ch = 0; ch < MAX_BRANCHES; ch++) {
812 int channel = to_channel(ch, branch);
813
814 dinfo = &pvt->dimm_info[slot][channel];
815 p_csrow = &mci->csrows[slot];
816
817 mtr = decode_mtr(pvt, slot, ch, branch,
818 dinfo, p_csrow, &nr_pages);
819 /* if no DIMMS on this row, continue */
820 if (!MTR_DIMMS_PRESENT(mtr))
821 continue;
822
823 /* Update per_csrow memory count */
824 p_csrow->nr_pages += nr_pages;
825 p_csrow->first_page = last_page;
826 last_page += nr_pages;
827 p_csrow->last_page = last_page;
828
829 rc = 0;
830 }
831 }
832 }
833
834 return rc;
835}
836
837/**
838 * decode_mir() - Decodes Memory Interleave Register (MIR) info
839 * @int mir_no: number of the MIR register to decode
840 * @mir: array with the MIR data cached on the driver
841 */
842static void decode_mir(int mir_no, u16 mir[MAX_MIR])
843{
844 if (mir[mir_no] & 3)
845 debugf2("MIR%d: limit= 0x%x Branch(es) that participate:"
846 " %s %s\n",
847 mir_no,
848 (mir[mir_no] >> 4) & 0xfff,
849 (mir[mir_no] & 1) ? "B0" : "",
850 (mir[mir_no] & 2) ? "B1" : "");
851}
852
853/**
854 * i7300_get_mc_regs() - Get the contents of the MC enumeration registers
855 * @mci: struct mem_ctl_info pointer
856 *
857 * Data read is cached internally for its usage when needed
858 */
859static int i7300_get_mc_regs(struct mem_ctl_info *mci)
860{
861 struct i7300_pvt *pvt;
862 u32 actual_tolm;
863 int i, rc;
864
865 pvt = mci->pvt_info;
866
867 pci_read_config_dword(pvt->pci_dev_16_0_fsb_ctlr, AMBASE,
868 (u32 *) &pvt->ambase);
869
870 debugf2("AMBASE= 0x%lx\n", (long unsigned int)pvt->ambase);
871
872 /* Get the Branch Map regs */
873 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, TOLM, &pvt->tolm);
874 pvt->tolm >>= 12;
875 debugf2("TOLM (number of 256M regions) =%u (0x%x)\n", pvt->tolm,
876 pvt->tolm);
877
878 actual_tolm = (u32) ((1000l * pvt->tolm) >> (30 - 28));
879 debugf2("Actual TOLM byte addr=%u.%03u GB (0x%x)\n",
880 actual_tolm/1000, actual_tolm % 1000, pvt->tolm << 28);
881
882 /* Get memory controller settings */
883 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS,
884 &pvt->mc_settings);
885 pci_read_config_dword(pvt->pci_dev_16_1_fsb_addr_map, MC_SETTINGS_A,
886 &pvt->mc_settings_a);
887
888 if (IS_SINGLE_MODE(pvt->mc_settings_a))
889 debugf0("Memory controller operating on single mode\n");
890 else
891 debugf0("Memory controller operating on %s mode\n",
892 IS_MIRRORED(pvt->mc_settings) ? "mirrored" : "non-mirrored");
893
894 debugf0("Error detection is %s\n",
895 IS_ECC_ENABLED(pvt->mc_settings) ? "enabled" : "disabled");
896 debugf0("Retry is %s\n",
897 IS_RETRY_ENABLED(pvt->mc_settings) ? "enabled" : "disabled");
898
899 /* Get Memory Interleave Range registers */
900 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR0,
901 &pvt->mir[0]);
902 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR1,
903 &pvt->mir[1]);
904 pci_read_config_word(pvt->pci_dev_16_1_fsb_addr_map, MIR2,
905 &pvt->mir[2]);
906
907 /* Decode the MIR regs */
908 for (i = 0; i < MAX_MIR; i++)
909 decode_mir(i, pvt->mir);
910
911 rc = i7300_init_csrows(mci);
912 if (rc < 0)
913 return rc;
914
915 /* Go and determine the size of each DIMM and place in an
916 * orderly matrix */
917 print_dimm_size(pvt);
918
919 return 0;
920}
921
922/*************************************************
923 * i7300 Functions related to device probe/release
924 *************************************************/
925
926/**
927 * i7300_put_devices() - Release the PCI devices
928 * @mci: struct mem_ctl_info pointer
929 */
930static void i7300_put_devices(struct mem_ctl_info *mci)
931{
932 struct i7300_pvt *pvt;
933 int branch;
934
935 pvt = mci->pvt_info;
936
937 /* Decrement usage count for devices */
938 for (branch = 0; branch < MAX_CH_PER_BRANCH; branch++)
939 pci_dev_put(pvt->pci_dev_2x_0_fbd_branch[branch]);
940 pci_dev_put(pvt->pci_dev_16_2_fsb_err_regs);
941 pci_dev_put(pvt->pci_dev_16_1_fsb_addr_map);
942}
943
944/**
945 * i7300_get_devices() - Find and perform 'get' operation on the MCH's
946 * device/functions we want to reference for this driver
947 * @mci: struct mem_ctl_info pointer
948 *
949 * Access and prepare the several devices for usage:
950 * I7300 devices used by this driver:
951 * Device 16, functions 0,1 and 2: PCI_DEVICE_ID_INTEL_I7300_MCH_ERR
952 * Device 21 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB0
953 * Device 22 function 0: PCI_DEVICE_ID_INTEL_I7300_MCH_FB1
954 */
955static int __devinit i7300_get_devices(struct mem_ctl_info *mci)
956{
957 struct i7300_pvt *pvt;
958 struct pci_dev *pdev;
959
960 pvt = mci->pvt_info;
961
962 /* Attempt to 'get' the MCH register we want */
963 pdev = NULL;
964 while (!pvt->pci_dev_16_1_fsb_addr_map ||
965 !pvt->pci_dev_16_2_fsb_err_regs) {
966 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
967 PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev);
968 if (!pdev) {
969 /* End of list, leave */
970 i7300_printk(KERN_ERR,
971 "'system address,Process Bus' "
972 "device not found:"
973 "vendor 0x%x device 0x%x ERR funcs "
974 "(broken BIOS?)\n",
975 PCI_VENDOR_ID_INTEL,
976 PCI_DEVICE_ID_INTEL_I7300_MCH_ERR);
977 goto error;
978 }
979
980 /* Store device 16 funcs 1 and 2 */
981 switch (PCI_FUNC(pdev->devfn)) {
982 case 1:
983 pvt->pci_dev_16_1_fsb_addr_map = pdev;
984 break;
985 case 2:
986 pvt->pci_dev_16_2_fsb_err_regs = pdev;
987 break;
988 }
989 }
990
991 debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n",
992 pci_name(pvt->pci_dev_16_0_fsb_ctlr),
993 pvt->pci_dev_16_0_fsb_ctlr->vendor,
994 pvt->pci_dev_16_0_fsb_ctlr->device);
995 debugf1("Branchmap, control and errors - PCI Bus ID: %s %x:%x\n",
996 pci_name(pvt->pci_dev_16_1_fsb_addr_map),
997 pvt->pci_dev_16_1_fsb_addr_map->vendor,
998 pvt->pci_dev_16_1_fsb_addr_map->device);
999 debugf1("FSB Error Regs - PCI Bus ID: %s %x:%x\n",
1000 pci_name(pvt->pci_dev_16_2_fsb_err_regs),
1001 pvt->pci_dev_16_2_fsb_err_regs->vendor,
1002 pvt->pci_dev_16_2_fsb_err_regs->device);
1003
1004 pvt->pci_dev_2x_0_fbd_branch[0] = pci_get_device(PCI_VENDOR_ID_INTEL,
1005 PCI_DEVICE_ID_INTEL_I7300_MCH_FB0,
1006 NULL);
1007 if (!pvt->pci_dev_2x_0_fbd_branch[0]) {
1008 i7300_printk(KERN_ERR,
1009 "MC: 'BRANCH 0' device not found:"
1010 "vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n",
1011 PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_FB0);
1012 goto error;
1013 }
1014
1015 pvt->pci_dev_2x_0_fbd_branch[1] = pci_get_device(PCI_VENDOR_ID_INTEL,
1016 PCI_DEVICE_ID_INTEL_I7300_MCH_FB1,
1017 NULL);
1018 if (!pvt->pci_dev_2x_0_fbd_branch[1]) {
1019 i7300_printk(KERN_ERR,
1020 "MC: 'BRANCH 1' device not found:"
1021 "vendor 0x%x device 0x%x Func 0 "
1022 "(broken BIOS?)\n",
1023 PCI_VENDOR_ID_INTEL,
1024 PCI_DEVICE_ID_INTEL_I7300_MCH_FB1);
1025 goto error;
1026 }
1027
1028 return 0;
1029
1030error:
1031 i7300_put_devices(mci);
1032 return -ENODEV;
1033}
1034
1035/**
1036 * i7300_init_one() - Probe for one instance of the device
1037 * @pdev: struct pci_dev pointer
1038 * @id: struct pci_device_id pointer - currently unused
1039 */
1040static int __devinit i7300_init_one(struct pci_dev *pdev,
1041 const struct pci_device_id *id)
1042{
1043 struct mem_ctl_info *mci;
1044 struct i7300_pvt *pvt;
1045 int num_channels;
1046 int num_dimms_per_channel;
1047 int num_csrows;
1048 int rc;
1049
1050 /* wake up device */
1051 rc = pci_enable_device(pdev);
1052 if (rc == -EIO)
1053 return rc;
1054
1055 debugf0("MC: " __FILE__ ": %s(), pdev bus %u dev=0x%x fn=0x%x\n",
1056 __func__,
1057 pdev->bus->number,
1058 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
1059
1060 /* We only are looking for func 0 of the set */
1061 if (PCI_FUNC(pdev->devfn) != 0)
1062 return -ENODEV;
1063
1064 /* As we don't have a motherboard identification routine to determine
1065 * actual number of slots/dimms per channel, we thus utilize the
1066 * resource as specified by the chipset. Thus, we might have
1067 * have more DIMMs per channel than actually on the mobo, but this
1068 * allows the driver to support upto the chipset max, without
1069 * some fancy mobo determination.
1070 */
1071 num_dimms_per_channel = MAX_SLOTS;
1072 num_channels = MAX_CHANNELS;
1073 num_csrows = MAX_SLOTS * MAX_CHANNELS;
1074
1075 debugf0("MC: %s(): Number of - Channels= %d DIMMS= %d CSROWS= %d\n",
1076 __func__, num_channels, num_dimms_per_channel, num_csrows);
1077
1078 /* allocate a new MC control structure */
1079 mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0);
1080
1081 if (mci == NULL)
1082 return -ENOMEM;
1083
1084 debugf0("MC: " __FILE__ ": %s(): mci = %p\n", __func__, mci);
1085
1086 mci->dev = &pdev->dev; /* record ptr to the generic device */
1087
1088 pvt = mci->pvt_info;
1089 pvt->pci_dev_16_0_fsb_ctlr = pdev; /* Record this device in our private */
1090
1091 pvt->tmp_prt_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
1092 if (!pvt->tmp_prt_buffer) {
1093 edac_mc_free(mci);
1094 return -ENOMEM;
1095 }
1096
1097 /* 'get' the pci devices we want to reserve for our use */
1098 if (i7300_get_devices(mci))
1099 goto fail0;
1100
1101 mci->mc_idx = 0;
1102 mci->mtype_cap = MEM_FLAG_FB_DDR2;
1103 mci->edac_ctl_cap = EDAC_FLAG_NONE;
1104 mci->edac_cap = EDAC_FLAG_NONE;
1105 mci->mod_name = "i7300_edac.c";
1106 mci->mod_ver = I7300_REVISION;
1107 mci->ctl_name = i7300_devs[0].ctl_name;
1108 mci->dev_name = pci_name(pdev);
1109 mci->ctl_page_to_phys = NULL;
1110
1111 /* Set the function pointer to an actual operation function */
1112 mci->edac_check = i7300_check_error;
1113
1114 /* initialize the MC control structure 'csrows' table
1115 * with the mapping and control information */
1116 if (i7300_get_mc_regs(mci)) {
1117 debugf0("MC: Setting mci->edac_cap to EDAC_FLAG_NONE\n"
1118 " because i7300_init_csrows() returned nonzero "
1119 "value\n");
1120 mci->edac_cap = EDAC_FLAG_NONE; /* no csrows found */
1121 } else {
1122 debugf1("MC: Enable error reporting now\n");
1123 i7300_enable_error_reporting(mci);
1124 }
1125
1126 /* add this new MC control structure to EDAC's list of MCs */
1127 if (edac_mc_add_mc(mci)) {
1128 debugf0("MC: " __FILE__
1129 ": %s(): failed edac_mc_add_mc()\n", __func__);
1130 /* FIXME: perhaps some code should go here that disables error
1131 * reporting if we just enabled it
1132 */
1133 goto fail1;
1134 }
1135
1136 i7300_clear_error(mci);
1137
1138 /* allocating generic PCI control info */
1139 i7300_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR);
1140 if (!i7300_pci) {
1141 printk(KERN_WARNING
1142 "%s(): Unable to create PCI control\n",
1143 __func__);
1144 printk(KERN_WARNING
1145 "%s(): PCI error report via EDAC not setup\n",
1146 __func__);
1147 }
1148
1149 return 0;
1150
1151 /* Error exit unwinding stack */
1152fail1:
1153
1154 i7300_put_devices(mci);
1155
1156fail0:
1157 kfree(pvt->tmp_prt_buffer);
1158 edac_mc_free(mci);
1159 return -ENODEV;
1160}
1161
1162/**
1163 * i7300_remove_one() - Remove the driver
1164 * @pdev: struct pci_dev pointer
1165 */
1166static void __devexit i7300_remove_one(struct pci_dev *pdev)
1167{
1168 struct mem_ctl_info *mci;
1169 char *tmp;
1170
1171 debugf0(__FILE__ ": %s()\n", __func__);
1172
1173 if (i7300_pci)
1174 edac_pci_release_generic_ctl(i7300_pci);
1175
1176 mci = edac_mc_del_mc(&pdev->dev);
1177 if (!mci)
1178 return;
1179
1180 tmp = ((struct i7300_pvt *)mci->pvt_info)->tmp_prt_buffer;
1181
1182 /* retrieve references to resources, and free those resources */
1183 i7300_put_devices(mci);
1184
1185 kfree(tmp);
1186 edac_mc_free(mci);
1187}
1188
1189/*
1190 * pci_device_id: table for which devices we are looking for
1191 *
1192 * Has only 8086:360c PCI ID
1193 */
1194static const struct pci_device_id i7300_pci_tbl[] __devinitdata = {
1195 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_I7300_MCH_ERR)},
1196 {0,} /* 0 terminated list. */
1197};
1198
1199MODULE_DEVICE_TABLE(pci, i7300_pci_tbl);
1200
1201/*
1202 * i7300_driver: pci_driver structure for this module
1203 */
1204static struct pci_driver i7300_driver = {
1205 .name = "i7300_edac",
1206 .probe = i7300_init_one,
1207 .remove = __devexit_p(i7300_remove_one),
1208 .id_table = i7300_pci_tbl,
1209};
1210
1211/**
1212 * i7300_init() - Registers the driver
1213 */
1214static int __init i7300_init(void)
1215{
1216 int pci_rc;
1217
1218 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1219
1220 /* Ensure that the OPSTATE is set correctly for POLL or NMI */
1221 opstate_init();
1222
1223 pci_rc = pci_register_driver(&i7300_driver);
1224
1225 return (pci_rc < 0) ? pci_rc : 0;
1226}
1227
1228/**
1229 * i7300_init() - Unregisters the driver
1230 */
1231static void __exit i7300_exit(void)
1232{
1233 debugf2("MC: " __FILE__ ": %s()\n", __func__);
1234 pci_unregister_driver(&i7300_driver);
1235}
1236
1237module_init(i7300_init);
1238module_exit(i7300_exit);
1239
1240MODULE_LICENSE("GPL");
1241MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
1242MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
1243MODULE_DESCRIPTION("MC Driver for Intel I7300 memory controllers - "
1244 I7300_REVISION);
1245
1246module_param(edac_op_state, int, 0444);
1247MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 90c038c0ad96..d278dd9cb765 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -820,7 +820,7 @@
820 820
821#define PCI_VENDOR_ID_ANIGMA 0x1051 821#define PCI_VENDOR_ID_ANIGMA 0x1051
822#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100 822#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100
823 823
824#define PCI_VENDOR_ID_EFAR 0x1055 824#define PCI_VENDOR_ID_EFAR 0x1055
825#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 825#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130
826#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 826#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463
@@ -1451,7 +1451,7 @@
1451 1451
1452#define PCI_VENDOR_ID_ZIATECH 0x1138 1452#define PCI_VENDOR_ID_ZIATECH 0x1138
1453#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 1453#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550
1454 1454
1455 1455
1456#define PCI_VENDOR_ID_SYSKONNECT 0x1148 1456#define PCI_VENDOR_ID_SYSKONNECT 0x1148
1457#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 1457#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
@@ -1605,8 +1605,8 @@
1605#define PCI_DEVICE_ID_RP8OCTA 0x0005 1605#define PCI_DEVICE_ID_RP8OCTA 0x0005
1606#define PCI_DEVICE_ID_RP8J 0x0006 1606#define PCI_DEVICE_ID_RP8J 0x0006
1607#define PCI_DEVICE_ID_RP4J 0x0007 1607#define PCI_DEVICE_ID_RP4J 0x0007
1608#define PCI_DEVICE_ID_RP8SNI 0x0008 1608#define PCI_DEVICE_ID_RP8SNI 0x0008
1609#define PCI_DEVICE_ID_RP16SNI 0x0009 1609#define PCI_DEVICE_ID_RP16SNI 0x0009
1610#define PCI_DEVICE_ID_RPP4 0x000A 1610#define PCI_DEVICE_ID_RPP4 0x000A
1611#define PCI_DEVICE_ID_RPP8 0x000B 1611#define PCI_DEVICE_ID_RPP8 0x000B
1612#define PCI_DEVICE_ID_RP4M 0x000D 1612#define PCI_DEVICE_ID_RP4M 0x000D
@@ -1616,9 +1616,9 @@
1616#define PCI_DEVICE_ID_URP8INTF 0x0802 1616#define PCI_DEVICE_ID_URP8INTF 0x0802
1617#define PCI_DEVICE_ID_URP16INTF 0x0803 1617#define PCI_DEVICE_ID_URP16INTF 0x0803
1618#define PCI_DEVICE_ID_URP8OCTA 0x0805 1618#define PCI_DEVICE_ID_URP8OCTA 0x0805
1619#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C 1619#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C
1620#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D 1620#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D
1621#define PCI_DEVICE_ID_CRP16INTF 0x0903 1621#define PCI_DEVICE_ID_CRP16INTF 0x0903
1622 1622
1623#define PCI_VENDOR_ID_CYCLADES 0x120e 1623#define PCI_VENDOR_ID_CYCLADES 0x120e
1624#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 1624#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100
@@ -2144,7 +2144,7 @@
2144#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 2144#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000
2145 2145
2146#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 2146#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
2147#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 2147#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0
2148 2148
2149#define PCI_VENDOR_ID_MELLANOX 0x15b3 2149#define PCI_VENDOR_ID_MELLANOX 0x15b3
2150#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 2150#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
@@ -2431,7 +2431,7 @@
2431#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 2431#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
2432#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 2432#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
2433#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 2433#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
2434#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 2434#define PCI_DEVICE_ID_INTEL_7505_0 0x2550
2435#define PCI_DEVICE_ID_INTEL_7205_0 0x255d 2435#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
2436#define PCI_DEVICE_ID_INTEL_82437 0x122d 2436#define PCI_DEVICE_ID_INTEL_82437 0x122d
2437#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e 2437#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
@@ -2634,6 +2634,9 @@
2634#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 2634#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
2635#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a 2635#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
2636#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e 2636#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
2637#define PCI_DEVICE_ID_INTEL_I7300_MCH_ERR 0x360c
2638#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB0 0x360f
2639#define PCI_DEVICE_ID_INTEL_I7300_MCH_FB1 0x3610
2637#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b 2640#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
2638#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c 2641#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c
2639#define PCI_DEVICE_ID_INTEL_IOAT_JSF0 0x3710 2642#define PCI_DEVICE_ID_INTEL_IOAT_JSF0 0x3710