linux/drivers/edac/i5100_edac.c
<<
>>
Prefs
   1/*
   2 * Intel 5100 Memory Controllers kernel module
   3 *
   4 * This file may be distributed under the terms of the
   5 * GNU General Public License.
   6 *
   7 * This module is based on the following document:
   8 *
   9 * Intel 5100X Chipset Memory Controller Hub (MCH) - Datasheet
  10 *      http://download.intel.com/design/chipsets/datashts/318378.pdf
  11 *
  12 * The intel 5100 has two independent channels. EDAC core currently
  13 * can not reflect this configuration so instead the chip-select
  14 * rows for each respective channel are laid out one after another,
  15 * the first half belonging to channel 0, the second half belonging
  16 * to channel 1.
  17 *
  18 * This driver is for DDR2 DIMMs, and it uses chip select to select among the
  19 * several ranks. However, instead of showing memories as ranks, it outputs
  20 * them as DIMM's. An internal table creates the association between ranks
  21 * and DIMM's.
  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/edac.h>
  28#include <linux/delay.h>
  29#include <linux/mmzone.h>
  30
  31#include "edac_core.h"
  32
  33/* register addresses */
  34
  35/* device 16, func 1 */
  36#define I5100_MC                0x40    /* Memory Control Register */
  37#define         I5100_MC_SCRBEN_MASK    (1 << 7)
  38#define         I5100_MC_SCRBDONE_MASK  (1 << 4)
  39#define I5100_MS                0x44    /* Memory Status Register */
  40#define I5100_SPDDATA           0x48    /* Serial Presence Detect Status Reg */
  41#define I5100_SPDCMD            0x4c    /* Serial Presence Detect Command Reg */
  42#define I5100_TOLM              0x6c    /* Top of Low Memory */
  43#define I5100_MIR0              0x80    /* Memory Interleave Range 0 */
  44#define I5100_MIR1              0x84    /* Memory Interleave Range 1 */
  45#define I5100_AMIR_0            0x8c    /* Adjusted Memory Interleave Range 0 */
  46#define I5100_AMIR_1            0x90    /* Adjusted Memory Interleave Range 1 */
  47#define I5100_FERR_NF_MEM       0xa0    /* MC First Non Fatal Errors */
  48#define         I5100_FERR_NF_MEM_M16ERR_MASK   (1 << 16)
  49#define         I5100_FERR_NF_MEM_M15ERR_MASK   (1 << 15)
  50#define         I5100_FERR_NF_MEM_M14ERR_MASK   (1 << 14)
  51#define         I5100_FERR_NF_MEM_M12ERR_MASK   (1 << 12)
  52#define         I5100_FERR_NF_MEM_M11ERR_MASK   (1 << 11)
  53#define         I5100_FERR_NF_MEM_M10ERR_MASK   (1 << 10)
  54#define         I5100_FERR_NF_MEM_M6ERR_MASK    (1 << 6)
  55#define         I5100_FERR_NF_MEM_M5ERR_MASK    (1 << 5)
  56#define         I5100_FERR_NF_MEM_M4ERR_MASK    (1 << 4)
  57#define         I5100_FERR_NF_MEM_M1ERR_MASK    (1 << 1)
  58#define         I5100_FERR_NF_MEM_ANY_MASK      \
  59                        (I5100_FERR_NF_MEM_M16ERR_MASK | \
  60                        I5100_FERR_NF_MEM_M15ERR_MASK | \
  61                        I5100_FERR_NF_MEM_M14ERR_MASK | \
  62                        I5100_FERR_NF_MEM_M12ERR_MASK | \
  63                        I5100_FERR_NF_MEM_M11ERR_MASK | \
  64                        I5100_FERR_NF_MEM_M10ERR_MASK | \
  65                        I5100_FERR_NF_MEM_M6ERR_MASK | \
  66                        I5100_FERR_NF_MEM_M5ERR_MASK | \
  67                        I5100_FERR_NF_MEM_M4ERR_MASK | \
  68                        I5100_FERR_NF_MEM_M1ERR_MASK)
  69#define I5100_NERR_NF_MEM       0xa4    /* MC Next Non-Fatal Errors */
  70#define I5100_EMASK_MEM         0xa8    /* MC Error Mask Register */
  71
  72/* device 21 and 22, func 0 */
  73#define I5100_MTR_0     0x154   /* Memory Technology Registers 0-3 */
  74#define I5100_DMIR      0x15c   /* DIMM Interleave Range */
  75#define I5100_VALIDLOG  0x18c   /* Valid Log Markers */
  76#define I5100_NRECMEMA  0x190   /* Non-Recoverable Memory Error Log Reg A */
  77#define I5100_NRECMEMB  0x194   /* Non-Recoverable Memory Error Log Reg B */
  78#define I5100_REDMEMA   0x198   /* Recoverable Memory Data Error Log Reg A */
  79#define I5100_REDMEMB   0x19c   /* Recoverable Memory Data Error Log Reg B */
  80#define I5100_RECMEMA   0x1a0   /* Recoverable Memory Error Log Reg A */
  81#define I5100_RECMEMB   0x1a4   /* Recoverable Memory Error Log Reg B */
  82#define I5100_MTR_4     0x1b0   /* Memory Technology Registers 4,5 */
  83
  84/* bit field accessors */
  85
  86static inline u32 i5100_mc_scrben(u32 mc)
  87{
  88        return mc >> 7 & 1;
  89}
  90
  91static inline u32 i5100_mc_errdeten(u32 mc)
  92{
  93        return mc >> 5 & 1;
  94}
  95
  96static inline u32 i5100_mc_scrbdone(u32 mc)
  97{
  98        return mc >> 4 & 1;
  99}
 100
 101static inline u16 i5100_spddata_rdo(u16 a)
 102{
 103        return a >> 15 & 1;
 104}
 105
 106static inline u16 i5100_spddata_sbe(u16 a)
 107{
 108        return a >> 13 & 1;
 109}
 110
 111static inline u16 i5100_spddata_busy(u16 a)
 112{
 113        return a >> 12 & 1;
 114}
 115
 116static inline u16 i5100_spddata_data(u16 a)
 117{
 118        return a & ((1 << 8) - 1);
 119}
 120
 121static inline u32 i5100_spdcmd_create(u32 dti, u32 ckovrd, u32 sa, u32 ba,
 122                                      u32 data, u32 cmd)
 123{
 124        return  ((dti & ((1 << 4) - 1))  << 28) |
 125                ((ckovrd & 1)            << 27) |
 126                ((sa & ((1 << 3) - 1))   << 24) |
 127                ((ba & ((1 << 8) - 1))   << 16) |
 128                ((data & ((1 << 8) - 1)) <<  8) |
 129                (cmd & 1);
 130}
 131
 132static inline u16 i5100_tolm_tolm(u16 a)
 133{
 134        return a >> 12 & ((1 << 4) - 1);
 135}
 136
 137static inline u16 i5100_mir_limit(u16 a)
 138{
 139        return a >> 4 & ((1 << 12) - 1);
 140}
 141
 142static inline u16 i5100_mir_way1(u16 a)
 143{
 144        return a >> 1 & 1;
 145}
 146
 147static inline u16 i5100_mir_way0(u16 a)
 148{
 149        return a & 1;
 150}
 151
 152static inline u32 i5100_ferr_nf_mem_chan_indx(u32 a)
 153{
 154        return a >> 28 & 1;
 155}
 156
 157static inline u32 i5100_ferr_nf_mem_any(u32 a)
 158{
 159        return a & I5100_FERR_NF_MEM_ANY_MASK;
 160}
 161
 162static inline u32 i5100_nerr_nf_mem_any(u32 a)
 163{
 164        return i5100_ferr_nf_mem_any(a);
 165}
 166
 167static inline u32 i5100_dmir_limit(u32 a)
 168{
 169        return a >> 16 & ((1 << 11) - 1);
 170}
 171
 172static inline u32 i5100_dmir_rank(u32 a, u32 i)
 173{
 174        return a >> (4 * i) & ((1 << 2) - 1);
 175}
 176
 177static inline u16 i5100_mtr_present(u16 a)
 178{
 179        return a >> 10 & 1;
 180}
 181
 182static inline u16 i5100_mtr_ethrottle(u16 a)
 183{
 184        return a >> 9 & 1;
 185}
 186
 187static inline u16 i5100_mtr_width(u16 a)
 188{
 189        return a >> 8 & 1;
 190}
 191
 192static inline u16 i5100_mtr_numbank(u16 a)
 193{
 194        return a >> 6 & 1;
 195}
 196
 197static inline u16 i5100_mtr_numrow(u16 a)
 198{
 199        return a >> 2 & ((1 << 2) - 1);
 200}
 201
 202static inline u16 i5100_mtr_numcol(u16 a)
 203{
 204        return a & ((1 << 2) - 1);
 205}
 206
 207
 208static inline u32 i5100_validlog_redmemvalid(u32 a)
 209{
 210        return a >> 2 & 1;
 211}
 212
 213static inline u32 i5100_validlog_recmemvalid(u32 a)
 214{
 215        return a >> 1 & 1;
 216}
 217
 218static inline u32 i5100_validlog_nrecmemvalid(u32 a)
 219{
 220        return a & 1;
 221}
 222
 223static inline u32 i5100_nrecmema_merr(u32 a)
 224{
 225        return a >> 15 & ((1 << 5) - 1);
 226}
 227
 228static inline u32 i5100_nrecmema_bank(u32 a)
 229{
 230        return a >> 12 & ((1 << 3) - 1);
 231}
 232
 233static inline u32 i5100_nrecmema_rank(u32 a)
 234{
 235        return a >>  8 & ((1 << 3) - 1);
 236}
 237
 238static inline u32 i5100_nrecmema_dm_buf_id(u32 a)
 239{
 240        return a & ((1 << 8) - 1);
 241}
 242
 243static inline u32 i5100_nrecmemb_cas(u32 a)
 244{
 245        return a >> 16 & ((1 << 13) - 1);
 246}
 247
 248static inline u32 i5100_nrecmemb_ras(u32 a)
 249{
 250        return a & ((1 << 16) - 1);
 251}
 252
 253static inline u32 i5100_redmemb_ecc_locator(u32 a)
 254{
 255        return a & ((1 << 18) - 1);
 256}
 257
 258static inline u32 i5100_recmema_merr(u32 a)
 259{
 260        return i5100_nrecmema_merr(a);
 261}
 262
 263static inline u32 i5100_recmema_bank(u32 a)
 264{
 265        return i5100_nrecmema_bank(a);
 266}
 267
 268static inline u32 i5100_recmema_rank(u32 a)
 269{
 270        return i5100_nrecmema_rank(a);
 271}
 272
 273static inline u32 i5100_recmema_dm_buf_id(u32 a)
 274{
 275        return i5100_nrecmema_dm_buf_id(a);
 276}
 277
 278static inline u32 i5100_recmemb_cas(u32 a)
 279{
 280        return i5100_nrecmemb_cas(a);
 281}
 282
 283static inline u32 i5100_recmemb_ras(u32 a)
 284{
 285        return i5100_nrecmemb_ras(a);
 286}
 287
 288/* some generic limits */
 289#define I5100_MAX_RANKS_PER_CHAN        6
 290#define I5100_CHANNELS                      2
 291#define I5100_MAX_RANKS_PER_DIMM        4
 292#define I5100_DIMM_ADDR_LINES           (6 - 3) /* 64 bits / 8 bits per byte */
 293#define I5100_MAX_DIMM_SLOTS_PER_CHAN   4
 294#define I5100_MAX_RANK_INTERLEAVE       4
 295#define I5100_MAX_DMIRS                 5
 296#define I5100_SCRUB_REFRESH_RATE        (5 * 60 * HZ)
 297
 298struct i5100_priv {
 299        /* ranks on each dimm -- 0 maps to not present -- obtained via SPD */
 300        int dimm_numrank[I5100_CHANNELS][I5100_MAX_DIMM_SLOTS_PER_CHAN];
 301
 302        /*
 303         * mainboard chip select map -- maps i5100 chip selects to
 304         * DIMM slot chip selects.  In the case of only 4 ranks per
 305         * channel, the mapping is fairly obvious but not unique.
 306         * we map -1 -> NC and assume both channels use the same
 307         * map...
 308         *
 309         */
 310        int dimm_csmap[I5100_MAX_DIMM_SLOTS_PER_CHAN][I5100_MAX_RANKS_PER_DIMM];
 311
 312        /* memory interleave range */
 313        struct {
 314                u64      limit;
 315                unsigned way[2];
 316        } mir[I5100_CHANNELS];
 317
 318        /* adjusted memory interleave range register */
 319        unsigned amir[I5100_CHANNELS];
 320
 321        /* dimm interleave range */
 322        struct {
 323                unsigned rank[I5100_MAX_RANK_INTERLEAVE];
 324                u64      limit;
 325        } dmir[I5100_CHANNELS][I5100_MAX_DMIRS];
 326
 327        /* memory technology registers... */
 328        struct {
 329                unsigned present;       /* 0 or 1 */
 330                unsigned ethrottle;     /* 0 or 1 */
 331                unsigned width;         /* 4 or 8 bits  */
 332                unsigned numbank;       /* 2 or 3 lines */
 333                unsigned numrow;        /* 13 .. 16 lines */
 334                unsigned numcol;        /* 11 .. 12 lines */
 335        } mtr[I5100_CHANNELS][I5100_MAX_RANKS_PER_CHAN];
 336
 337        u64 tolm;               /* top of low memory in bytes */
 338        unsigned ranksperchan;  /* number of ranks per channel */
 339
 340        struct pci_dev *mc;     /* device 16 func 1 */
 341        struct pci_dev *ch0mm;  /* device 21 func 0 */
 342        struct pci_dev *ch1mm;  /* device 22 func 0 */
 343
 344        struct delayed_work i5100_scrubbing;
 345        int scrub_enable;
 346};
 347
 348/* map a rank/chan to a slot number on the mainboard */
 349static int i5100_rank_to_slot(const struct mem_ctl_info *mci,
 350                              int chan, int rank)
 351{
 352        const struct i5100_priv *priv = mci->pvt_info;
 353        int i;
 354
 355        for (i = 0; i < I5100_MAX_DIMM_SLOTS_PER_CHAN; i++) {
 356                int j;
 357                const int numrank = priv->dimm_numrank[chan][i];
 358
 359                for (j = 0; j < numrank; j++)
 360                        if (priv->dimm_csmap[i][j] == rank)
 361                                return i * 2 + chan;
 362        }
 363
 364        return -1;
 365}
 366
 367static const char *i5100_err_msg(unsigned err)
 368{
 369        static const char *merrs[] = {
 370                "unknown", /* 0 */
 371                "uncorrectable data ECC on replay", /* 1 */
 372                "unknown", /* 2 */
 373                "unknown", /* 3 */
 374                "aliased uncorrectable demand data ECC", /* 4 */
 375                "aliased uncorrectable spare-copy data ECC", /* 5 */
 376                "aliased uncorrectable patrol data ECC", /* 6 */
 377                "unknown", /* 7 */
 378                "unknown", /* 8 */
 379                "unknown", /* 9 */
 380                "non-aliased uncorrectable demand data ECC", /* 10 */
 381                "non-aliased uncorrectable spare-copy data ECC", /* 11 */
 382                "non-aliased uncorrectable patrol data ECC", /* 12 */
 383                "unknown", /* 13 */
 384                "correctable demand data ECC", /* 14 */
 385                "correctable spare-copy data ECC", /* 15 */
 386                "correctable patrol data ECC", /* 16 */
 387                "unknown", /* 17 */
 388                "SPD protocol error", /* 18 */
 389                "unknown", /* 19 */
 390                "spare copy initiated", /* 20 */
 391                "spare copy completed", /* 21 */
 392        };
 393        unsigned i;
 394
 395        for (i = 0; i < ARRAY_SIZE(merrs); i++)
 396                if (1 << i & err)
 397                        return merrs[i];
 398
 399        return "none";
 400}
 401
 402/* convert csrow index into a rank (per channel -- 0..5) */
 403static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
 404{
 405        const struct i5100_priv *priv = mci->pvt_info;
 406
 407        return csrow % priv->ranksperchan;
 408}
 409
 410/* convert csrow index into a channel (0..1) */
 411static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
 412{
 413        const struct i5100_priv *priv = mci->pvt_info;
 414
 415        return csrow / priv->ranksperchan;
 416}
 417
 418static void i5100_handle_ce(struct mem_ctl_info *mci,
 419                            int chan,
 420                            unsigned bank,
 421                            unsigned rank,
 422                            unsigned long syndrome,
 423                            unsigned cas,
 424                            unsigned ras,
 425                            const char *msg)
 426{
 427        char detail[80];
 428
 429        /* Form out message */
 430        snprintf(detail, sizeof(detail),
 431                 "bank %u, cas %u, ras %u\n",
 432                 bank, cas, ras);
 433
 434        edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
 435                             0, 0, syndrome,
 436                             chan, rank, -1,
 437                             msg, detail);
 438}
 439
 440static void i5100_handle_ue(struct mem_ctl_info *mci,
 441                            int chan,
 442                            unsigned bank,
 443                            unsigned rank,
 444                            unsigned long syndrome,
 445                            unsigned cas,
 446                            unsigned ras,
 447                            const char *msg)
 448{
 449        char detail[80];
 450
 451        /* Form out message */
 452        snprintf(detail, sizeof(detail),
 453                 "bank %u, cas %u, ras %u\n",
 454                 bank, cas, ras);
 455
 456        edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
 457                             0, 0, syndrome,
 458                             chan, rank, -1,
 459                             msg, detail);
 460}
 461
 462static void i5100_read_log(struct mem_ctl_info *mci, int chan,
 463                           u32 ferr, u32 nerr)
 464{
 465        struct i5100_priv *priv = mci->pvt_info;
 466        struct pci_dev *pdev = (chan) ? priv->ch1mm : priv->ch0mm;
 467        u32 dw;
 468        u32 dw2;
 469        unsigned syndrome = 0;
 470        unsigned ecc_loc = 0;
 471        unsigned merr;
 472        unsigned bank;
 473        unsigned rank;
 474        unsigned cas;
 475        unsigned ras;
 476
 477        pci_read_config_dword(pdev, I5100_VALIDLOG, &dw);
 478
 479        if (i5100_validlog_redmemvalid(dw)) {
 480                pci_read_config_dword(pdev, I5100_REDMEMA, &dw2);
 481                syndrome = dw2;
 482                pci_read_config_dword(pdev, I5100_REDMEMB, &dw2);
 483                ecc_loc = i5100_redmemb_ecc_locator(dw2);
 484        }
 485
 486        if (i5100_validlog_recmemvalid(dw)) {
 487                const char *msg;
 488
 489                pci_read_config_dword(pdev, I5100_RECMEMA, &dw2);
 490                merr = i5100_recmema_merr(dw2);
 491                bank = i5100_recmema_bank(dw2);
 492                rank = i5100_recmema_rank(dw2);
 493
 494                pci_read_config_dword(pdev, I5100_RECMEMB, &dw2);
 495                cas = i5100_recmemb_cas(dw2);
 496                ras = i5100_recmemb_ras(dw2);
 497
 498                /* FIXME:  not really sure if this is what merr is...
 499                 */
 500                if (!merr)
 501                        msg = i5100_err_msg(ferr);
 502                else
 503                        msg = i5100_err_msg(nerr);
 504
 505                i5100_handle_ce(mci, chan, bank, rank, syndrome, cas, ras, msg);
 506        }
 507
 508        if (i5100_validlog_nrecmemvalid(dw)) {
 509                const char *msg;
 510
 511                pci_read_config_dword(pdev, I5100_NRECMEMA, &dw2);
 512                merr = i5100_nrecmema_merr(dw2);
 513                bank = i5100_nrecmema_bank(dw2);
 514                rank = i5100_nrecmema_rank(dw2);
 515
 516                pci_read_config_dword(pdev, I5100_NRECMEMB, &dw2);
 517                cas = i5100_nrecmemb_cas(dw2);
 518                ras = i5100_nrecmemb_ras(dw2);
 519
 520                /* FIXME:  not really sure if this is what merr is...
 521                 */
 522                if (!merr)
 523                        msg = i5100_err_msg(ferr);
 524                else
 525                        msg = i5100_err_msg(nerr);
 526
 527                i5100_handle_ue(mci, chan, bank, rank, syndrome, cas, ras, msg);
 528        }
 529
 530        pci_write_config_dword(pdev, I5100_VALIDLOG, dw);
 531}
 532
 533static void i5100_check_error(struct mem_ctl_info *mci)
 534{
 535        struct i5100_priv *priv = mci->pvt_info;
 536        u32 dw, dw2;
 537
 538        pci_read_config_dword(priv->mc, I5100_FERR_NF_MEM, &dw);
 539        if (i5100_ferr_nf_mem_any(dw)) {
 540
 541                pci_read_config_dword(priv->mc, I5100_NERR_NF_MEM, &dw2);
 542
 543                i5100_read_log(mci, i5100_ferr_nf_mem_chan_indx(dw),
 544                               i5100_ferr_nf_mem_any(dw),
 545                               i5100_nerr_nf_mem_any(dw2));
 546
 547                pci_write_config_dword(priv->mc, I5100_NERR_NF_MEM, dw2);
 548        }
 549        pci_write_config_dword(priv->mc, I5100_FERR_NF_MEM, dw);
 550}
 551
 552/* The i5100 chipset will scrub the entire memory once, then
 553 * set a done bit. Continuous scrubbing is achieved by enqueing
 554 * delayed work to a workqueue, checking every few minutes if
 555 * the scrubbing has completed and if so reinitiating it.
 556 */
 557
 558static void i5100_refresh_scrubbing(struct work_struct *work)
 559{
 560        struct delayed_work *i5100_scrubbing = container_of(work,
 561                                                            struct delayed_work,
 562                                                            work);
 563        struct i5100_priv *priv = container_of(i5100_scrubbing,
 564                                               struct i5100_priv,
 565                                               i5100_scrubbing);
 566        u32 dw;
 567
 568        pci_read_config_dword(priv->mc, I5100_MC, &dw);
 569
 570        if (priv->scrub_enable) {
 571
 572                pci_read_config_dword(priv->mc, I5100_MC, &dw);
 573
 574                if (i5100_mc_scrbdone(dw)) {
 575                        dw |= I5100_MC_SCRBEN_MASK;
 576                        pci_write_config_dword(priv->mc, I5100_MC, dw);
 577                        pci_read_config_dword(priv->mc, I5100_MC, &dw);
 578                }
 579
 580                schedule_delayed_work(&(priv->i5100_scrubbing),
 581                                      I5100_SCRUB_REFRESH_RATE);
 582        }
 583}
 584/*
 585 * The bandwidth is based on experimentation, feel free to refine it.
 586 */
 587static int i5100_set_scrub_rate(struct mem_ctl_info *mci, u32 bandwidth)
 588{
 589        struct i5100_priv *priv = mci->pvt_info;
 590        u32 dw;
 591
 592        pci_read_config_dword(priv->mc, I5100_MC, &dw);
 593        if (bandwidth) {
 594                priv->scrub_enable = 1;
 595                dw |= I5100_MC_SCRBEN_MASK;
 596                schedule_delayed_work(&(priv->i5100_scrubbing),
 597                                      I5100_SCRUB_REFRESH_RATE);
 598        } else {
 599                priv->scrub_enable = 0;
 600                dw &= ~I5100_MC_SCRBEN_MASK;
 601                cancel_delayed_work(&(priv->i5100_scrubbing));
 602        }
 603        pci_write_config_dword(priv->mc, I5100_MC, dw);
 604
 605        pci_read_config_dword(priv->mc, I5100_MC, &dw);
 606
 607        bandwidth = 5900000 * i5100_mc_scrben(dw);
 608
 609        return bandwidth;
 610}
 611
 612static int i5100_get_scrub_rate(struct mem_ctl_info *mci)
 613{
 614        2" class="sref">u32 bandwidth)
 588{
 615" id="L64"> 614        2" cliead_config_dword<_ href="+code=i5100_mc_scrb="sref">deally si6 class="sref">u32 ferri" class="sref">i5100_ress="line" name="L610"> 610}
dw2);
 615" id="L64"> 614        ss="sref">HW_EVENT_ERR_UNCORRECTED, mci, 1,
 526ras =  606
 607        62ne" name="L609"> 609        return  520    62h;
}
mci->pvt_inft_inamenfoice_funedac/i5100_e9namft_inamenfoice_funeL607" name="L474"> 474   vend" id="L532" classvend" VENT_;
 522                     name="L474"> 474   nfoicee="L607"> 607msg =                      name="L474"> 474   funedac/i5100_e9namfuneL607code=i5100_get_scrub_rate" class="sref"ferr" cla6s="sref">ferr);
