aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mc.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_mc.h')
-rw-r--r--drivers/edac/edac_mc.h96
1 files changed, 43 insertions, 53 deletions
diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h
index 2cec157aaeba..8d9e83909b9c 100644
--- a/drivers/edac/edac_mc.h
+++ b/drivers/edac/edac_mc.h
@@ -15,11 +15,9 @@
15 * 15 *
16 */ 16 */
17 17
18
19#ifndef _EDAC_MC_H_ 18#ifndef _EDAC_MC_H_
20#define _EDAC_MC_H_ 19#define _EDAC_MC_H_
21 20
22
23#include <linux/config.h> 21#include <linux/config.h>
24#include <linux/kernel.h> 22#include <linux/kernel.h>
25#include <linux/types.h> 23#include <linux/types.h>
@@ -33,7 +31,6 @@
33#include <linux/completion.h> 31#include <linux/completion.h>
34#include <linux/kobject.h> 32#include <linux/kobject.h>
35 33
36
37#define EDAC_MC_LABEL_LEN 31 34#define EDAC_MC_LABEL_LEN 31
38#define MC_PROC_NAME_MAX_LEN 7 35#define MC_PROC_NAME_MAX_LEN 7
39 36
@@ -44,13 +41,13 @@
44#endif 41#endif
45 42
46#define edac_printk(level, prefix, fmt, arg...) \ 43#define edac_printk(level, prefix, fmt, arg...) \
47 printk(level "EDAC " prefix ": " fmt, ##arg) 44 printk(level "EDAC " prefix ": " fmt, ##arg)
48 45
49#define edac_mc_printk(mci, level, fmt, arg...) \ 46#define edac_mc_printk(mci, level, fmt, arg...) \
50 printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg) 47 printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
51 48
52#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \ 49#define edac_mc_chipset_printk(mci, level, prefix, fmt, arg...) \
53 printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg) 50 printk(level "EDAC " prefix " MC%d: " fmt, mci->mc_idx, ##arg)
54 51
55/* prefixes for edac_printk() and edac_mc_printk() */ 52/* prefixes for edac_printk() and edac_mc_printk() */
56#define EDAC_MC "MC" 53#define EDAC_MC "MC"
@@ -71,14 +68,16 @@ extern int edac_debug_level;
71#define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ ) 68#define debugf2( ... ) edac_debug_printk(2, __VA_ARGS__ )
72#define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ ) 69#define debugf3( ... ) edac_debug_printk(3, __VA_ARGS__ )
73#define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ ) 70#define debugf4( ... ) edac_debug_printk(4, __VA_ARGS__ )
74#else /* !CONFIG_EDAC_DEBUG */ 71
72#else /* !CONFIG_EDAC_DEBUG */
73
75#define debugf0( ... ) 74#define debugf0( ... )
76#define debugf1( ... ) 75#define debugf1( ... )
77#define debugf2( ... ) 76#define debugf2( ... )
78#define debugf3( ... ) 77#define debugf3( ... )
79#define debugf4( ... ) 78#define debugf4( ... )
80#endif /* !CONFIG_EDAC_DEBUG */
81 79
80#endif /* !CONFIG_EDAC_DEBUG */
82 81
83#define edac_xstr(s) edac_str(s) 82#define edac_xstr(s) edac_str(s)
84#define edac_str(s) #s 83#define edac_str(s) #s
@@ -86,7 +85,8 @@ extern int edac_debug_level;
86 85
87#define BIT(x) (1 << (x)) 86#define BIT(x) (1 << (x))
88 87
89#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, PCI_DEVICE_ID_ ## vend ## _ ## dev 88#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
89 PCI_DEVICE_ID_ ## vend ## _ ## dev
90 90
91/* memory devices */ 91/* memory devices */
92enum dev_type { 92enum dev_type {
@@ -136,7 +136,6 @@ enum mem_type {
136#define MEM_FLAG_RDDR BIT(MEM_RDDR) 136#define MEM_FLAG_RDDR BIT(MEM_RDDR)
137#define MEM_FLAG_RMBS BIT(MEM_RMBS) 137#define MEM_FLAG_RMBS BIT(MEM_RMBS)
138 138
139
140/* chipset Error Detection and Correction capabilities and mode */ 139/* chipset Error Detection and Correction capabilities and mode */
141enum edac_type { 140enum edac_type {
142 EDAC_UNKNOWN = 0, /* Unknown if ECC is available */ 141 EDAC_UNKNOWN = 0, /* Unknown if ECC is available */
@@ -161,7 +160,6 @@ enum edac_type {
161#define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED) 160#define EDAC_FLAG_S8ECD8ED BIT(EDAC_S8ECD8ED)
162#define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED) 161#define EDAC_FLAG_S16ECD16ED BIT(EDAC_S16ECD16ED)
163 162
164
165/* scrubbing capabilities */ 163/* scrubbing capabilities */
166enum scrub_type { 164enum scrub_type {
167 SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */ 165 SCRUB_UNKNOWN = 0, /* Unknown if scrubber is available */
@@ -269,20 +267,19 @@ enum scrub_type {
269 * PS - I enjoyed writing all that about as much as you enjoyed reading it. 267 * PS - I enjoyed writing all that about as much as you enjoyed reading it.
270 */ 268 */
271 269
272
273struct channel_info { 270struct channel_info {
274 int chan_idx; /* channel index */ 271 int chan_idx; /* channel index */
275 u32 ce_count; /* Correctable Errors for this CHANNEL */ 272 u32 ce_count; /* Correctable Errors for this CHANNEL */
276 char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */ 273 char label[EDAC_MC_LABEL_LEN + 1]; /* DIMM label on motherboard */
277 struct csrow_info *csrow; /* the parent */ 274 struct csrow_info *csrow; /* the parent */
278}; 275};
279 276
280
281struct csrow_info { 277struct csrow_info {
282 unsigned long first_page; /* first page number in dimm */ 278 unsigned long first_page; /* first page number in dimm */
283 unsigned long last_page; /* last page number in dimm */ 279 unsigned long last_page; /* last page number in dimm */
284 unsigned long page_mask; /* used for interleaving - 280 unsigned long page_mask; /* used for interleaving -
285 0UL for non intlv */ 281 * 0UL for non intlv
282 */
286 u32 nr_pages; /* number of pages in csrow */ 283 u32 nr_pages; /* number of pages in csrow */
287 u32 grain; /* granularity of reported error in bytes */ 284 u32 grain; /* granularity of reported error in bytes */
288 int csrow_idx; /* the chip-select row */ 285 int csrow_idx; /* the chip-select row */
@@ -301,18 +298,18 @@ struct csrow_info {
301 struct channel_info *channels; 298 struct channel_info *channels;
302}; 299};
303 300
304
305struct mem_ctl_info { 301struct mem_ctl_info {
306 struct list_head link; /* for global list of mem_ctl_info structs */ 302 struct list_head link; /* for global list of mem_ctl_info structs */
307 unsigned long mtype_cap; /* memory types supported by mc */ 303 unsigned long mtype_cap; /* memory types supported by mc */
308 unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */ 304 unsigned long edac_ctl_cap; /* Mem controller EDAC capabilities */
309 unsigned long edac_cap; /* configuration capabilities - this is 305 unsigned long edac_cap; /* configuration capabilities - this is
310 closely related to edac_ctl_cap. The 306 * closely related to edac_ctl_cap. The
311 difference is that the controller 307 * difference is that the controller may be
312 may be capable of s4ecd4ed which would 308 * capable of s4ecd4ed which would be listed
313 be listed in edac_ctl_cap, but if 309 * in edac_ctl_cap, but if channels aren't
314 channels aren't capable of s4ecd4ed then the 310 * capable of s4ecd4ed then the edac_cap would
315 edac_cap would not have that capability. */ 311 * not have that capability.
312 */
316 unsigned long scrub_cap; /* chipset scrub capabilities */ 313 unsigned long scrub_cap; /* chipset scrub capabilities */
317 enum scrub_type scrub_mode; /* current scrub mode */ 314 enum scrub_type scrub_mode; /* current scrub mode */
318 315
@@ -324,7 +321,7 @@ struct mem_ctl_info {
324 */ 321 */
325 /* FIXME - why not send the phys page to begin with? */ 322 /* FIXME - why not send the phys page to begin with? */
326 unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci, 323 unsigned long (*ctl_page_to_phys) (struct mem_ctl_info * mci,
327 unsigned long page); 324 unsigned long page);
328 int mc_idx; 325 int mc_idx;
329 int nr_csrows; 326 int nr_csrows;
330 struct csrow_info *csrows; 327 struct csrow_info *csrows;
@@ -356,67 +353,66 @@ struct mem_ctl_info {
356 struct completion kobj_complete; 353 struct completion kobj_complete;
357}; 354};
358 355
359
360
361/* write all or some bits in a byte-register*/ 356/* write all or some bits in a byte-register*/
362static inline void pci_write_bits8(struct pci_dev *pdev, int offset, 357static inline void pci_write_bits8(struct pci_dev *pdev, int offset, u8 value,
363 u8 value, u8 mask) 358 u8 mask)
364{ 359{
365 if (mask != 0xff) { 360 if (mask != 0xff) {
366 u8 buf; 361 u8 buf;
362
367 pci_read_config_byte(pdev, offset, &buf); 363 pci_read_config_byte(pdev, offset, &buf);
368 value &= mask; 364 value &= mask;
369 buf &= ~mask; 365 buf &= ~mask;
370 value |= buf; 366 value |= buf;
371 } 367 }
368
372 pci_write_config_byte(pdev, offset, value); 369 pci_write_config_byte(pdev, offset, value);
373} 370}
374 371
375
376/* write all or some bits in a word-register*/ 372/* write all or some bits in a word-register*/
377static inline void pci_write_bits16(struct pci_dev *pdev, int offset, 373static inline void pci_write_bits16(struct pci_dev *pdev, int offset,
378 u16 value, u16 mask) 374 u16 value, u16 mask)
379{ 375{
380 if (mask != 0xffff) { 376 if (mask != 0xffff) {
381 u16 buf; 377 u16 buf;
378
382 pci_read_config_word(pdev, offset, &buf); 379 pci_read_config_word(pdev, offset, &buf);
383 value &= mask; 380 value &= mask;
384 buf &= ~mask; 381 buf &= ~mask;
385 value |= buf; 382 value |= buf;
386 } 383 }
384
387 pci_write_config_word(pdev, offset, value); 385 pci_write_config_word(pdev, offset, value);
388} 386}
389 387
390
391/* write all or some bits in a dword-register*/ 388/* write all or some bits in a dword-register*/
392static inline void pci_write_bits32(struct pci_dev *pdev, int offset, 389static inline void pci_write_bits32(struct pci_dev *pdev, int offset,
393 u32 value, u32 mask) 390 u32 value, u32 mask)
394{ 391{
395 if (mask != 0xffff) { 392 if (mask != 0xffff) {
396 u32 buf; 393 u32 buf;
394
397 pci_read_config_dword(pdev, offset, &buf); 395 pci_read_config_dword(pdev, offset, &buf);
398 value &= mask; 396 value &= mask;
399 buf &= ~mask; 397 buf &= ~mask;
400 value |= buf; 398 value |= buf;
401 } 399 }
400
402 pci_write_config_dword(pdev, offset, value); 401 pci_write_config_dword(pdev, offset, value);
403} 402}
404 403
405
406#ifdef CONFIG_EDAC_DEBUG 404#ifdef CONFIG_EDAC_DEBUG
407void edac_mc_dump_channel(struct channel_info *chan); 405void edac_mc_dump_channel(struct channel_info *chan);
408void edac_mc_dump_mci(struct mem_ctl_info *mci); 406void edac_mc_dump_mci(struct mem_ctl_info *mci);
409void edac_mc_dump_csrow(struct csrow_info *csrow); 407void edac_mc_dump_csrow(struct csrow_info *csrow);
410#endif /* CONFIG_EDAC_DEBUG */ 408#endif /* CONFIG_EDAC_DEBUG */
411 409
412extern int edac_mc_add_mc(struct mem_ctl_info *mci); 410extern int edac_mc_add_mc(struct mem_ctl_info *mci);
413extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev); 411extern struct mem_ctl_info * edac_mc_del_mc(struct pci_dev *pdev);
414
415extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, 412extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
416 unsigned long page); 413 unsigned long page);
417 414extern void edac_mc_scrub_block(unsigned long page, unsigned long offset,
418extern void edac_mc_scrub_block(unsigned long page, 415 u32 size);
419 unsigned long offset, u32 size);
420 416
421/* 417/*
422 * The no info errors are used when error overflows are reported. 418 * The no info errors are used when error overflows are reported.
@@ -429,31 +425,25 @@ extern void edac_mc_scrub_block(unsigned long page,
429 * statement clutter and extra function arguments. 425 * statement clutter and extra function arguments.
430 */ 426 */
431extern void edac_mc_handle_ce(struct mem_ctl_info *mci, 427extern void edac_mc_handle_ce(struct mem_ctl_info *mci,
432 unsigned long page_frame_number, 428 unsigned long page_frame_number, unsigned long offset_in_page,
433 unsigned long offset_in_page, 429 unsigned long syndrome, int row, int channel,
434 unsigned long syndrome, 430 const char *msg);
435 int row, int channel, const char *msg);
436
437extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci, 431extern void edac_mc_handle_ce_no_info(struct mem_ctl_info *mci,
438 const char *msg); 432 const char *msg);
439
440extern void edac_mc_handle_ue(struct mem_ctl_info *mci, 433extern void edac_mc_handle_ue(struct mem_ctl_info *mci,
441 unsigned long page_frame_number, 434 unsigned long page_frame_number, unsigned long offset_in_page,
442 unsigned long offset_in_page, 435 int row, const char *msg);
443 int row, const char *msg);
444
445extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci, 436extern void edac_mc_handle_ue_no_info(struct mem_ctl_info *mci,
446 const char *msg); 437 const char *msg);
447 438
448/* 439/*
449 * This kmalloc's and initializes all the structures. 440 * This kmalloc's and initializes all the structures.
450 * Can't be used if all structures don't have the same lifetime. 441 * Can't be used if all structures don't have the same lifetime.
451 */ 442 */
452extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, 443extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
453 unsigned nr_csrows, unsigned nr_chans); 444 unsigned nr_chans);
454 445
455/* Free an mc previously allocated by edac_mc_alloc() */ 446/* Free an mc previously allocated by edac_mc_alloc() */
456extern void edac_mc_free(struct mem_ctl_info *mci); 447extern void edac_mc_free(struct mem_ctl_info *mci);
457 448
458
459#endif /* _EDAC_MC_H_ */ 449#endif /* _EDAC_MC_H_ */