i7core_edac: Add support for sysfs addrmatch group
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
9fa2fc2e2d
commit
a5538e531f
|
@ -778,105 +778,59 @@ static ssize_t i7core_inject_eccmask_show(struct mem_ctl_info *mci,
|
||||||
* 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
|
* 23:16 and 31:24). Flipping bits in two symbol pairs will cause an
|
||||||
* uncorrectable error to be injected.
|
* uncorrectable error to be injected.
|
||||||
*/
|
*/
|
||||||
static ssize_t i7core_inject_addrmatch_store(struct mem_ctl_info *mci,
|
|
||||||
const char *data, size_t count)
|
|
||||||
{
|
|
||||||
struct i7core_pvt *pvt = mci->pvt_info;
|
|
||||||
char *cmd, *val;
|
|
||||||
long value;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (pvt->inject.enable)
|
#define DECLARE_ADDR_MATCH(param, limit) \
|
||||||
disable_inject(mci);
|
static ssize_t i7core_inject_store_##param( \
|
||||||
|
struct mem_ctl_info *mci, \
|
||||||
do {
|
const char *data, size_t count) \
|
||||||
cmd = strsep((char **) &data, ":");
|
{ \
|
||||||
if (!cmd)
|
struct i7core_pvt *pvt = mci->pvt_info; \
|
||||||
break;
|
long value; \
|
||||||
val = strsep((char **) &data, " \n\t");
|
int rc; \
|
||||||
if (!val)
|
\
|
||||||
return cmd - data;
|
if (pvt->inject.enable) \
|
||||||
|
disable_inject(mci); \
|
||||||
if (!strcasecmp(val, "any"))
|
\
|
||||||
value = -1;
|
if (!strcasecmp(data, "any")) \
|
||||||
else {
|
value = -1; \
|
||||||
rc = strict_strtol(val, 10, &value);
|
else { \
|
||||||
if ((rc < 0) || (value < 0))
|
rc = strict_strtoul(data, 10, &value); \
|
||||||
return cmd - data;
|
if ((rc < 0) || (value >= limit)) \
|
||||||
}
|
return -EIO; \
|
||||||
|
} \
|
||||||
if (!strcasecmp(cmd, "channel")) {
|
\
|
||||||
if (value < 3)
|
pvt->inject.param = value; \
|
||||||
pvt->inject.channel = value;
|
\
|
||||||
else
|
return count; \
|
||||||
return cmd - data;
|
} \
|
||||||
} else if (!strcasecmp(cmd, "dimm")) {
|
\
|
||||||
if (value < 3)
|
static ssize_t i7core_inject_show_##param( \
|
||||||
pvt->inject.dimm = value;
|
struct mem_ctl_info *mci, \
|
||||||
else
|
char *data) \
|
||||||
return cmd - data;
|
{ \
|
||||||
} else if (!strcasecmp(cmd, "rank")) {
|
struct i7core_pvt *pvt = mci->pvt_info; \
|
||||||
if (value < 4)
|
if (pvt->inject.param < 0) \
|
||||||
pvt->inject.rank = value;
|
return sprintf(data, "any\n"); \
|
||||||
else
|
else \
|
||||||
return cmd - data;
|
return sprintf(data, "%d\n", pvt->inject.param);\
|
||||||
} else if (!strcasecmp(cmd, "bank")) {
|
|
||||||
if (value < 32)
|
|
||||||
pvt->inject.bank = value;
|
|
||||||
else
|
|
||||||
return cmd - data;
|
|
||||||
} else if (!strcasecmp(cmd, "page")) {
|
|
||||||
if (value <= 0xffff)
|
|
||||||
pvt->inject.page = value;
|
|
||||||
else
|
|
||||||
return cmd - data;
|
|
||||||
} else if (!strcasecmp(cmd, "col") ||
|
|
||||||
!strcasecmp(cmd, "column")) {
|
|
||||||
if (value <= 0x3fff)
|
|
||||||
pvt->inject.col = value;
|
|
||||||
else
|
|
||||||
return cmd - data;
|
|
||||||
}
|
|
||||||
} while (1);
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t i7core_inject_addrmatch_show(struct mem_ctl_info *mci,
|
#define ATTR_ADDR_MATCH(param) \
|
||||||
char *data)
|
{ \
|
||||||
{
|
.attr = { \
|
||||||
struct i7core_pvt *pvt = mci->pvt_info;
|
.name = #param, \
|
||||||
char channel[4], dimm[4], bank[4], rank[4], page[7], col[7];
|
.mode = (S_IRUGO | S_IWUSR) \
|
||||||
|
}, \
|
||||||
|
.show = i7core_inject_show_##param, \
|
||||||
|
.store = i7core_inject_store_##param, \
|
||||||
|
}
|
||||||
|
|
||||||
if (pvt->inject.channel < 0)
|
DECLARE_ADDR_MATCH(channel, 3);
|
||||||
sprintf(channel, "any");
|
DECLARE_ADDR_MATCH(dimm, 3);
|
||||||
else
|
DECLARE_ADDR_MATCH(rank, 4);
|
||||||
sprintf(channel, "%d", pvt->inject.channel);
|
DECLARE_ADDR_MATCH(bank, 32);
|
||||||
if (pvt->inject.dimm < 0)
|
DECLARE_ADDR_MATCH(page, 0x10000);
|
||||||
sprintf(dimm, "any");
|
DECLARE_ADDR_MATCH(col, 0x4000);
|
||||||
else
|
|
||||||
sprintf(dimm, "%d", pvt->inject.dimm);
|
|
||||||
if (pvt->inject.bank < 0)
|
|
||||||
sprintf(bank, "any");
|
|
||||||
else
|
|
||||||
sprintf(bank, "%d", pvt->inject.bank);
|
|
||||||
if (pvt->inject.rank < 0)
|
|
||||||
sprintf(rank, "any");
|
|
||||||
else
|
|
||||||
sprintf(rank, "%d", pvt->inject.rank);
|
|
||||||
if (pvt->inject.page < 0)
|
|
||||||
sprintf(page, "any");
|
|
||||||
else
|
|
||||||
sprintf(page, "0x%04x", pvt->inject.page);
|
|
||||||
if (pvt->inject.col < 0)
|
|
||||||
sprintf(col, "any");
|
|
||||||
else
|
|
||||||
sprintf(col, "0x%04x", pvt->inject.col);
|
|
||||||
|
|
||||||
return sprintf(data, "channel: %s\ndimm: %s\nbank: %s\n"
|
|
||||||
"rank: %s\npage: %s\ncolumn: %s\n",
|
|
||||||
channel, dimm, bank, rank, page, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_and_test(struct pci_dev *dev, int where, u32 val)
|
static int write_and_test(struct pci_dev *dev, int where, u32 val)
|
||||||
{
|
{
|
||||||
|
@ -1079,7 +1033,25 @@ static ssize_t i7core_ce_regs_show(struct mem_ctl_info *mci, char *data)
|
||||||
/*
|
/*
|
||||||
* Sysfs struct
|
* Sysfs struct
|
||||||
*/
|
*/
|
||||||
static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
|
|
||||||
|
|
||||||
|
static struct mcidev_sysfs_attribute i7core_addrmatch_attrs[] = {
|
||||||
|
ATTR_ADDR_MATCH(channel),
|
||||||
|
ATTR_ADDR_MATCH(dimm),
|
||||||
|
ATTR_ADDR_MATCH(rank),
|
||||||
|
ATTR_ADDR_MATCH(bank),
|
||||||
|
ATTR_ADDR_MATCH(page),
|
||||||
|
ATTR_ADDR_MATCH(col),
|
||||||
|
{ .attr = { .name = NULL } }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct mcidev_sysfs_group i7core_inject_addrmatch = {
|
||||||
|
.name = "inject_addrmatch",
|
||||||
|
.mcidev_attr = i7core_addrmatch_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mcidev_sysfs_attribute i7core_sysfs_attrs[] = {
|
||||||
{
|
{
|
||||||
.attr = {
|
.attr = {
|
||||||
.name = "inject_section",
|
.name = "inject_section",
|
||||||
|
@ -1102,12 +1074,7 @@ static struct mcidev_sysfs_attribute i7core_inj_attrs[] = {
|
||||||
.show = i7core_inject_eccmask_show,
|
.show = i7core_inject_eccmask_show,
|
||||||
.store = i7core_inject_eccmask_store,
|
.store = i7core_inject_eccmask_store,
|
||||||
}, {
|
}, {
|
||||||
.attr = {
|
.grp = &i7core_inject_addrmatch,
|
||||||
.name = "inject_addrmatch",
|
|
||||||
.mode = (S_IRUGO | S_IWUSR)
|
|
||||||
},
|
|
||||||
.show = i7core_inject_addrmatch_show,
|
|
||||||
.store = i7core_inject_addrmatch_store,
|
|
||||||
}, {
|
}, {
|
||||||
.attr = {
|
.attr = {
|
||||||
.name = "inject_enable",
|
.name = "inject_enable",
|
||||||
|
@ -1750,7 +1717,7 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
|
||||||
i7core_dev->socket);
|
i7core_dev->socket);
|
||||||
mci->dev_name = pci_name(i7core_dev->pdev[0]);
|
mci->dev_name = pci_name(i7core_dev->pdev[0]);
|
||||||
mci->ctl_page_to_phys = NULL;
|
mci->ctl_page_to_phys = NULL;
|
||||||
mci->mc_driver_sysfs_attributes = i7core_inj_attrs;
|
mci->mc_driver_sysfs_attributes = i7core_sysfs_attrs;
|
||||||
/* Set the function pointer to an actual operation function */
|
/* Set the function pointer to an actual operation function */
|
||||||
mci->edac_check = i7core_check_error;
|
mci->edac_check = i7core_check_error;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue