aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-02-12 06:21:34 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-21 14:22:49 -0400
commit0142877aa4e54dd9943fb727e9b386c36c8e3ab7 (patch)
treea417008857f8bb421052bf22b2ce03be49053f5e /drivers/edac
parentdf95e42e1f20a561f2fe0a632d5b8fd6c26f1bb9 (diff)
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>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i5400_edac.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/edac/i5400_edac.c b/drivers/edac/i5400_edac.c
index 74d6ec342afb..b44a5de1c22c 100644
--- a/drivers/edac/i5400_edac.c
+++ b/drivers/edac/i5400_edac.c
@@ -735,7 +735,7 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
735 735
736 /* Attempt to 'get' the MCH register we want */ 736 /* Attempt to 'get' the MCH register we want */
737 pdev = NULL; 737 pdev = NULL;
738 while (!pvt->branchmap_werrors || !pvt->fsb_error_regs) { 738 while (1) {
739 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 739 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
740 PCI_DEVICE_ID_INTEL_5400_ERR, pdev); 740 PCI_DEVICE_ID_INTEL_5400_ERR, pdev);
741 if (!pdev) { 741 if (!pdev) {
@@ -743,23 +743,42 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
743 i5400_printk(KERN_ERR, 743 i5400_printk(KERN_ERR,
744 "'system address,Process Bus' " 744 "'system address,Process Bus' "
745 "device not found:" 745 "device not found:"
746 "vendor 0x%x device 0x%x ERR funcs " 746 "vendor 0x%x device 0x%x ERR func 1 "
747 "(broken BIOS?)\n", 747 "(broken BIOS?)\n",
748 PCI_VENDOR_ID_INTEL, 748 PCI_VENDOR_ID_INTEL,
749 PCI_DEVICE_ID_INTEL_5400_ERR); 749 PCI_DEVICE_ID_INTEL_5400_ERR);
750 goto error; 750 return -ENODEV;
751 } 751 }
752 752
753 /* Store device 16 funcs 1 and 2 */ 753 /* Store device 16 func 1 */
754 switch (PCI_FUNC(pdev->devfn)) { 754 if (PCI_FUNC(pdev->devfn) == 1)
755 case 1:
756 pvt->branchmap_werrors = pdev;
757 break;
758 case 2:
759 pvt->fsb_error_regs = pdev;
760 break; 755 break;
756 }
757 pvt->branchmap_werrors = pdev;
758
759 pdev = NULL;
760 while (1) {
761 pdev = pci_get_device(PCI_VENDOR_ID_INTEL,
762 PCI_DEVICE_ID_INTEL_5400_ERR, pdev);
763 if (!pdev) {
764 /* End of list, leave */
765 i5400_printk(KERN_ERR,
766 "'system address,Process Bus' "
767 "device not found:"
768 "vendor 0x%x device 0x%x ERR func 2 "
769 "(broken BIOS?)\n",
770 PCI_VENDOR_ID_INTEL,
771 PCI_DEVICE_ID_INTEL_5400_ERR);
772
773 pci_dev_put(pvt->branchmap_werrors);
774 return -ENODEV;
761 } 775 }
776
777 /* Store device 16 func 2 */
778 if (PCI_FUNC(pdev->devfn) == 2)
779 break;
762 } 780 }
781 pvt->fsb_error_regs = pdev;
763 782
764 debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n", 783 debugf1("System Address, processor bus- PCI Bus ID: %s %x:%x\n",
765 pci_name(pvt->system_address), 784 pci_name(pvt->system_address),
@@ -778,7 +797,10 @@ static int i5400_get_devices(struct mem_ctl_info *mci, int dev_idx)
778 "MC: 'BRANCH 0' device not found:" 797 "MC: 'BRANCH 0' device not found:"
779 "vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n", 798 "vendor 0x%x device 0x%x Func 0 (broken BIOS?)\n",
780 PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_FBD0); 799 PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_FBD0);
781 goto error; 800
801 pci_dev_put(pvt->fsb_error_regs);
802 pci_dev_put(pvt->branchmap_werrors);
803 return -ENODEV;
782 } 804 }
783 805
784 /* If this device claims to have more than 2 channels then 806 /* 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)
796 "(broken BIOS?)\n", 818 "(broken BIOS?)\n",
797 PCI_VENDOR_ID_INTEL, 819 PCI_VENDOR_ID_INTEL,
798 PCI_DEVICE_ID_INTEL_5400_FBD1); 820 PCI_DEVICE_ID_INTEL_5400_FBD1);
799 goto error; 821
822 pci_dev_put(pvt->branch_0);
823 pci_dev_put(pvt->fsb_error_regs);
824 pci_dev_put(pvt->branchmap_werrors);
825 return -ENODEV;
800 } 826 }
801 827
802 return 0; 828 return 0;
803
804error:
805 i5400_put_devices(mci);
806 return -ENODEV;
807} 829}
808 830
809/* 831/*