mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
i7300_edac: Fix device reference count
commit 75135da0d6
upstream.
pci_get_device() decrements the reference count of "from" (last
argument) so when we break off the loop successfully we have only one
device reference - and we don't know which device we have. If we want
a reference to each device, we must take them explicitly and let
the pci_get_device() walk complete to avoid duplicate references.
This is serious, as over-putting device references will cause
the device to eventually disappear. Without this fix, the kernel
crashes after a few insmod/rmmod cycles.
Tested on an Intel S7000FC4UR system with a 7300 chipset.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Link: http://lkml.kernel.org/r/20140224111656.09bbb7ed@endymion.delvare
Cc: Mauro Carvalho Chehab <m.chehab@samsung.com>
Cc: Doug Thompson <dougthompson@xmission.com>
Cc: stable@vger.kernel.org
Signed-off-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
e78970f0d7
commit
714c034f82
1 changed files with 20 additions and 18 deletions
|
@ -962,33 +962,35 @@ static int __devinit i7300_get_devices(struct mem_ctl_info *mci)
|
|||
|
||||
/* Attempt to 'get' the MCH register we want */
|
||||
pdev = NULL;
|
||||
while (!pvt->pci_dev_16_1_fsb_addr_map ||
|
||||
!pvt->pci_dev_16_2_fsb_err_regs) {
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_I7300_MCH_ERR, pdev);
|
||||
if (!pdev) {
|
||||
/* End of list, leave */
|
||||
i7300_printk(KERN_ERR,
|
||||
"'system address,Process Bus' "
|
||||
"device not found:"
|
||||
"vendor 0x%x device 0x%x ERR funcs "
|
||||
"(broken BIOS?)\n",
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_I7300_MCH_ERR);
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_I7300_MCH_ERR,
|
||||
pdev))) {
|
||||
/* Store device 16 funcs 1 and 2 */
|
||||
switch (PCI_FUNC(pdev->devfn)) {
|
||||
case 1:
|
||||
pvt->pci_dev_16_1_fsb_addr_map = pdev;
|
||||
if (!pvt->pci_dev_16_1_fsb_addr_map)
|
||||
pvt->pci_dev_16_1_fsb_addr_map =
|
||||
pci_dev_get(pdev);
|
||||
break;
|
||||
case 2:
|
||||
pvt->pci_dev_16_2_fsb_err_regs = pdev;
|
||||
if (!pvt->pci_dev_16_2_fsb_err_regs)
|
||||
pvt->pci_dev_16_2_fsb_err_regs =
|
||||
pci_dev_get(pdev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pvt->pci_dev_16_1_fsb_addr_map ||
|
||||
!pvt->pci_dev_16_2_fsb_err_regs) {
|
||||
/* At least one device was not found */
|
||||
i7300_printk(KERN_ERR,
|
||||
"'system address,Process Bus' device not found:"
|
||||
"vendor 0x%x device 0x%x ERR funcs (broken BIOS?)\n",
|
||||
PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_I7300_MCH_ERR);
|
||||
goto error;
|
||||
}
|
||||
|
||||
debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n",
|
||||
pci_name(pvt->pci_dev_16_0_fsb_ctlr),
|
||||
pvt->pci_dev_16_0_fsb_ctlr->vendor,
|
||||
|
|
Loading…
Reference in a new issue