i5400_edac: Avoid calling pci_put_device() twice
When i5400_edac driver is removed and re-loaded a few times, it causes an OOPS, as it is currently decrementing some PCI device usage two times. When called inside a loop, pci_get_device() will call pci_put_device(). That mangles the error count. In this specific case, it seems easier to just duplicate the call. Also fixes the error logic when pci_get_device fails. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
df95e42e1f
commit
0142877aa4
1 changed files with 39 additions and 17 deletions
|
@ -735,7 +735,7 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
|
||||||
|
|
||||||
/* Attempt to 'get' the MCH register we want */
|
/* Attempt to 'get' the MCH register we want */
|
||||||
pdev = NULL;
|
pdev = NULL;
|
||||||
while (!pvt->branchmap_werrors || !pvt->fsb_error_regs) {
|
while (1) {
|
||||||
pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||||
PCI_DEVICE_ID_INTEL_5400_ERR, pdev);
|
PCI_DEVICE_ID_INTEL_5400_ERR, pdev);
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
|
@ -743,23 +743,42 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
|
||||||
i5400_printk(KERN_ERR,
|
i5400_printk(KERN_ERR,
|
||||||
"'system address,Process Bus' "
|
"'system address,Process Bus' "
|
||||||
"device not found:"
|
"device not found:"
|
||||||
"vendor 0x%x device 0x%x ERR funcs "
|
"vendor 0x%x device 0x%x ERR func 1 "
|
||||||
"(broken BIOS?)\n",
|
"(broken BIOS?)\n",
|
||||||
PCI_VENDOR_ID_INTEL,
|
PCI_VENDOR_ID_INTEL,
|
||||||
PCI_DEVICE_ID_INTEL_5400_ERR);
|
PCI_DEVICE_ID_INTEL_5400_ERR);
|
||||||
goto error;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store device 16 funcs 1 and 2 */
|
/* Store device 16 func 1 */
|
||||||
switch (PCI_FUNC(pdev->devfn)) {
|
if (PCI_FUNC(pdev->devfn) == 1)
|
||||||
case 1:
|
|
||||||
pvt->branchmap_werrors = pdev;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
|
||||||
pvt->fsb_error_regs = pdev;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pvt->branchmap_werrors = pdev;
|
||||||
|
|
||||||
|
pdev = NULL;
|
||||||
|
while (1) {
|
||||||
|
pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||||
|
PCI_DEVICE_ID_INTEL_5400_ERR, pdev);
|
||||||
|
if (!pdev) {
|
||||||
|
/* End of list, leave */
|
||||||
|
i5400_printk(KERN_ERR,
|
||||||
|
"'system address,Process Bus' "
|
||||||
|
"device not found:"
|
||||||
|
"vendor 0x%x device 0x%x ERR func 2 "
|
||||||
|
"(broken BIOS?)\n",
|
||||||
|
PCI_VENDOR_ID_INTEL,
|
||||||
|
PCI_DEVICE_ID_INTEL_5400_ERR);
|
||||||
|
|
||||||
|
pci_dev_put(pvt->branchmap_werrors);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store device 16 func 2 */
|
||||||
|
if (PCI_FUNC(pdev->devfn) == 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pvt->fsb_error_regs = pdev;
|
||||||
|
|
||||||
debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n",
|
debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n",
|
||||||
pci_name(pvt->system_address),
|
pci_name(pvt->system_address),
|
||||||
|
@ -778,7 +797,10 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
|
||||||
"MC: 'BRANCH 0' device not found:"
|
"MC: 'BRANCH 0' device not found:"
|
||||||
"vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n",
|
"vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n",
|
||||||
PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_FBD0);
|
PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_FBD0);
|
||||||
goto error;
|
|
||||||
|
pci_dev_put(pvt->fsb_error_regs);
|
||||||
|
pci_dev_put(pvt->branchmap_werrors);
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this device claims to have more than 2 channels then
|
/* If this device claims to have more than 2 channels then
|
||||||
|
@ -796,14 +818,14 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
|
||||||
"(broken BIOS?)\n",
|
"(broken BIOS?)\n",
|
||||||
PCI_VENDOR_ID_INTEL,
|
PCI_VENDOR_ID_INTEL,
|
||||||
PCI_DEVICE_ID_INTEL_5400_FBD1);
|
PCI_DEVICE_ID_INTEL_5400_FBD1);
|
||||||
goto error;
|
|
||||||
|
pci_dev_put(pvt->branch_0);
|
||||||
|
pci_dev_put(pvt->fsb_error_regs);
|
||||||
|
pci_dev_put(pvt->branchmap_werrors);
|
||||||
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
|
||||||
i5400_put_devices(mci);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Reference in a new issue