mem_ctl_inf=msg" cla6s="sref">msg = mci->pvt_inef=a href="+code=pef=/i5100_edac.c#L614" idNULLa href="+code=pNULL589" id="L589" class="line" name="L589"> 61(n62        , dw);
msg6/a>);62"drivers/edac/i5100_edac.c#L598" id=ef=a href="+code=pef=/i5100_edac.c#L614" idft_inamenfoicedac/i5100_e9namft_inamenfoiceL607" class="line" nvend" id="L532" classvend" VENT_474"> 474   nfoicee="L607"> 607 56863f_mem_any" class="sref">i5100_ferr_nf_mem_6=pdev" cl6ss="sref">pdev, dw &= ~ 521i5100_ferr_nf_mem_6=
63                          strb" nk   63ef="+code=I5100_MC" class="sref">I5100_MC<6ef">i51006check_error(struct <6 href63w);
 *630_mc_scrbdone" class="sref">ib" nk   priv 609        return      6  u32 , <6 href="+code=dw2" class=6sref"6dw2;
 609        return       6 if (i5100_ferr_nf_mem_6ny(d6))>}
{

 612static int 6c,  60764+code=mem_ctl_info" class="sref">mem_ctl_inf/a>,  613{
 614        2" class="sref">u32 bandwid         6        474   "+cod"sref">i5100_handle"+cod"sre/i5100_edac.c#L614" id="srefcsrom_to href="drivers/edac/i5100_csrom_to hrefL607" class="line" n"drivers/edac/i5100_edac.c#L527" id="L527" srome="L607"> 607bandwid msg" cla6     474   "+cof">i5100_handle"+co/i5100_edac.c#L614" id="srefcsrom_to "+cof">i5100_handle="srefcsrom_to "+coL607" class="line" n"drivers/edac/i5100_edac.c#L527" id="L527" srome="L607"> 607bandwid /a>     6ref="+code=dw2" class="s6ef">d62));
 474   addr_dw2"href="drivers/edaddr_dw2"hhref="+code=bandwidth" class="sref">bandwid w, <6ef">mc,  526dw26/a>);6mc,  521<"+code=mclass="sref">dw2);
 474   "+cof">i5100_handle"+co/i51][74"> 474   "+cod"sref">i5100_handle"+cod"sre/i51].me="L521"> 521<"+esrs/de=mclass="sref">esrs/L607code=i5100_get_scrub_rate" class="sref"EM, <6 href="+code=dw" class="6ref">65">dw &= ~bandwid550" id="6550" class="line" name="6550">65_NF_MEM" class="sref">I5100_NERR_NF_MEM 5565a href="drivers/edac/i5100_eaddr_dw2"href="drivers/edaddr_dw2"hhref =EM" class="sref">I5100_NERR_NF_MEM, 6553 593        if ef">HWDIMM_ADDR_LINES>        ss="sref">HWDIMM_ADDR_LINESne" n+EM" class="sref">I5100_NERR_NF_MEMpriv->dw2);
 474   "+cof">i5100_handle"+co/i51][74"> 474   "+cod"sref">i5100_handle"+cod"sre/i51].me="L521"> 521i5100_handlenumcolne" n+EM" class="sref">I5100_NERR_NF_MEM652);
