aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-23 17:56:47 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-10 10:45:01 -0400
commita5538e531fc1e00ac7185dcfcebf33c37b5d742e (patch)
tree5fbc7a51f9282c401dd6c98ad755dab51c9113e3 /drivers/edac
parent9fa2fc2e2d641df7d69dc4e06cf2552c44b58e95 (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.c173
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 */
781static 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) \
783static 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 \
807static 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
845static 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" 828DECLARE_ADDR_MATCH(channel, 3);
877 "rank: %s\npage: %s\ncolumn: %s\n", 829DECLARE_ADDR_MATCH(dimm, 3);
878 channel, dimm, bank, rank, page, col); 830DECLARE_ADDR_MATCH(rank, 4);
879} 831DECLARE_ADDR_MATCH(bank, 32);
832DECLARE_ADDR_MATCH(page, 0x10000);
833DECLARE_ADDR_MATCH(col, 0x4000);
880 834
881static int write_and_test(struct pci_dev *dev, int where, u32 val) 835static 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 */
1082static struct mcidev_sysfs_attribute i7core_inj_attrs[] = { 1036
1037
1038static 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
1049static struct mcidev_sysfs_group i7core_inject_addrmatch = {
1050 .name = "inject_addrmatch",
1051 .mcidev_attr = i7core_addrmatch_attrs,
1052};
1053
1054static 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