aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac/edac_mc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/edac/edac_mc.c')
-rw-r--r--drivers/edac/edac_mc.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index 603de8b49f27..357c95f30fc6 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)
1632 return NULL; 1632 return NULL;
1633} 1633}
1634 1634
1635static int add_mc_to_global_list(struct mem_ctl_info *mci) 1635/* Return 0 on success, 1 on failure.
1636 * Before calling this function, caller must
1637 * assign a unique value to mci->mc_idx.
1638 */
1639static int add_mc_to_global_list (struct mem_ctl_info *mci)
1636{ 1640{
1637 struct list_head *item, *insert_before; 1641 struct list_head *item, *insert_before;
1638 struct mem_ctl_info *p; 1642 struct mem_ctl_info *p;
1639 int i;
1640 1643
1641 if (list_empty(&mc_devices)) { 1644 insert_before = &mc_devices;
1642 mci->mc_idx = 0;
1643 insert_before = &mc_devices;
1644 } else {
1645 if (find_mci_by_dev(mci->dev)) {
1646 edac_printk(KERN_WARNING, EDAC_MC,
1647 "%s (%s) %s %s already assigned %d\n",
1648 mci->dev->bus_id, dev_name(mci->dev),
1649 mci->mod_name, mci->ctl_name,
1650 mci->mc_idx);
1651 return 1;
1652 }
1653 1645
1654 insert_before = NULL; 1646 if (unlikely((p = find_mci_by_dev(mci->dev)) != NULL))
1655 i = 0; 1647 goto fail0;
1656 1648
1657 list_for_each(item, &mc_devices) { 1649 list_for_each(item, &mc_devices) {
1658 p = list_entry(item, struct mem_ctl_info, link); 1650 p = list_entry(item, struct mem_ctl_info, link);
1659 1651
1660 if (p->mc_idx != i) { 1652 if (p->mc_idx >= mci->mc_idx) {
1661 insert_before = item; 1653 if (unlikely(p->mc_idx == mci->mc_idx))
1662 break; 1654 goto fail1;
1663 }
1664 1655
1665 i++; 1656 insert_before = item;
1657 break;
1666 } 1658 }
1667
1668 mci->mc_idx = i;
1669
1670 if (insert_before == NULL)
1671 insert_before = &mc_devices;
1672 } 1659 }
1673 1660
1674 list_add_tail_rcu(&mci->link, insert_before); 1661 list_add_tail_rcu(&mci->link, insert_before);
1675 return 0; 1662 return 0;
1663
1664fail0:
1665 edac_printk(KERN_WARNING, EDAC_MC,
1666 "%s (%s) %s %s already assigned %d\n", p->dev->bus_id,
1667 dev_name(p->dev), p->mod_name, p->ctl_name, p->mc_idx);
1668 return 1;
1669
1670fail1:
1671 edac_printk(KERN_WARNING, EDAC_MC,
1672 "bug in low-level driver: attempt to assign\n"
1673 " duplicate mc_idx %d in %s()\n", p->mc_idx, __func__);
1674 return 1;
1676} 1675}
1677 1676
1678static void complete_mc_list_del(struct rcu_head *head) 1677static 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)
1696 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and 1695 * edac_mc_add_mc: Insert the 'mci' structure into the mci global list and
1697 * create sysfs entries associated with mci structure 1696 * create sysfs entries associated with mci structure
1698 * @mci: pointer to the mci structure to be added to the list 1697 * @mci: pointer to the mci structure to be added to the list
1698 * @mc_idx: A unique numeric identifier to be assigned to the 'mci' structure.
1699 * 1699 *
1700 * Return: 1700 * Return:
1701 * 0 Success 1701 * 0 Success
@@ -1703,9 +1703,10 @@ static void del_mc_from_global_list(struct mem_ctl_info *mci)
1703 */ 1703 */
1704 1704
1705/* FIXME - should a warning be printed if no error detection? correction? */ 1705/* FIXME - should a warning be printed if no error detection? correction? */
1706int edac_mc_add_mc(struct mem_ctl_info *mci) 1706int edac_mc_add_mc(struct mem_ctl_info *mci, int mc_idx)
1707{ 1707{
1708 debugf0("%s()\n", __func__); 1708 debugf0("%s()\n", __func__);
1709 mci->mc_idx = mc_idx;
1709#ifdef CONFIG_EDAC_DEBUG 1710#ifdef CONFIG_EDAC_DEBUG
1710 if (edac_debug_level >= 3) 1711 if (edac_debug_level >= 3)
1711 edac_mc_dump_mci(mci); 1712 edac_mc_dump_mci(mci);