diff options
Diffstat (limited to 'drivers/edac/i7300_edac.c')
-rw-r--r-- | drivers/edac/i7300_edac.c | 115 |
1 files changed, 44 insertions, 71 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c index 3bafa3bca148..97c22fd650ee 100644 --- a/drivers/edac/i7300_edac.c +++ b/drivers/edac/i7300_edac.c | |||
@@ -464,17 +464,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
464 | FERR_FAT_FBD, error_reg); | 464 | FERR_FAT_FBD, error_reg); |
465 | 465 | ||
466 | snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, | 466 | snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, |
467 | "FATAL (Branch=%d DRAM-Bank=%d %s " | 467 | "Bank=%d RAS=%d CAS=%d Err=0x%lx (%s))", |
468 | "RAS=%d CAS=%d Err=0x%lx (%s))", | 468 | bank, ras, cas, errors, specific); |
469 | branch, bank, | 469 | |
470 | is_wr ? "RDWR" : "RD", | 470 | edac_mc_handle_error(HW_EVENT_ERR_FATAL, mci, 0, 0, 0, |
471 | ras, cas, | 471 | branch, -1, rank, |
472 | errors, specific); | 472 | is_wr ? "Write error" : "Read error", |
473 | 473 | pvt->tmp_prt_buffer, NULL); | |
474 | /* Call the helper to output message */ | 474 | |
475 | edac_mc_handle_fbd_ue(mci, rank, branch << 1, | ||
476 | (branch << 1) + 1, | ||
477 | pvt->tmp_prt_buffer); | ||
478 | } | 475 | } |
479 | 476 | ||
480 | /* read in the 1st NON-FATAL error register */ | 477 | /* read in the 1st NON-FATAL error register */ |
@@ -513,23 +510,14 @@ static void i7300_process_fbd_error(struct mem_ctl_info *mci) | |||
513 | 510 | ||
514 | /* Form out message */ | 511 | /* Form out message */ |
515 | snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, | 512 | snprintf(pvt->tmp_prt_buffer, PAGE_SIZE, |
516 | "Corrected error (Branch=%d, Channel %d), " | 513 | "DRAM-Bank=%d RAS=%d CAS=%d, Err=0x%lx (%s))", |
517 | " DRAM-Bank=%d %s " | 514 | bank, ras, cas, errors, specific); |
518 | "RAS=%d CAS=%d, CE Err=0x%lx, Syndrome=0x%08x(%s))", | 515 | |
519 | branch, channel, | 516 | edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 0, 0, |
520 | bank, | 517 | syndrome, |
521 | is_wr ? "RDWR" : "RD", | 518 | branch >> 1, channel % 2, rank, |
522 | ras, cas, | 519 | is_wr ? "Write error" : "Read error", |
523 | errors, syndrome, specific); | 520 | pvt->tmp_prt_buffer, NULL); |
524 | |||
525 | /* | ||
526 | * Call the helper to output message | ||
527 | * NOTE: Errors are reported per-branch, and not per-channel | ||
528 | * Currently, we don't know how to identify the right | ||
529 | * channel. | ||
530 | */ | ||
531 | edac_mc_handle_fbd_ce(mci, rank, channel, | ||
532 | pvt->tmp_prt_buffer); | ||
533 | } | 521 | } |
534 | return; | 522 | return; |
535 | } | 523 | } |
@@ -617,8 +605,7 @@ static void i7300_enable_error_reporting(struct mem_ctl_info *mci) | |||
617 | static int decode_mtr(struct i7300_pvt *pvt, | 605 | static int decode_mtr(struct i7300_pvt *pvt, |
618 | int slot, int ch, int branch, | 606 | int slot, int ch, int branch, |
619 | struct i7300_dimm_info *dinfo, | 607 | struct i7300_dimm_info *dinfo, |
620 | struct csrow_info *p_csrow, | 608 | struct dimm_info *dimm) |
621 | u32 *nr_pages) | ||
622 | { | 609 | { |
623 | int mtr, ans, addrBits, channel; | 610 | int mtr, ans, addrBits, channel; |
624 | 611 | ||
@@ -650,7 +637,6 @@ static int decode_mtr(struct i7300_pvt *pvt, | |||
650 | addrBits -= 3; /* 8 bits per bytes */ | 637 | addrBits -= 3; /* 8 bits per bytes */ |
651 | 638 | ||
652 | dinfo->megabytes = 1 << addrBits; | 639 | dinfo->megabytes = 1 << addrBits; |
653 | *nr_pages = dinfo->megabytes << 8; | ||
654 | 640 | ||
655 | debugf2("\t\tWIDTH: x%d\n", MTR_DRAM_WIDTH(mtr)); | 641 | debugf2("\t\tWIDTH: x%d\n", MTR_DRAM_WIDTH(mtr)); |
656 | 642 | ||
@@ -663,11 +649,6 @@ static int decode_mtr(struct i7300_pvt *pvt, | |||
663 | debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]); | 649 | debugf2("\t\tNUMCOL: %s\n", numcol_toString[MTR_DIMM_COLS(mtr)]); |
664 | debugf2("\t\tSIZE: %d MB\n", dinfo->megabytes); | 650 | debugf2("\t\tSIZE: %d MB\n", dinfo->megabytes); |
665 | 651 | ||
666 | p_csrow->grain = 8; | ||
667 | p_csrow->mtype = MEM_FB_DDR2; | ||
668 | p_csrow->csrow_idx = slot; | ||
669 | p_csrow->page_mask = 0; | ||
670 | |||
671 | /* | 652 | /* |
672 | * The type of error detection actually depends of the | 653 | * The type of error detection actually depends of the |
673 | * mode of operation. When it is just one single memory chip, at | 654 | * mode of operation. When it is just one single memory chip, at |
@@ -677,15 +658,18 @@ static int decode_mtr(struct i7300_pvt *pvt, | |||
677 | * See datasheet Sections 7.3.6 to 7.3.8 | 658 | * See datasheet Sections 7.3.6 to 7.3.8 |
678 | */ | 659 | */ |
679 | 660 | ||
661 | dimm->nr_pages = MiB_TO_PAGES(dinfo->megabytes); | ||
662 | dimm->grain = 8; | ||
663 | dimm->mtype = MEM_FB_DDR2; | ||
680 | if (IS_SINGLE_MODE(pvt->mc_settings_a)) { | 664 | if (IS_SINGLE_MODE(pvt->mc_settings_a)) { |
681 | p_csrow->edac_mode = EDAC_SECDED; | 665 | dimm->edac_mode = EDAC_SECDED; |
682 | debugf2("\t\tECC code is 8-byte-over-32-byte SECDED+ code\n"); | 666 | debugf2("\t\tECC code is 8-byte-over-32-byte SECDED+ code\n"); |
683 | } else { | 667 | } else { |
684 | debugf2("\t\tECC code is on Lockstep mode\n"); | 668 | debugf2("\t\tECC code is on Lockstep mode\n"); |
685 | if (MTR_DRAM_WIDTH(mtr) == 8) | 669 | if (MTR_DRAM_WIDTH(mtr) == 8) |
686 | p_csrow->edac_mode = EDAC_S8ECD8ED; | 670 | dimm->edac_mode = EDAC_S8ECD8ED; |
687 | else | 671 | else |
688 | p_csrow->edac_mode = EDAC_S4ECD4ED; | 672 | dimm->edac_mode = EDAC_S4ECD4ED; |
689 | } | 673 | } |
690 | 674 | ||
691 | /* ask what device type on this row */ | 675 | /* ask what device type on this row */ |
@@ -694,9 +678,9 @@ static int decode_mtr(struct i7300_pvt *pvt, | |||
694 | IS_SCRBALGO_ENHANCED(pvt->mc_settings) ? | 678 | IS_SCRBALGO_ENHANCED(pvt->mc_settings) ? |
695 | "enhanced" : "normal"); | 679 | "enhanced" : "normal"); |
696 | 680 | ||
697 | p_csrow->dtype = DEV_X8; | 681 | dimm->dtype = DEV_X8; |
698 | } else | 682 | } else |
699 | p_csrow->dtype = DEV_X4; | 683 | dimm->dtype = DEV_X4; |
700 | 684 | ||
701 | return mtr; | 685 | return mtr; |
702 | } | 686 | } |
@@ -774,11 +758,10 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) | |||
774 | { | 758 | { |
775 | struct i7300_pvt *pvt; | 759 | struct i7300_pvt *pvt; |
776 | struct i7300_dimm_info *dinfo; | 760 | struct i7300_dimm_info *dinfo; |
777 | struct csrow_info *p_csrow; | ||
778 | int rc = -ENODEV; | 761 | int rc = -ENODEV; |
779 | int mtr; | 762 | int mtr; |
780 | int ch, branch, slot, channel; | 763 | int ch, branch, slot, channel; |
781 | u32 last_page = 0, nr_pages; | 764 | struct dimm_info *dimm; |
782 | 765 | ||
783 | pvt = mci->pvt_info; | 766 | pvt = mci->pvt_info; |
784 | 767 | ||
@@ -809,25 +792,23 @@ static int i7300_init_csrows(struct mem_ctl_info *mci) | |||
809 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], | 792 | pci_read_config_word(pvt->pci_dev_2x_0_fbd_branch[branch], |
810 | where, | 793 | where, |
811 | &pvt->mtr[slot][branch]); | 794 | &pvt->mtr[slot][branch]); |
812 | for (ch = 0; ch < MAX_BRANCHES; ch++) { | 795 | for (ch = 0; ch < MAX_CH_PER_BRANCH; ch++) { |
813 | int channel = to_channel(ch, branch); | 796 | int channel = to_channel(ch, branch); |
814 | 797 | ||
798 | dimm = EDAC_DIMM_PTR(mci->layers, mci->dimms, | ||
799 | mci->n_layers, branch, ch, slot); | ||
800 | |||
815 | dinfo = &pvt->dimm_info[slot][channel]; | 801 | dinfo = &pvt->dimm_info[slot][channel]; |
816 | p_csrow = &mci->csrows[slot]; | ||
817 | 802 | ||
818 | mtr = decode_mtr(pvt, slot, ch, branch, | 803 | mtr = decode_mtr(pvt, slot, ch, branch, |
819 | dinfo, p_csrow, &nr_pages); | 804 | dinfo, dimm); |
805 | |||
820 | /* if no DIMMS on this row, continue */ | 806 | /* if no DIMMS on this row, continue */ |
821 | if (!MTR_DIMMS_PRESENT(mtr)) | 807 | if (!MTR_DIMMS_PRESENT(mtr)) |
822 | continue; | 808 | continue; |
823 | 809 | ||
824 | /* Update per_csrow memory count */ | ||
825 | p_csrow->nr_pages += nr_pages; | ||
826 | p_csrow->first_page = last_page; | ||
827 | last_page += nr_pages; | ||
828 | p_csrow->last_page = last_page; | ||
829 | |||
830 | rc = 0; | 810 | rc = 0; |
811 | |||
831 | } | 812 | } |
832 | } | 813 | } |
833 | } | 814 | } |
@@ -1042,10 +1023,8 @@ static int __devinit i7300_init_one(struct pci_dev *pdev, | |||
1042 | const struct pci_device_id *id) | 1023 | const struct pci_device_id *id) |
1043 | { | 1024 | { |
1044 | struct mem_ctl_info *mci; | 1025 | struct mem_ctl_info *mci; |
1026 | struct edac_mc_layer layers[3]; | ||
1045 | struct i7300_pvt *pvt; | 1027 | struct i7300_pvt *pvt; |
1046 | int num_channels; | ||
1047 | int num_dimms_per_channel; | ||
1048 | int num_csrows; | ||
1049 | int rc; | 1028 | int rc; |
1050 | 1029 | ||
1051 | /* wake up device */ | 1030 | /* wake up device */ |
@@ -1062,23 +1041,17 @@ static int __devinit i7300_init_one(struct pci_dev *pdev, | |||
1062 | if (PCI_FUNC(pdev->devfn) != 0) | 1041 | if (PCI_FUNC(pdev->devfn) != 0) |
1063 | return -ENODEV; | 1042 | return -ENODEV; |
1064 | 1043 | ||
1065 | /* As we don't have a motherboard identification routine to determine | ||
1066 | * actual number of slots/dimms per channel, we thus utilize the | ||
1067 | * resource as specified by the chipset. Thus, we might have | ||
1068 | * have more DIMMs per channel than actually on the mobo, but this | ||
1069 | * allows the driver to support up to the chipset max, without | ||
1070 | * some fancy mobo determination. | ||
1071 | */ | ||
1072 | num_dimms_per_channel = MAX_SLOTS; | ||
1073 | num_channels = MAX_CHANNELS; | ||
1074 | num_csrows = MAX_SLOTS * MAX_CHANNELS; | ||
1075 | |||
1076 | debugf0("MC: %s(): Number of - Channels= %d DIMMS= %d CSROWS= %d\n", | ||
1077 | __func__, num_channels, num_dimms_per_channel, num_csrows); | ||
1078 | |||
1079 | /* allocate a new MC control structure */ | 1044 | /* allocate a new MC control structure */ |
1080 | mci = edac_mc_alloc(sizeof(*pvt), num_csrows, num_channels, 0); | 1045 | layers[0].type = EDAC_MC_LAYER_BRANCH; |
1081 | 1046 | layers[0].size = MAX_BRANCHES; | |
1047 | layers[0].is_virt_csrow = false; | ||
1048 | layers[1].type = EDAC_MC_LAYER_CHANNEL; | ||
1049 | layers[1].size = MAX_CH_PER_BRANCH; | ||
1050 | layers[1].is_virt_csrow = true; | ||
1051 | layers[2].type = EDAC_MC_LAYER_SLOT; | ||
1052 | layers[2].size = MAX_SLOTS; | ||
1053 | layers[2].is_virt_csrow = true; | ||
1054 | mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers, sizeof(*pvt)); | ||
1082 | if (mci == NULL) | 1055 | if (mci == NULL) |
1083 | return -ENOMEM; | 1056 | return -ENOMEM; |
1084 | 1057 | ||