diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-23 17:56:47 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-10 10:45:01 -0400 |
commit | a5538e531fc1e00ac7185dcfcebf33c37b5d742e (patch) | |
tree | 5fbc7a51f9282c401dd6c98ad755dab51c9113e3 /drivers/edac | |
parent | 9fa2fc2e2d641df7d69dc4e06cf2552c44b58e95 (diff) |
i7core_edac: Add support for sysfs addrmatch group
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 173 |
1 files changed, 70 insertions, 103 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 0478cc85e920..afa5281e8df9 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -778,105 +778,59 @@ static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci, | |||
778 | * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an | 778 | * 23:16 and 31:24). Flipping bits in two symbol pairs will cause an |
779 | * uncorrectable error to be injected. | 779 | * uncorrectable error to be injected. |
780 | */ | 780 | */ |
781 | static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci, | ||
782 | const char *data, size_t count) | ||
783 | { | ||
784 | struct i7core_pvt *pvt = mci->pvt_info; | ||
785 | char *cmd, *val; | ||
786 | long value; | ||
787 | int rc; | ||
788 | |||
789 | if (pvt->inject.enable) | ||
790 | disable_inject(mci); | ||
791 | |||
792 | do { | ||
793 | cmd = strsep((char **) &data, ":"); | ||
794 | if (!cmd) | ||
795 | break; | ||
796 | val = strsep((char **) &data, " \n\t"); | ||
797 | if (!val) | ||
798 | return cmd - data; | ||
799 | |||
800 | if (!strcasecmp(val, "any")) | ||
801 | value = -1; | ||
802 | else { | ||
803 | rc = strict_strtol(val, 10, &value); | ||
804 | if ((rc < 0) || (value < 0)) | ||
805 | return cmd - data; | ||
806 | } | ||
807 | |||
808 | if (!strcasecmp(cmd, "channel")) { | ||
809 | if (value < 3) | ||
810 | pvt->inject.channel = value; | ||
811 | else | ||
812 | return cmd - data; | ||
813 | } else if (!strcasecmp(cmd, "dimm")) { | ||
814 | if (value < 3) | ||
815 | pvt->inject.dimm = value; | ||
816 | else | ||
817 | return cmd - data; | ||
818 | } else if (!strcasecmp(cmd, "rank")) { | ||
819 | if (value < 4) | ||
820 | pvt->inject.rank = value; | ||
821 | else | ||
822 | return cmd - data; | ||
823 | } else if (!strcasecmp(cmd, "bank")) { | ||
824 | if (value < 32) | ||
825 | pvt->inject.bank = value; | ||
826 | else | ||
827 | return cmd - data; | ||
828 | } else if (!strcasecmp(cmd, "page")) { | ||
829 | if (value <= 0xffff) | ||
830 | pvt->inject.page = value; | ||
831 | else | ||
832 | return cmd - data; | ||
833 | } else if (!strcasecmp(cmd, "col") || | ||
834 | !strcasecmp(cmd, "column")) { | ||
835 | if (value <= 0x3fff) | ||
836 | pvt->inject.col = value; | ||
837 | else | ||
838 | return cmd - data; | ||
839 | } | ||
840 | } while (1); | ||
841 | 781 | ||
842 | return count; | 782 | #define DECLARE_ADDR_MATCH(param, limit) \ |
783 | static ssize_t i7core_inject_store_##param( \ | ||
784 | struct mem_ctl_info *mci, \ | ||
785 | const char *data, size_t count) \ | ||
786 | { \ | ||
787 | struct i7core_pvt *pvt = mci->pvt_info; \ | ||
788 | long value; \ | ||
789 | int rc; \ | ||
790 | \ | ||
791 | if (pvt->inject.enable) \ | ||
792 | disable_inject(mci); \ | ||
793 | \ | ||
794 | if (!strcasecmp(data, "any")) \ | ||
795 | value = -1; \ | ||
796 | else { \ | ||
797 | rc = strict_strtoul(data, 10, &value); \ | ||
798 | if ((rc < 0) || (value >= limit)) \ | ||
799 | return -EIO; \ | ||
800 | } \ | ||
801 | \ | ||
802 | pvt->inject.param = value; \ | ||
803 | \ | ||
804 | return count; \ | ||
805 | } \ | ||
806 | \ | ||
807 | static ssize_t i7core_inject_show_##param( \ | ||
808 | struct mem_ctl_info *mci, \ | ||
809 | char *data) \ | ||
810 | { \ | ||
811 | struct i7core_pvt *pvt = mci->pvt_info; \ | ||
812 | if (pvt->inject.param < 0) \ | ||
813 | return sprintf(data, "any\n"); \ | ||
814 | else \ | ||
815 | return sprintf(data, "%d\n", pvt->inject.param);\ | ||
843 | } | 816 | } |
844 | 817 | ||
845 | static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci, | 818 | #define ATTR_ADDR_MATCH(param) \ |
846 | char *data) | 819 | { \ |
847 | { | 820 | .attr = { \ |
848 | struct i7core_pvt *pvt = mci->pvt_info; | 821 | .name = #param, \ |
849 | char channel[4], dimm[4], bank[4], rank[4], page[7], col[7]; | 822 | .mode = (S_IRUGO | S_IWUSR) \ |
850 | 823 | }, \ | |
851 | if (pvt->inject.channel < 0) | 824 | .show = i7core_inject_show_##param, \ |
852 | sprintf(channel, "any"); | 825 | .store = i7core_inject_store_##param, \ |
853 | else | 826 | } |
854 | sprintf(channel, "%d", pvt->inject.channel); | ||
855 | if (pvt->inject.dimm < 0) | ||
856 | sprintf(dimm, "any"); | ||
857 | else | ||
858 | sprintf(dimm, "%d", pvt->inject.dimm); | ||
859 | if (pvt->inject.bank < 0) | ||
860 | sprintf(bank, "any"); | ||
861 | else | ||
862 | sprintf(bank, "%d", pvt->inject.bank); | ||
863 | if (pvt->inject.rank < 0) | ||
864 | sprintf(rank, "any"); | ||
865 | else | ||
866 | sprintf(rank, "%d", pvt->inject.rank); | ||
867 | if (pvt->inject.page < 0) | ||
868 | sprintf(page, "any"); | ||
869 | else | ||
870 | sprintf(page, "0x%04x", pvt->inject.page); | ||
871 | if (pvt->inject.col < 0) | ||
872 | sprintf(col, "any"); | ||
873 | else | ||
874 | sprintf(col, "0x%04x", pvt->inject.col); | ||
875 | 827 | ||
876 | return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n" | 828 | DECLARE_ADDR_MATCH(channel, 3); |
877 | "rank: %s\npage: %s\ncolumn: %s\n", | 829 | DECLARE_ADDR_MATCH(dimm, 3); |
878 | channel, dimm, bank, rank, page, col); | 830 | DECLARE_ADDR_MATCH(rank, 4); |
879 | } | 831 | DECLARE_ADDR_MATCH(bank, 32); |
832 | DECLARE_ADDR_MATCH(page, 0x10000); | ||
833 | DECLARE_ADDR_MATCH(col, 0x4000); | ||
880 | 834 | ||
881 | static int write_and_test(struct pci_dev *dev, int where, u32 val) | 835 | static int write_and_test(struct pci_dev *dev, int where, u32 val) |
882 | { | 836 | { |
@@ -1079,7 +1033,25 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data) | |||
1079 | /* | 1033 | /* |
1080 | * Sysfs struct | 1034 | * Sysfs struct |
1081 | */ | 1035 | */ |
1082 | static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { | 1036 | |
1037 | |||
1038 | static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = { | ||
1039 | ATTR_ADDR_MATCH(channel), | ||
1040 | ATTR_ADDR_MATCH(dimm), | ||
1041 | ATTR_ADDR_MATCH(rank), | ||
1042 | ATTR_ADDR_MATCH(bank), | ||
1043 | ATTR_ADDR_MATCH(page), | ||
1044 | ATTR_ADDR_MATCH(col), | ||
1045 | { .attr = { .name = NULL } } | ||
1046 | }; | ||
1047 | |||
1048 | |||
1049 | static struct mcidev_sysfs_group i7core_inject_addrmatch = { | ||
1050 | .name = "inject_addrmatch", | ||
1051 | .mcidev_attr = i7core_addrmatch_attrs, | ||
1052 | }; | ||
1053 | |||
1054 | static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = { | ||
1083 | { | 1055 | { |
1084 | .attr = { | 1056 | .attr = { |
1085 | .name = "inject_section", | 1057 | .name = "inject_section", |
@@ -1102,12 +1074,7 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { | |||
1102 | .show = i7core_inject_eccmask_show, | 1074 | .show = i7core_inject_eccmask_show, |
1103 | .store = i7core_inject_eccmask_store, | 1075 | .store = i7core_inject_eccmask_store, |
1104 | }, { | 1076 | }, { |
1105 | .attr = { | 1077 | .grp = &i7core_inject_addrmatch, |
1106 | .name = "inject_addrmatch", | ||
1107 | .mode = (S_IRUGO | S_IWUSR) | ||
1108 | }, | ||
1109 | .show = i7core_inject_addrmatch_show, | ||
1110 | .store = i7core_inject_addrmatch_store, | ||
1111 | }, { | 1078 | }, { |
1112 | .attr = { | 1079 | .attr = { |
1113 | .name = "inject_enable", | 1080 | .name = "inject_enable", |
@@ -1750,7 +1717,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev, | |||
1750 | i7core_dev->socket); | 1717 | i7core_dev->socket); |
1751 | mci->dev_name = pci_name(i7core_dev->pdev[0]); | 1718 | mci->dev_name = pci_name(i7core_dev->pdev[0]); |
1752 | mci->ctl_page_to_phys = NULL; | 1719 | mci->ctl_page_to_phys = NULL; |
1753 | mci->mc_driver_sysfs_attributes = i7core_inj_attrs; | 1720 | mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs; |
1754 | /* Set the function pointer to an actual operation function */ | 1721 | /* Set the function pointer to an actual operation function */ |
1755 | mci->edac_check = i7core_check_error; | 1722 | mci->edac_check = i7core_check_error; |
1756 | 1723 | ||