i7core_edac: Be sure that the edac pci handler will be properly released
With multi-sockets, more than one edac pci handler is enabled. Be sure to un-register all instances. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
f6f94e2ab1
commit
939747bd68
|
@ -810,6 +810,7 @@ extern struct mem_ctl_info *edac_mc_alloc(unsigned sz_pvt, unsigned nr_csrows,
|
||||||
extern int edac_mc_add_mc(struct mem_ctl_info *mci);
|
extern int edac_mc_add_mc(struct mem_ctl_info *mci);
|
||||||
extern void edac_mc_free(struct mem_ctl_info *mci);
|
extern void edac_mc_free(struct mem_ctl_info *mci);
|
||||||
extern struct mem_ctl_info *edac_mc_find(int idx);
|
extern struct mem_ctl_info *edac_mc_find(int idx);
|
||||||
|
extern struct mem_ctl_info *find_mci_by_dev(struct device *dev);
|
||||||
extern struct mem_ctl_info *edac_mc_del_mc(struct device *dev);
|
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,
|
extern int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci,
|
||||||
unsigned long page);
|
unsigned long page);
|
||||||
|
|
|
@ -239,13 +239,14 @@ void edac_mc_free(struct mem_ctl_info *mci)
|
||||||
EXPORT_SYMBOL_GPL(edac_mc_free);
|
EXPORT_SYMBOL_GPL(edac_mc_free);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* find_mci_by_dev
|
* find_mci_by_dev
|
||||||
*
|
*
|
||||||
* scan list of controllers looking for the one that manages
|
* scan list of controllers looking for the one that manages
|
||||||
* the 'dev' device
|
* the 'dev' device
|
||||||
|
* @dev: pointer to a struct device related with the MCI
|
||||||
*/
|
*/
|
||||||
static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
||||||
{
|
{
|
||||||
struct mem_ctl_info *mci;
|
struct mem_ctl_info *mci;
|
||||||
struct list_head *item;
|
struct list_head *item;
|
||||||
|
@ -261,6 +262,7 @@ static struct mem_ctl_info *find_mci_by_dev(struct device *dev)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(find_mci_by_dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* handler for EDAC to check if NMI type handler has asserted interrupt
|
* handler for EDAC to check if NMI type handler has asserted interrupt
|
||||||
|
|
|
@ -261,6 +261,9 @@ struct i7core_pvt {
|
||||||
|
|
||||||
/* Count indicator to show errors not got */
|
/* Count indicator to show errors not got */
|
||||||
unsigned mce_overrun;
|
unsigned mce_overrun;
|
||||||
|
|
||||||
|
/* Struct to control EDAC polling */
|
||||||
|
struct edac_pci_ctl_info *i7core_pci;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Static vars */
|
/* Static vars */
|
||||||
|
@ -378,8 +381,6 @@ static const struct pci_device_id i7core_pci_tbl[] __devinitdata = {
|
||||||
{0,} /* 0 terminated list. */
|
{0,} /* 0 terminated list. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct edac_pci_ctl_info *i7core_pci;
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Anciliary status routines
|
Anciliary status routines
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1906,9 +1907,9 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocating generic PCI control info */
|
/* allocating generic PCI control info */
|
||||||
i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
|
pvt->i7core_pci = edac_pci_create_generic_ctl(&i7core_dev->pdev[0]->dev,
|
||||||
EDAC_MOD_STR);
|
EDAC_MOD_STR);
|
||||||
if (unlikely(!i7core_pci)) {
|
if (unlikely(!pvt->i7core_pci)) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"%s(): Unable to create PCI control\n",
|
"%s(): Unable to create PCI control\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -2008,12 +2009,10 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct mem_ctl_info *mci;
|
struct mem_ctl_info *mci;
|
||||||
struct i7core_dev *i7core_dev, *tmp;
|
struct i7core_dev *i7core_dev, *tmp;
|
||||||
|
struct i7core_pvt *pvt;
|
||||||
|
|
||||||
debugf0(__FILE__ ": %s()\n", __func__);
|
debugf0(__FILE__ ": %s()\n", __func__);
|
||||||
|
|
||||||
if (i7core_pci)
|
|
||||||
edac_pci_release_generic_ctl(i7core_pci);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we have a trouble here: pdev value for removal will be wrong, since
|
* we have a trouble here: pdev value for removal will be wrong, since
|
||||||
* it will point to the X58 register used to detect that the machine
|
* it will point to the X58 register used to detect that the machine
|
||||||
|
@ -2024,19 +2023,28 @@ static void __devexit i7core_remove(struct pci_dev *pdev)
|
||||||
|
|
||||||
mutex_lock(&i7core_edac_lock);
|
mutex_lock(&i7core_edac_lock);
|
||||||
list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
|
list_for_each_entry_safe(i7core_dev, tmp, &i7core_edac_list, list) {
|
||||||
mci = edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
|
mci = find_mci_by_dev(&i7core_dev->pdev[0]->dev);
|
||||||
if (mci) {
|
if (unlikely(!mci || !mci->pvt_info)) {
|
||||||
struct i7core_pvt *pvt = mci->pvt_info;
|
i7core_printk(KERN_ERR,
|
||||||
|
"Couldn't find mci hanler\n");
|
||||||
|
} else {
|
||||||
|
pvt = mci->pvt_info;
|
||||||
i7core_dev = pvt->i7core_dev;
|
i7core_dev = pvt->i7core_dev;
|
||||||
|
|
||||||
|
if (likely(pvt->i7core_pci))
|
||||||
|
edac_pci_release_generic_ctl(pvt->i7core_pci);
|
||||||
|
else
|
||||||
|
i7core_printk(KERN_ERR,
|
||||||
|
"Couldn't find mem_ctl_info for socket %d\n",
|
||||||
|
i7core_dev->socket);
|
||||||
|
pvt->i7core_pci = NULL;
|
||||||
|
|
||||||
|
edac_mc_del_mc(&i7core_dev->pdev[0]->dev);
|
||||||
|
|
||||||
edac_mce_unregister(&pvt->edac_mce);
|
edac_mce_unregister(&pvt->edac_mce);
|
||||||
kfree(mci->ctl_name);
|
kfree(mci->ctl_name);
|
||||||
edac_mc_free(mci);
|
edac_mc_free(mci);
|
||||||
i7core_put_devices(i7core_dev);
|
i7core_put_devices(i7core_dev);
|
||||||
} else {
|
|
||||||
i7core_printk(KERN_ERR,
|
|
||||||
"Couldn't find mci for socket %d\n",
|
|
||||||
i7core_dev->socket);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
probed--;
|
probed--;
|
||||||
|
|
Reference in New Issue