diff --git a/drivers/edac/amd76x_edac.c b/drivers/edac/amd76x_edac.c index 7fd6283fe00809c93445d3e5e3fa383271320475..303cb500b377707ee95200a7023d31b7a03c60d6 100644 --- a/drivers/edac/amd76x_edac.c +++ b/drivers/edac/amd76x_edac.c @@ -257,7 +257,10 @@ static int amd76x_probe1(struct pci_dev *pdev, int dev_idx) amd76x_get_error_info(mci, &discard); /* clear counters */ - if (edac_mc_add_mc(mci)) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index de9f332eabf0e64b78ff2c1e16a5a7577ea05f08..5e773e382e8a92ab39c9eb634c6b46b3304a314f 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c @@ -953,7 +953,10 @@ static int e752x_probe1(struct pci_dev *pdev, int dev_idx) "tolm = %x, remapbase = %x, remaplimit = %x\n", pvt->tolm, pvt->remapbase, pvt->remaplimit); - if (edac_mc_add_mc(mci)) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } diff --git a/drivers/edac/e7xxx_edac.c b/drivers/edac/e7xxx_edac.c index d601d53b99203bbfa2367b2871ab5fa9f1eab622..1e282c843e777e5d2fdf92ffc1167d4667ed99b9 100644 --- a/drivers/edac/e7xxx_edac.c +++ b/drivers/edac/e7xxx_edac.c @@ -463,7 +463,10 @@ static int e7xxx_probe1(struct pci_dev *pdev, int dev_idx) /* clear any pending errors, or initial state bits */ e7xxx_get_error_info(mci, &discard); - if (edac_mc_add_mc(mci) != 0) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 603de8b49f2740614522cc7bb66d17e15c70a214..357c95f30fc690dba7a2c02bc6635dc358c22764 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -1632,47 +1632,46 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev) return NULL; } -static int add_mc_to_global_list(struct mem_ctl_info *mci) +/* Return 0 on success, 1 on failure. + * Before calling this function, caller must + * assign a unique value to mci->mc_idx. + */ +static int add_mc_to_global_list (struct mem_ctl_info *mci) { struct list_head *item, *insert_before; struct mem_ctl_info *p; - int i; - if (list_empty(&mc_devices)) { - mci->mc_idx = 0; - insert_before = &mc_devices; - } else { - if (find_mci_by_dev(mci->dev)) { - edac_printk(KERN_WARNING, EDAC_MC, - "%s (%s) %s %s already assigned %d\n", - mci->dev->bus_id, dev_name(mci->dev), - mci->mod_name, mci->ctl_name, - mci->mc_idx); - return 1; - } + insert_before = &mc_devices; - insert_before = NULL; - i = 0; + if (unlikely((p = find_mci_by_dev(mci->dev)) != NULL)) + goto fail0; - list_for_each(item, &mc_devices) { - p = list_entry(item, struct mem_ctl_info, link); + list_for_each(item, &mc_devices) { + p = list_entry(item, struct mem_ctl_info, link); - if (p->mc_idx != i) { - insert_before = item; - break; - } + if (p->mc_idx >= mci->mc_idx) { + if (unlikely(p->mc_idx == mci->mc_idx)) + goto fail1; - i++; + insert_before = item; + break; } - - mci->mc_idx = i; - - if (insert_before == NULL) - insert_before = &mc_devices; } list_add_tail_rcu(&mci->link, insert_before); return 0; + +fail0: + edac_printk(KERN_WARNING, EDAC_MC, + "%s (%s) %s %s already assigned %d\n", p->dev->bus_id, + dev_name(p->dev), p->mod_name, p->ctl_name, p->mc_idx); + return 1; + +fail1: + edac_printk(KERN_WARNING, EDAC_MC, + "bug in low-level driver: attempt to assign\n" + " duplicate mc_idx %d in %s()\n", p->mc_idx, __func__); + return 1; } static void complete_mc_list_del(struct rcu_head *head) @@ -1696,6 +1695,7 @@ static void del_mc_from_global_list(struct mem_ctl_info *mci) * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and * create sysfs entries associated with mci structure * @mci: pointer to the mci structure to be added to the list + * @mc_idx: A unique numeric identifier to be assigned to the 'mci' structure. * * Return: * 0 Success @@ -1703,9 +1703,10 @@ static void del_mc_from_global_list(struct mem_ctl_info *mci) */ /* FIXME - should a warning be printed if no error detection? correction? */ -int edac_mc_add_mc(struct mem_ctl_info *mci) +int edac_mc_add_mc(struct mem_ctl_info *mci, int mc_idx) { debugf0("%s()\n", __func__); + mci->mc_idx = mc_idx; #ifdef CONFIG_EDAC_DEBUG if (edac_debug_level >= 3) edac_mc_dump_mci(mci); diff --git a/drivers/edac/edac_mc.h b/drivers/edac/edac_mc.h index a2c3a4607a89cbe242962f492331e7a4cfa3bb4d..342979677d2fd5e8727f5a97d18e332350b59356 100644 --- a/drivers/edac/edac_mc.h +++ b/drivers/edac/edac_mc.h @@ -417,7 +417,7 @@ void edac_mc_dump_mci(struct mem_ctl_info *mci); void edac_mc_dump_csrow(struct csrow_info *csrow); #endif /* CONFIG_EDAC_DEBUG */ -extern int edac_mc_add_mc(struct mem_ctl_info *mci); +extern int edac_mc_add_mc(struct mem_ctl_info *mci,int mc_idx); extern struct mem_ctl_info * edac_mc_del_mc(struct device *dev); extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page); diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index baa021b96d18e93f28dcbb0ed08c2e40406b786a..e2c3b8bc097b2cdb9a944bc98b0c359cd5a14b41 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c @@ -208,7 +208,10 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) i82860_get_error_info(mci, &discard); /* clear counters */ - if (edac_mc_add_mc(mci)) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); edac_mc_free(mci); } else { diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 3f509a7ea02a11819aec1ce5f313a8caadd30dd6..2be18ca96408752d3adaed932a0d6054c5bbcd85 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c @@ -390,7 +390,10 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx) i82875p_get_error_info(mci, &discard); /* clear counters */ - if (edac_mc_add_mc(mci)) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail3; } diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c index d04769aade5d5ef727da767e1788298c45e35987..eb3aa615dc57ce6b526a39b408e347770b6709c4 100644 --- a/drivers/edac/r82600_edac.c +++ b/drivers/edac/r82600_edac.c @@ -304,7 +304,10 @@ static int r82600_probe1(struct pci_dev *pdev, int dev_idx) r82600_get_error_info(mci, &discard); /* clear counters */ - if (edac_mc_add_mc(mci)) { + /* Here we assume that we will never see multiple instances of this + * type of memory controller. The ID is therefore hardcoded to 0. + */ + if (edac_mc_add_mc(mci,0)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; }