dw2);
 474   "+cof">i5100_handle"+co/i51][74"> 474   "+cod"sref">i5100_handle"+cod"sre/i51].me="L521"> 521 607I5100_NERR_NF_MEM     6
dw2);
 474   "+cof">i5100_handle"+co/i51][74"> 474   "+cod"sref">i5100_handle"+cod"sre/i51].me="L521"> 521bandwide="L556">6556 65 by en=i510e="L526"> 526(struct <6 href65w);
 *w66v" class="sref">priv<(( name="L4long4longc (1ULL <<ers/edac/i5100_eaddr_dw2"href="drivers/edaddr_dw2"hhref) /ers/edac/i5100_ePAGE_SIZbbing),
bandwidss="sref"6i5100_scrubbing = I5100_VALID6 561 6                        6     66_NF_MEM" class="sref">I5100_NERR_NF_MEM 562    6     6631}
{

 612static int , mem_ctl_in6ine" name6"L564"> 564         6     66i)
 534{
 535        struct i5100_priv * 565             6     66ref="+code=mci" class="sref">mci->pvt_inmmhref="drivers/edmmhVENT[2]00_{vers/edac/i5100_e+code=mclass="sref">dw2);
i5100_handle"+0mmdac.c#L527" id="L527"e+code=mclass="sref">dw2);
i5100_handle"+1mmdac. }v" class="sref">i5100_priv *     66" class="line" name="L566"> 566));
i5100_priv *6 526mc);
HWCHANNELS>        ss="sref">HWCHANNELS_priv="drivers/edac/i54" id="L534" cla_pri++" class="sref">dw);
privi5100_priv * 576        if (dw &= ~mci->pvt_infs/edac/i5100_edac.c#L530" 00_edac.c#L535" id=mhref="drivers/edmmhVENT["drivers/edac/i54" id="L534" cla_pri]v" class="sref">i5100_priv * 6nable" class="sref">scru6_enab67_NF_MEM" class="sref">I5100_NERR_NF_MEMmc fors/edac/i5100_edacj4" id="L534" clj_pric#L59="drivers/edac/ij4" id="L534" clj_pric<ers/edac/i5100_eef">HWMAX_RANKS_PERWCHAN>        ss="sref">HWMAX_RANKS_PERWCHAN_priv="drivers/edac/ij4" id="L534" clj_pri++" class="sref">dw);
);
 474   addrref="drivers/edaddrhref =EM" class="sref">I5100_NERR_NF_MEM      6         if (if">priv<("drivers/edac/ij4" id="L534" clj_pric<e4) ?ers/edac/i5100_eef">HWMTR_0>        ss="sref">HWMTR_0ne" n+="drivers/edac/ij4" id="L534" clj_pric* 2 :EM" class="sref">I5100_NERR_NF_MEMdw |= HWMTR_4>        ss="sref">HWMTR_4ne" n+=("drivers/edac/ij4" id="L534" clj_pric-e4) * 2v" class="sref">i5100_priv *     6"+code=mc" class="sref">6c6 I5100_u"> 614 "> 588)s="sref">I5100_me="L607"> 607 61href="+co6e=mc" class="sref">mc 526dw);
<6 href67"drivers/edac/i5100_eMC" class="sref">I5100_line" name="L610"sref">i5100_ress="line" name="L610> 529
, me="L607"> 607bandwidlass="lin6" name="L578"> 578  6     68f_mem_any" class="sref">i5100_ferr_nf_mem_6layed_wor6(&(priv->dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521<"+esrs/de=mclass="sref">esrs/L60700_edac.c#L614" id="srefmt _"+esrs/de=mclass="sref="srefmt _"+esrs/9
 607bandwidl561 6a>                      6     68                          strers/edac/i5100_e+code=mclass="sref">dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521
 607bandwidlref="+co6I5100_SCRUB_REFRESH_RATE6/a>);68="line" name="L522"> 522                e+code=mclass="sref">dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521 606

 607bandwidla>,  586 68w);
dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521
 607bandwidla>      6583}
i5100_mc_scrbdone+code=mclass="sref">dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521 607 607
 607bandwidlname="L56line" name="L585"> 585dw |= dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri].me="L521"> 521i5100_handlenumcolne" n= 10n+="drivers/edac/ii5100_handle
 607bandwidl/a>     6
I5100_VALID6 href="+c6de=mci" class="sref">mci6/a>, 68_NERR_NF_MEM" class="sref">I5100_NERR_NF_MEM, <6ef="+code6bandwidth" class="sref">6andwi68RR_NFame="L609"> 609        return privi5100_ferr_nf_mem_60" id="L560" class="line" name="L560"> 560 }
u326}
mc/* Th id="SK,  * set dth is based on experimentation, feel free to6 594 6              }
00_val>
 612static int         6       dw |= I5100_cL608" id="L608" ch30" id="L530" class="u8>static int )s="sref">I5100_slo/de=mclass="srefslo/30" id="L530" class="u8>static int )s="sref">I5100_addrref="drivers/edaddrhref_E="L530" class="u8>static int )name="L612"> 612byid="L611" class="byid9(&(dw);
 597<6a>                      6     6          534{
 535        struct i5100_priv *I5100_6CRUB_REFRESH_RATE);
6a hre6="drivers/edacs="sref">I5100_u"> 614 "> 588)s="sref">I5100_me="L607"> 607 67 599 7              (&(;
i5100_ress="line" name="L610> 529
dw2);
 615" id="L64"> 614        ss="sref">HWSPDDATAhref_ERR_UNCORRECTED, me="L607"> 607bandwi7ing" clas7="sref">i5100_scrubbing<7a>));70ef="+code=I5100_MC" class="sref"="srefspddata_busclass="sref">dw),
spddata_busc9
 6077c70w);
, 7a href="+code=dw" class=7sref"7dw4" id="L594" class="line" name="L594"7_6C, 7a       602        }
 603        HWSPDCMDf="+_;
),
spdcmame" n6"> 586cancel_de7rben(7a href="+code=dw" class=7sref"70drivers/edac/i5100_edac.c#L578" id="L578" 7dac/i51007edac.c#L609" id="L609" c7ass="71ref="+code=mci}
7andwi711                         cancel_de7610" id="7610" class="line" name="7610">71dw;
 588el_delayed_work" class="sref">cancel_de7>i5100_ge7_scrub_rate(struct <7 href71ef="+code=I51while (1" class="sref">dw);
71ine" name="L593"> 593        if c/i5100_edac.c#L"sref">i5100_ress="line" name="L610> 529
dw2);
 615" id="L64"> 614        ss="sref">HWSPDDATAhref_ERR_UNCORRECTED, me="L607"> 607dw);
 521<="srefspddata_busclass="sref">dw),
spddata_busc9
 607 614        2" cli7ad_co71"sref">dw |= u32 <7 href71));
 588el_delayed_work" class="sref">cancel_de7>8, &7dac/i5100_edac.c#L5918s 7chiev71_NERR_NF_MEM" class="sref">I5100_NERR_NF_MEM, <7"L54 href7>ras = (72w);
 521),
spddata_rduct  607),
spddata_sb"> 586
 607 520    72">dw &= ~
I5100_NERR_NF_MEMi5100_ge7100_edac.c#L522" id="L527" cla7s="line" name=name="L612"> 612byid="L611" class="byid9 586 607bandwi7> *msg = I5107ferr" cla7s="sref">ferr);
bandwi7>" id="L67s="sref">msg = I5100_NERR_NF_MEM, <7(n72        msg7/a>);72"drivpan class="comment">/* Thfid="dimm chip select mapi5100_edac.c#L583" id="L583" class="line" na7"L528" cl7ss="line" name="L528"> 57873f_mempan class="comment">/* Ti5100_edac.c#L583" id="L583" class="line" na7"" class=7ss="sref">pdev, 7350}
/*chip selects>/*73/a>/* Th  o investign6"ref=thereme="some/way>/*  this *(struct <7 href73 * set dth is based on experimentation, feel free to7o *73v" cl>}
{
 612static int privdw);
 534{
 535        struct i5100_priv *, <7 href="+code=dw2" class=7sref"7dw2;
i5100_priv *      7 if (HWMAX_DIMM_SLOTS_PERWCHAN>        ss="sref">HWMAX_DIMM_SLOTS_PERWCHAN_priv="drivers/edac/i54" id="L534" cla_pri++" class="sref">dw);
d74">dw &= ~i5100_priv *7c, I5100_NERR_NF_MEM74="line" name="L522"> fors/edac/i5100_edacj4" id="L534" clj_pric#L59="drivers/edac/ij4" id="L534" clj_pric<ers/edac/i5100_eef">HWMAX_RANKS_PERWDIMM>        ss="sref">HWMAX_RANKS_PERWDIMM_priv="drivers/edac/ij4" id="L534" clj_pri++"EM" class="sref">I5100_NERR_NF_MEM *);
dw2);
 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri]c#L-59er}
I5100_NERR_NF_MEM, <7 msg" cla7         7ref="+code=dw2" class="s7ef">d72));
mc, dw2);
i5100_handle"sresper"+co_pric#=e4) class="sref">dw);
dw27/a>);74"drivers/edac/i5100_e               e+code=mclass="sref">dw2);
mc, priv->dw2);
(75">dw &= ~->dw2);
75                     /a>->dw2);
i5100_priv * 5575="line" name="L522"> /a>->dw2);
i5100_priv * *7553 593        if e+code=mclass="sref">dw2);
752);
dw2);
     7
dw2);
, <7556 75ef="+code=I5100_MC" c/a>->dw2);
i5100_priv *dw2);
 *w76v" class="sref">priv->dw2);
( = dw &= ~->dw2);
priv-> 562    7     7631->I5107ine" name7"L564"> 564         7     76v" cl>}
{
->pvt_infs/edac/i5100_edac.c#L530" _;
 565             7     76"sref">dw |=  612static int  576classclass="sref">dw);
7 534{
 535        struct i5100_priv *mc);
i5100_priv *, &7a href="+code=dw" class=7sref"77f_mem_any" class="sref">i5100_ferr_nf_mem_7L570"> 577        if (dw &fors/edac/i5100_edac.4" id="L534" cla_pric#L59="drivers/edac/i54" id="L534" cla_pri <ers/edac/i5100_eef">HWCHANNELS>        ss="sref">HWCHANNELS_priv="drivers/edac/i54" id="L534" cla_pri++" class="sref">dw);
scru7_enab77                     eef="drivers/edac/ij4" id="L534" clj_priv" class="sref">i5100_priv *mcI5100_MC<7aa>, );
HWMAX_DIMM_SLOTS_PERWCHAN>        ss="sref">HWMAX_DIMM_SLOTS_PERWCHAN_priv="drivers/edac/ij4" id="L534" clj_pri++" class="sref">dw);
i"drivers/edac/iu8>static int )s="sref">I5100_"sref">i5100_handler   href="+code=bandwidth" class="sref">bandwi7/name="L57            7"+code=mc" class="sref">7c7 edac.c#L535" id="L535" class="line" name9"> 615" id="L64"54" id="L534" cla_pri9"> 615" id="L64"j4" id="L534" clj_pri, 5_ERR_UNCORRECTED, "sref">i5100_handler   href)c<e0code=i5100_get_scrub_rate" class="sref7href="+co7e=mc" class="sref">mc->dw2);
i5100_handledimm_numrsre9 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri]c#L599" id="L599" class="line" name="L599"7"+code=dw7 class="sref">dw);
<7 href77"drivers/edac/i5100_eMC" clas="+c9" id="L599" class="line" name="L599"7lass="lin7" name="L578"> 578  7     78v" class="sref">priv->dw2);
i5100_handledimm_numrsre9 474   54" id="L534" cla_pri][74"> 474   j4" id="L534" clj_pri]c#L" class="line" nesref">i5100_handler   hrefERR_UN 3) +L594" id="L594" class="line" name="L594"7layed_wor7(&(privriv->priv->);78ef="+code=I5100_MC" class="sref">I5100_MC<7la>,  587 78w);
 612static int       7583}
 585     7
 586>
pvt_infs/edac/i5100_edac.c#L530" _;
mci7/a>, 78ef="+code=I5100_MC" ccccccccccccccccccccccccccccccc>
 612static int 7andwi78RR_NFclass="sref">dw);
priv);
 614 "> 588)s="sref">I5100_me="L607"> 607 670" id="L570" class="line" name="L570"> 5791                          588<3      a href="driversdme="L607"> 607     id="L589" class="line" name="L589"> 670561 7pf="drivers/edac/i5100_edac.c#L534" id="L534" class="line" name="L534"> 534{
 535        struct i5100_priv *mcpf="drivers/edac/i5100_>->pvt_inmmhref="drivers/edmmhVENT[2]00_{vers/edac/i5100_e+code=mclass="sref">dw2);
i5100_handle"+0mmdac.c#L527" id="L527"e+code=mclass="sref">dw2);
i5100_handle"+1mmdac. }v" class="sref">i5100_priv *, );
i5100_priv * 7                      7       dwers/edac/i5100_>-&g" name="L610"sref">i5100_ress="line" name="L610> 529
HWTOLM>        ss="sref">HWTOLM30" idRR_UNCORRECTED, me="L607"> 607dw);
dwers/edac/i5100_>+code=mclass="sref">dw2);
i5100_handletolm/i5100_>
 588<6i5100_handleedac.ctolm_tolm9
 607dw);
                      7     79 by en=i510e="L526"> 526I5100_7CRUB_REFRESH_RATE);
7a hre7="drivers/edacs="sref">I5100_>-&g" name="L610"sref">i5100_ress="line" name="L610> 529
HWMIR0>        ss="sref">HWMIR030" idRR_UNCORRECTED, me="L607"> 607dw);
);
dw2);
 521 588<6 607dw);
dw2);
 521 "> 588wEN    [1]c#Lers/edac/i5100_edac.cmir_wEN1a href="+code=pedac.cmir_wEN19
 607dw);
;
dw2);
 521 "> 588wEN    [0]c#Lers/edac/i5100_edac.cmir_wEN0>        ss="sredac.cmir_wEN09
 607dw);
mc));80ef="+code=I5100_MC" class="sref">I5100_MC<8t;8c80w);
i5100_ress="line" name="L610> 529
HWMIR1a href="+code=pef">HWMIR130" idRR_UNCORRECTED, me="L607"> 607dw);
;
dw2);
 521 588<6 607dw);
dw2);
 521 "> 588wEN    [1]c#Lers/edac/i5100_edac.cmir_wEN1a href="+code=pedac.cmir_wEN19
 607dw);
(&(dwers/edac/i5100_>+code=mclass="sref">dw2);
 521 "> 588wEN    [0]c#Lers/edac/i5100_edac.cmir_wEN0>        ss="sredac.cmir_wEN09
 607dw);
                      8f="+c80 by en=i510e="L526"> 526(8a href="+code=dw" class=8sref"80"drivers/edacs="sref">I5100_>-&g" name="L610"sref">i5100_ress="line" name="L610> 529
HWAMIR_0>        ss="sref">HWAMIR_030" idRR_UNCORRECTED, me="L607"> 607dw);
dw2);
 607 68ef="+code8bandwidth" class="sref">8andwi811                         -&g" name="L610"sref">i5100_ress="line" name="L610> 529
HWAMIR_1a href="+code=pef">HWAMIR_130" idRR_UNCORRECTED, me="L607"> 607dw);
81dw;
dw2);
 607 68e399 8_scrub_rate(struct <8 href81ef="+code=I5100_MC" class="sref">I5100_MC<8o *81ine" name="L5fors/edac/i5100_edac.4" id="L534" cla_pric#L59="drivers/edac/i54" id="L534" cla_pri <ers/edac/i5100_eef">HWCHANNELS>        ss="sref">HWCHANNELS_priv="drivers/edac/i54" id="L534" cla_pri++" class="sref">dw);
i5100_priv * 614        2" cli8ad_co81ig_dword<_ href="+code=i5100_mc_scrb="sref8>deally s86 class="sref">u32 <8 href81));
dw);
i5100_handle href="+code=bandwidth" class="sref">bandwi8"L54 href8>ras = (82v" class="sref">priv-&g" name="L610602" class="line" name="" name="L610602" 9
HWDMIR>        ss="sref">HWDMIR" cla+="drivers/edac/ij4" id="L534" clj_pric* 4idRR_UNCORRECTED, dme="L607"> 607    c="+codesref">dw);
 520    82h;
dw2);
 474   j4" id="L534" clj_pri].me="L521"> 521399 8100_edac.c#L522" id="L528" cla82="line" name="L522"> 522         >
 588<6 607    c <<e28="+codesref">dw);
msg = i5100_handle hrefc#L59="drivers/edac/ief">i5100_handle hrefc<ers/edac/i5100_eef">HWMAX_RANKS_PERWDIMM>        ss="sref">HWMAX_RANKS_PERWDIMM_priv="drivers/edac/ief">i5100_handle href++"EM" class="sref">I5100_NERR_NF_MEMferr);
if">privdw2);
 474   j4" id="L534" clj_pri].me="L521"> 521i5100_handler   href[74"> 474   ef">i5100_handle href]00;
msg = dw |= i5100_handleedac.cdmir_esre9
 607    id="L530" class="ef">i5100_handle hrefc="+codesref">dw);
n82I5100_VALID8me, <8 href="+code=cas" class=8sref"82_NERR_NF_MEM" class="sref">I5100_NERR_NF_MEM, <8 href="+c8de=msg" class="sref">msg8/a>);82drivers/edac/i5100_edac.c#L578" id="L578" 8"L528" cl8ss="line" name="L528"> 588830);

pdev, I5100_NERR_NF_MEM, <8"
83_NF_MEM" class="sref">I5100_NERR_NF_MEM83/a>}
{
>
 612static int  *(struct <8 href83dw);
830_mc_scrbdoneref="drivers/edac/i54" id="L534" cla_priv" class="sref">i5100_priv *privdwf="drivers/edac/i5100_edac.c#L534" id="L534" class="line" name="L534"> 534{
 535        struct i5100_priv *     8  ;
 535    to=_dimmhref="drivers/edto=_dimmh_priv="drivers/edac/i54" id="L534" cla_pri++" class="sref">dw);
 534dimmct i5100_priv *      8 if (priv<00_val name="L4longivers/edac/i5100npag"href="drivers/ednpag"h/i5100_edac.c#L535" idivnpag"href="drivers/edivnpag"h9
 615" id="L64"54" id="L534" cla_pric94" id="L594" class="line" name="L594"8ny(d84">dw &= ~i5100_handle"+co_pric#_edac.c#L535" idivcsrow_to_"+cof">i5100_handleivcsrow_to_"+co9
 615" id="L64"54" id="L534" cla_pric94" id="L594" class="line" name="L594"8n
,  615" id="L64"esref">i5100_handler   hrefE#_edac.c#L535" idivcsrow_to_esref">i5100_handleedac.ccsrow_to_esre9
 615" id="L64"54" id="L534" cla_pric94" id="L594" class="line" name="L594"8ni5100_ge8href="+code=dw2" class="8ref">84ef="+code=I5100_MC" class="sref">I5100_MC<8, *);
 521i00_tinue94" id="L594" class="line" name="L594"8nmsg" cla8         8ref="+code=dw2" class="s8ef">d84));
        ss="srEDAC_DIMM_PTR9
 535    layodea href="+code=playodef="+9"> 615" id="L64"=/a>static int  535    dimmhref="drivers/eddimmh_pri9"> 615" id="L64"=/a>static int  535    n_layodea href="+code=pn_layode_pri9ord<_ href="+code=i5100_mc_scrb="sref8 w, <8ef">mc,  615" id="L64""+cof">i5100_handle"+co_pri9"> 615" id="L64"esref">i5100_handler   href, 0c94" id="L594" class="line" name="L594"8nhref="+c8de=dw2" class="sref">dw28/a>);84drivers/edac/i5100_edac.c#L578" id="L578" 8c" class=8sref">mc, priv-> 535    nr_pag"href="drivers/ednr_pag"h_priE#_edac.c#L535" idnpag"href="drivers/ednpag"h/i5194" id="L594" class="line" name="L594"8cy(85">dw &= ~dw);
85                     f">priv-> 535    graiof">i5100_handlegraio_priE#_32v" class="sref">i5100_priv * 5585="line" name="L522"> f">priv-> 535    dtypd="L611" class="dtypd_priE#_>
dw2);
 474   "+cof">i5100_handle"+co_pri][74"> 474   esref">i5100_handler   href].me="L521"> 521i5100_priv * *8553 593e" name="L522"> f">priv-> 588DEV_Xane" n:->static int i"drivers/edac/idimmct  535    mtypd="L611" class="mtypd_priE#_5"> 535    MEM_RDDRhref="+cod"> 588MEM_RDDRh/i5194" id="L594" class="line" name="L594"8cmsg" cla8555" class="line" name="8555">852);
i"drivers/edac/idimmct  535    e="L_m   ct         ss="srEDAC_SECDED/i5194" id="L594" class="line" name="L594"8c/a>     8
i"drivers/edac/isn">dntf>        ss="srsn">dntf9
 535    labela href="+code=plabelhref, sizeof>
 535    labela href="+code=plabelhref)9ord<_ href="+code=i5100_mc_scrb="sref85w, <8556 85ef="+code=I5100_MC" cef="driv"sref">i"}
(struct <8 href85"drivers/edac/i5100_eef="driv"sref">i"drivers/edac/i_mc_scr   _to_slo/de=mclass="sref_mc_scr   _to_slo/9
 615" id="L64""+cof">i5100_handle"+co_pri9"> 615" id="L64"esref">i5100_handler   hrefcel_delayed_work" class="sref">cancel_de8/a> *w86v" class="sref">priv< class="sref">I5100_NERR_NF_MEM, <8/y( = ;
 586 562    8     86="line" name="L522"> 522  > 615" id="L64""+cof">i5100_handle"+co_pri9"> 615" id="L64"esref">i5100_handler   href, (long)> 615" id="L64"PAGES_TO_MiBf">i5100_handlePAGES_TO_MiB9
cancel_de8/ *I5100_NERR_NF_MEM, <8/        8"L564"> 564         8     860_mc_riv-> 565             8     86ig_dword<_ href="+code=i5100_mc_scrb="sref8 /a>     86" class="line" name="L586"> 586}
{
>
pvt_infs/edac/i5100_edac.c#L530" _;
8
pvt_ini class="line" nai " clcode=i5100_get_scrub_rate" class="sref8href="+co8e=mc" class="sref">mcdw);
);
 578        if (dw &>
 612static int scru8_enab87lass="sref">pf="drivers/edac/i5100_e="L_mc_layodct {
mcpf="drivers/edac/i5100_edac.c#L534" id="L534" class="line" name="L534"> 534{
 *);

pvt_inch0mmf">i5100_handle"+0mmdac.c#ss="sref">pvt_inch1mmf">i5100_handle"+1mmdac.94" id="L594" class="line" name="L594"8L        8         if ( 588<3      a href="driversdme="L607"> 607     id="L589" class="line" name="L589"> 68L/a>     8"+code=mc" class="sref">8c8 i5100_handler   sper"+     id="L589" class="line" name="L589"> 68L="L556">8e=mc" class="sref">mc 526dw);
<8 href87"drivers/edac00_MC" class="sref"PCI_FUNCf">i5100_handlePCI_FUNC9
 535    devfof">i5100_handledevfo/i51c != 1code=i5100_get_scrub_rate" class="sref8lass="lin8" name="L578"> 578  8     88v" class="sref">priv        ss="srENODEV     id="L589" class="line" name="L589"> 68layed_wor8(&( 8a>                      8     88dw;

cancel_de8lref="+co8I5100_SCRUB_REFRESH_RATE8/a>);883drivers/edac00_MC" class="sref"redac/i5100_e9namrc/i51E<e0c class="sref">dw);
 588 88ine" name="L593"> 593"drivers/edac/ire=a href="+code=pre=_pric#L"drivers/edac/iredac/i5100_e9namrc/i5194" id="L594" class="line" name="L594"8la>      8583}
 585->        mci8/a>, 88ef="+code=I51r}
8andwi88"drivers/edacs="sref">I5100_>-&g" name="L610602" class="line" name="" name="L610602" 9
HWMCf">i5100_handleef">HWMC30" idRR_UNCORRECTED, dme="L607"> 607    c="+codesref">dw);
priv);
 521i5100_handleivmc_errdeteo9
 607    cc class="sref">dw);
 589">dw &= ~->i5100_handlee+cnte9
i5100_handleKERN_INFO     a}
dw);
->        ss="srENODEV     id="L589" class="line" name="L589"> 68"ref="+co8e=mc" class="sref">mc gotoL"drivers/edac/ibail_rs/edac/i5100_edac.bail_rs/e     id="L589" class="line" name="L589"> 68"a>, I5100_NERR_NF_MEM, <8 594 8                      8       dwe}
dwers/edac/i5100_>-&g" name="L610602" class="line" name="" name="L610602" 9
HWMS>        ss="sref">HWMS30" idRR_UNCORRECTED, dme="L607"> 607    c="+codesref">dw);
                      8     898sref">dwers/edac/i5100_rsresper"+f">i5100_handler   sper"+    c#L!!>
 607    ERR_UN (1 <<e8)c * 2 +L499" id="L599" class="line" name="L599"8f">I5100_8CRUB_REFRESH_RATE);
8a hre89drivers/edac/i5100_edac.c#L578" id="L578" 9 599 9               9 " class="line" name="L59s="sr901                         
HWEMASK_MEM>        ss="sref">HWEMASK_MEM30" idRR_UNCORRECTED, dme="L607"> 607    c="+codesref">dw);
;
 607    ERR_UN= ~="L530" class="ef">HWFERR_NF_MEM_ANY_MASK>        ss="sref">HWFERR_NF_MEM_ANY_MASK     id="L589" class="line" name="L589"> 69 399 9 =mc" class="sref">mc));903                         
HWEMASK_MEM>        ss="sref">HWEMASK_MEM30" idCORRECTED, dme="L607"> 607    c="+codesref">dw);
90I5109 5;
i5100_handle"+0mmdac.E#_edac.c#L535" idvt_iget"t;
i5100_handlePCI_VENDOR_ID_INTEL30" _;
(&());
i            /a>->                      9f="+c90w2;
 521i5100_handle"+0mmdac.c class="sref">dw);
->        ss="srENODEV     id="L589" class="line" name="L589"> 69dac/i51009edac.c#L609" id="L609" c9ass="91v" class="sref">priv 69ef="+code9bandwidth" class="sref">9andwi911             class="sref">I5100_NERR_NF_MEM, <9d299 9610" class="line" name="9610">91_NF_MEM" class="sref">I5100_NERR_NF_MEM 9_scrub_rate(struct <9 href913                         
i5100_handle"+0mmdac.c id="L589" class="line" name="L589"> 69e499 9href="+code=mci" class="9ref">91ine" name="L500_MC" class="sref"redac/i5100_e9namrc/i51E<e0c class="sref">dw);
 614        2" cli9ad_co912);
u32 <9 href91));
I5100_NERR_NF_MEM, <9d8 526ras = (920);
i5100_handle"+1mmdac. #_edac.c#L535" idvt_iget"t;
i5100_handlePCI_VENDOR_ID_INTEL30" _;
 520    92">dw &= ~-> 588PCI_DEVICE_ID_INTEL_i51002h30" id0c94" id="L594" class="line" name="L594"9>
 521i5100_handle"+1mmdac.c class="sref">dw);
 /a>->        ss="srENODEV     id="L589" class="line" name="L589"> 69> *msg =  69>MC, 9s="sref">ferr);
I5100_NERR_NF_MEM, <9>" id="L69s="sref">msg = n927sref">dwers/edac/i5100_redac/i5100_e9namrc/i51E#_edac.c#L535" idvt_ienable"t;
i5100_handle"+1mmdac.c id="L589" class="line" name="L589"> 69>8;
dw);
msg9/a>);92"drivers/edac/i5100_e/a>-> 59893v" class="sref">privpdev, I5100_NERR_NF_MEM, <9"
93_NF_MEM" class="sref">I5100_NERR_NF_MEM933                          521 535    EDAC_MC_LAYERWCHANNELf">i5100_handleEDAC_MC_LAYERWCHANNEL/i5194" id="L594" class="line" name="L594"9" *(struct <9 href93w);
 521i5100_priv * *935w;
 521i5100_handleis_vir=_csrow_priE#_5"> 535    falsea href="+code=pfalse/i5194" id="L594" class="line" name="L594"9"" id="L69iv" class="sref">priv 521 535    EDAC_MC_LAYERWSLOTf">i5100_handleEDAC_MC_LAYERWSLOT/i5194" id="L594" class="line" name="L594"9"deally s9  dwers/edac/i5100_layodea href="+code=playodef="+[1].me="L521"> 521i5100_handler   sper"+    94" id="L594" class="line" name="L594"9"8dwers/edac/i5100_layodea href="+code=playodef="+[1].me="L521"> 521i5100_handleis_vir=_csrow_priE#_5"> 535    trud="L611" class="trud    94" id="L594" class="line" name="L594"9"href="+c9>mc, I5100_static int  535    e="L>mc_alloedac/i5100_e9name="L>mc_alloe90idCORRECTED, ARRAY_SIZEdac/i5100_e9namARRAY_SIZE9
, layodea href="+code=playodef="+94" id="L594" class="line" name="L594"9/a>      9 if (priv<<<<<<<<<<<<="L534"> 534{
cancel_de9ny(d94">dw &r0_Mame="L521"> 521<static int dw);
->        ss="srENOMEM    94" id="L594" class="line" name="L594"9ni5100_ge9href="+code=dw2" class="9ref">94="line" name="L522"> gotoL"drivers/edac/ibail_disable""+1dac/i5100_edac.bail_disable""+1    94" id="L594" class="line" name="L594"9n *I5100_NERR_NF_MEM, <9         9        535     s/edac/i5100_edac.c#L530" c#LRR_UNCORRECTED, fs/edac/i5100_edac.c#L530" ="L535"> 535    deve="L607"> 607 69 /a>     9ref="+code=dw2" class="s9ef">d94        mc, dwers/edac/i5100_{
 535        struct i5100_priv *dw29/a>);94"drivers/edacs="sref">I5100_>+code=mclass="sref">dw2);
i5100_handler   sper"+co_priE#_ers/edac/i5100_rsresper"+f">i5100_handler   sper"+    94" id="L594" class="line" name="L594"9c" class=9sref">mc, dw2);
(951                         dw2);
i5100_handle"+0mmdac.E#_edac.c#L535" idch0mmf">i5100_handle"+0mmdac.94" id="L594" class="line" name="L594"9c
95dw;
dw2);
i5100_handle"+1mmdac. #_edac.c#L535" idch1mmf">i5100_handle"+1mmdac.94" id="L594" class="line" name="L594"9" id="L559" class="line" name="L559"> 5595ef="+code=I5100_MC" class="sref">I5100_MC<9" *9553);
RR_UN>
dw2);
Iscrubbing>">i5100_handleief">Iscrubbingf="+)idCORRECTED, _mc_screfreshIscrubbing>">i5100_handleief">IrefreshIscrubbingdac.c id="L589" class="line" name="L589"> 69c        9 class="line" name="L5549> 55495w4" id="L594" class="line" name="L594"9cmsg" cla9555" class="line" name="9555">95"sref">dwe}
}
rt maintaining it  dth is based on experimentation, feel free to9c/a>     9
dwers/edac/i5100_>-&g" name="L610602" class="line" name="" name="L610602" 9
HWMCf">i5100_handleef">HWMC30" idRR_UNCORRECTED, dme="L607"> 607    c="+codesref">dw);
 95w2;
mc_scrbeof">i5100_handleivmc_scrbeo9
 607    cc class="sref">dw);
(struct <9 href95"drivers/edac/i5100_e
dw2);
dw);
w96v" class="sref">priv 5ef">i5100_handleschedule"t;layod0> 5e9RR_UN>
dw2);
Iscrubbing>">i5100_handleief">Iscrubbingf="+)i"+codesref">dw);
dw &= ~dw);
I5100_NERR_NF_MEM, <9ss="line"9name="L562"> 562    9     96ef="+code=I5100_MC" class="sref">I5100_MC<9/ *);
Iini=_dimm_layou/de=mclass="sref_mc_scini=_dimm_layou/9
 564         9     965w;
i5100_handleief">Iini=_interleaving9
 565             9     96ig_dword<_ href="+code=i5100_mc_scrb="sref9 /a>     96" class="line" name="L596"> 5967sref">dwers/edac/i5100_="L535" class="line" name="L535"> 535    mtypd_cap535" class="linetypd_capdac. #_edac.c#L535" idMEM_FLAG_FB_DDRhref="+cod"> 588MEM_FLAG_FB_DDRhdac.94" id="L594" class="line" name="L594"9 ="L556">9dwers/edac/i5100_="L535" class="line" name="L535"> 535    e="L>clascap535" class="line="L>clascap_priE#_5"> 535    EDAC_FLAG_SECDED>        ss="srEDAC_FLAG_SECDEDdac.94" id="L594" class="line" name="L594"9 href="+c9e=mc" class="sref">mcI5100_static int  535    e="L>cap535" class="line="L>cap_priE#_5"> 535    EDAC_FLAG_SECDED>        ss="srEDAC_FLAG_SECDEDdac.94" id="L594" class="line" name="L594"9a>, &9a href="+code=dw" class=9sref"970);
 535    mod_ cla535" class="lineod_ cla_priE#_5}
(        if ( 535    mod_vodct >"not clasioned"th is b94" id="L594" class="line" name="L594"9a50" id="9nable" class="sref">scru9_enab97dw;
 535    clas cla535" class="linclas cla_priE#_5}
mcstatic int  535    devs cla535" class="lindevs cla/i51E#_edac.c#L535" idve=" cla535" class="linve=" cla9
 *);
 535    claspag"_to_phyea href="+code=pclaspag"_to_phye/i51E#_edac.c#L535" idNULLf">i5100_handleNULLdac.94" id="L594" class="line" name="L594"9a        9         if (static int  535    e="L>checef">i5100_handlee="L>chece/i51E#_edac.c#L535" ide" namchece_error>">i5100_handleief">Ichece_errordac.94" id="L594" class="line" name="L594"9a/a>     9"+code=mc" class="sref">9c977sref">dwers/edac/i5100_="L535" class="line" name="L535"> 535    set_sdramIscrub_ratea href="+code=pset_sdramIscrub_rate/i51E#_edac.c#L535" ide" namset_scrub_ratea href="+code=pe" namset_scrub_ratedac.94" id="L594" class="line" name="L594"9a="L556">9e=mc" class="sref">mcdwers/edac/i5100_="L535" class="line" name="L535"> 535    get_sdramIscrub_ratea href="+code=pget_sdramIscrub_rate/i51E#_edac.c#L535" ide" namget_scrub_ratea href="+code=pe" namget_scrub_ratedac.94" id="L594" class="line" name="L594"9ahref="+c9 class="sref">dw);
<9 href97drivers/edac/i5100_edac.c#L578" id="L578" 9lass="lin9" name="L578"> 578  9     980);
="L530" class="=/a>static int (&( 9a>                      9     98dw;
i5100_handlee="L>op_>}
dw);
 589 98ine" name="L5case_5"> 535    EDAC_OPSTATE_POLLf">i5100_handleEDAC_OPSTATE_POLLne" :lass="sref">dw);
 535    EDAC_OPSTATE_NMIf">i5100_handleEDAC_OPSTATE_NMIne" :lass="sref">dw);
 585);
     9
dwdefault:lass="sref">dw);
9de=mci" class="sref">mci9/a>, 98ef="+code=I5100_MC" cC" class="sref"e="L>op_>}
i5100_handlee="L>op_>}
 535    EDAC_OPSTATE_POLLf">i5100_handleEDAC_OPSTATE_POLLne" 94" id="L594" class="line" name="L594"9lhref="+c9bandwidth" class="sref">9andwi98"drivers/edac/i5100_ebreak94" id="L594" class="line" name="L594"9="+code=p9iv" class="sref">priv);
I5100_NERR_NF_MEM, <90" id="L590" class="line" name="L590"> 599h;
mc_add_/e9="L530" class="=/a>static int dw);
mc ers/edac/i5100_re=a href="+code=pre=_pric#L-edac.c#L535" idENODEV>        ss="srENODEV     id="L589" class="line" name="L589"> 69"a>, );
        ss="srbail_scrub     id="L589" class="line" name="L589"> 69"        9              I5100_NERR_NF_MEM, <9>        9       (&(dwef="driers/edac/i5100_re=a href="+code=pre=_pri id="L589" class="line" name="L589"> 69"="L556">9a>                      9     99 by en=i510e="L526"> 526I5100_9CRUB_REFRESH_RATE);
9a hre99drive"drivers/edac/ibail_scrub>        ss="srbail_scrub    :lass="sref">dw);
);
ref"+>ref"w;
dw2);
ass="sref">dw);
ref1                          5e_syncclass="line" nacancel"t;layod0> 5e_sync9RR_UN>
dw2);
Iscrubbing>">i5100_handleief">Iscrubbingf="+)c94" id="L594" class="line" name="L594" na2+code=prefa href="+code=dw" classrefa >refdw;
mc_freef">i5100_handlee="L>mc_free9="L530" class="=/a>static int mcrefef="+code=I5100_MC" class="sref">I5100_MC4+code=prefedac.c#L593" id="L593" refed>ref4rive"drivers/edac/ibail_disable""+1dac/i5100_edac.bail_disable""+1    :lass="sref">dw);
ref5w;
="L530" class="ch1mmf">i5100_handle"+1mmdac.c id="L589" class="line" name="L589"> 6me=6+code=pref      (&(dw);
dwers/edac/i5100_{t_info_pu/de=mclass="sref{t_info_pu/9="L530" class="ch1mmf">i5100_handle"+1mmdac.c id="L589" class="line" name="L589"> 6me=9+code=prefRUB_REFRESH_RATE);
refRU>refdrivers/edac/i5100_edac.c#L578" id="L578" 101"+code=preedac.c#L609" id="L609" creeda>reedrive"drivers/edac/ibail_disable""+0dac/i5100_edac.bail_disable""+0    :lass="sref">dw);
reban>ree1                         ="L530" class="ch0mmf">i5100_handle"+0mmdac.c id="L589" class="line" name="L589"> 6ree2+code=pre610" class="line" name="re610>ree_NF_MEM" class="sref">I5100_NERR_NF_MEM(struct ree3rive"drivers/edac/ibail_"+0dac/i5100_edac.bail_"+0/i51:lass="sref">dw);
="L530" class="ch0mmf">i5100_handle"+0mmdac.c id="L589" class="line" name="L589"> 6ree5+code=pre href="drivers/edac/i510re hr>reew4" id="L594" class="line" name="L594"ree6+code=pre"> 614        2" clire"> >ree6rive"drivers/edac/ibail_rs/edac/i5100_edac.bail_rs/e    :lass="sref">dw);
u32 ree7sref">dwers/edac/i5100_>-&gnisable"t;="L530" class="rs/edac/i5100_edac.c#L530" c94" id="L594" class="line" name="L594"ree8+code=predac/i5100_edac.c#L5918s redac>ree by en=i510e="L526"> 526ras = dw);
dwef="driers/edac/i5100_re=a href="+code=pre=_pri id="L589" class="line" name="L589"> 6reh1+code=preline" name="L520"> 520reh1     class="sref">I5100_NERR_NF_MEM, reh_NF_MEM" class="sref">I5100_NERR_NF_MEMIremove_ond="L611" class="line" remove_ond9>
pvt_infs/edac/i5100_edac.c#L530" code=i5100_get_scrub_rate" class="srefreh4+code=pres="sref">msg = dw);
ferr);
 612static int msg =  534{
reh8sref">dwers/edac/i5100_="L535" class="line" nameE#_5"> 535    e="L>mc_del_/edac/i5100_e9name="L>mc_del_/e9RR_UNs="sref">pvt_infs/edac/i5100_edac.c#L530" ="L535"> 535    deve="L607"> 607msgrede=>rehdrivers/edac/i5100_edac.c#L578" id="L578" 103"+code=press="line" name="L528"> 5ress=>ress            r0_Mame="L521"> 521<static int pdev, res">dw &= ~I5100_NERR_NF_MEM 535        struct i5100_priv *(struct resI510res5+code=prehref="+code=mci" class="rehre>res5w;
dw2);
I510res6+code=preiv" class="sref">privres                           5e_syncclass="line" nacancel"t;layod0> 5e_sync9RR_UN>
dw2);
Iscrubbing>">i5100_handleief">Iscrubbingf="+)c94" id="L594" class="line" name="L594" n37+code=pre  res        res8sref">dwers/edac/i5100_{t_inisable"t;="L530" class="rs/edac/i5100_edac.c#L530" c94" id="L594" class="line" name="L594"re39+code=pre>mc, I5100_>-&gnisable"t;="L530" class="r+code=mclass="sref">dw2);
i5100_handle"+0mmdac.c94" id="L594" class="line" name="L594"re4"+code=pre if (I5100_>-&gnisable"t;="L530" class="r+code=mclass="sref">dw2);
i5100_handle"+1mmdac.c id="L589" class="line" name="L589"> 6me41+code=prehref="+code=dw" class="srehre>re 1                         ="L530" class="r+code=mclass="sref">dw2);
i5100_handle"+0mmdac.c94" id="L594" class="line" name="L594"re42+code=prec, ="L530" class="r+code=mclass="sref">dw2);
i5100_handle"+1mmdac.c id="L589" class="line" name="L589"> 6me43+code=prehref="+code=dw2" class="rehre>re ef="+code=I5100_MC" class="sref">I5100_MCre w);
mc_freef">i5100_handlee="L>mc_free9="L530" class="=/a>static int dw);
mc, re ef="+code=I51r}
dw2rede=>re "drivers/edac{h/a>->="L530" class="PCI_VENDOR_ID_INTELf">i5100_handlePCI_VENDOR_ID_INTEL30" _h/a>-> 614 _edac.PCI_DEVICE_ID_INTEL_i5100">f="+c }i"+codesref">dw);
mc, ="L530" class="r/a>static int resef="+code=I5100_MC" class="sref">I5100_MCrelas>res4a hr>}

ItMC" cde=mclass="srefref">ItMC" cdac. #_class="sref">dw);
 521< cla535" class="lin cla/i51E#_edac.c#L535" idKBUILD_BASENAMEdac/i5100_e9namKBUILD_BASENAMEf="+ilass="sref">dw);
 521dw);
res7w;
 521dw);
res8w;
 521dw);
I5100_MC = ree1a hr>}
Iini=535" class="linref">Iini=9voidcrs/edac/i5100_edac.c#L578" id="L578" 1062+code=pre                        re   >ree2class="sref">dw);
 562    renam>ree3drivers/edac0nhref="drivers/edame=""cclass="line" name="rc/i5194" id="L594" class="line" name="L594"ree4+code=preI510re65+code=pre"L564"> 564         re"L5>ree5w;
RR_UNs="sref">pvt_inref">ItMC" cde=mclass="srefref">ItMC" cdac.c94" id="L594" class="line" name="L594" n66+code=pre5"> 565             re5">>reeig_dword<_ href="+code=i5100_mc_scrb="srefc_67+code=pre6" class="line" name="L5re6" >ree7sref">dwef="dri>="L530" class="r/ai"cclass="line" name="rc/i51E<e0c ?ref="drivers/edavt_i"cclass="line" name="rc/i51E:_594"="+code=I5100_MC" class="sref">I510re68+code=preree8_mc_riv->mcreedrivers/edac/i5100_edac.c#L578" id="L578" 107"+code=prea href="+code=dw" class=rea h>rea rive>}
Iexi=a href="+code=pref">Iexi=9voidcrs/edac/i5100_edac.c#L578" id="L578" 1071+code=pre        if (rea1class="sref">dw);
scrurenab>readw;
RR_UNs="sref">pvt_inref">ItMC" cde=mclass="srefref">ItMC" cdac.c94" id="L594" class="line" name="L594" n73+code=pree=mc" class="sref">mcrea3_mc_riv->reaI510re75+code=pre         if (="L530" class="ass="lini=535" class="linref">Iini=9="L530" class="ass="lexi=a href="+code=pref">Iexi=9re"+c>rea        mcrea8rive"drivers/edac/iMODULE_LICENSEdac/i5100_e9namMODULE_LICENSE9=}
dw);
readrive"drivers/edac/iMODULE_AUTHORdac/i5100_e9namMODULE_AUTHOR/a>         578  re" n>re" w;
<>=}
(&(=}
                      rea> >re"2rive"/pre>
The original LXR software by the " id="L59http://sourceforge.net/projects/lxr">LXR riveuni=yf="+idthisrexperiers/al clasion by " id="L59mailto:lxr@ ux.no">lxr@ ux.nof="+.
lxr. ux.no kindly hosted by " id="L59http://www.redpill- pro.no">Redpill L pro ASf="+idprovidla of L uxc00_vulting and operahions ser