aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/ibmphp_core.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-14 14:03:14 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-01-14 14:14:25 -0500
commitc4ec84c7db0e4b01ed40cc2388f16ae5c6513cc0 (patch)
treeb280cdcdbf714b6709e8d87a0d157f4979cb73d7 /drivers/pci/hotplug/ibmphp_core.c
parent5ef68e8867ca9d979644d05c6045b2c79d8989de (diff)
PCI: hotplug: Use global PCI rescan-remove locking
Multiple race conditions are possible between PCI hotplug and the generic PCI bus rescan and device removal that can be triggered via sysfs. To avoid those race conditions make PCI hotplug use global PCI rescan-remove locking. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/hotplug/ibmphp_core.c')
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index efdc13adbe41..cf3ac1e4b099 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -718,6 +718,8 @@ static void ibm_unconfigure_device(struct pci_func *func)
718 func->device, func->function); 718 func->device, func->function);
719 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); 719 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
720 720
721 pci_lock_rescan_remove();
722
721 for (j = 0; j < 0x08; j++) { 723 for (j = 0; j < 0x08; j++) {
722 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); 724 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
723 if (temp) { 725 if (temp) {
@@ -725,7 +727,10 @@ static void ibm_unconfigure_device(struct pci_func *func)
725 pci_dev_put(temp); 727 pci_dev_put(temp);
726 } 728 }
727 } 729 }
730
728 pci_dev_put(func->dev); 731 pci_dev_put(func->dev);
732
733 pci_unlock_rescan_remove();
729} 734}
730 735
731/* 736/*
@@ -780,6 +785,8 @@ static int ibm_configure_device(struct pci_func *func)
780 int flag = 0; /* this is to make sure we don't double scan the bus, 785 int flag = 0; /* this is to make sure we don't double scan the bus,
781 for bridged devices primarily */ 786 for bridged devices primarily */
782 787
788 pci_lock_rescan_remove();
789
783 if (!(bus_structure_fixup(func->busno))) 790 if (!(bus_structure_fixup(func->busno)))
784 flag = 1; 791 flag = 1;
785 if (func->dev == NULL) 792 if (func->dev == NULL)
@@ -789,7 +796,7 @@ static int ibm_configure_device(struct pci_func *func)
789 if (func->dev == NULL) { 796 if (func->dev == NULL) {
790 struct pci_bus *bus = pci_find_bus(0, func->busno); 797 struct pci_bus *bus = pci_find_bus(0, func->busno);
791 if (!bus) 798 if (!bus)
792 return 0; 799 goto out;
793 800
794 num = pci_scan_slot(bus, 801 num = pci_scan_slot(bus,
795 PCI_DEVFN(func->device, func->function)); 802 PCI_DEVFN(func->device, func->function));
@@ -800,7 +807,7 @@ static int ibm_configure_device(struct pci_func *func)
800 PCI_DEVFN(func->device, func->function)); 807 PCI_DEVFN(func->device, func->function));
801 if (func->dev == NULL) { 808 if (func->dev == NULL) {
802 err("ERROR... : pci_dev still NULL\n"); 809 err("ERROR... : pci_dev still NULL\n");
803 return 0; 810 goto out;
804 } 811 }
805 } 812 }
806 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { 813 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
@@ -810,6 +817,8 @@ static int ibm_configure_device(struct pci_func *func)
810 pci_bus_add_devices(child); 817 pci_bus_add_devices(child);
811 } 818 }
812 819
820 out:
821 pci_unlock_rescan_remove();
813 return 0; 822 return 0;
814} 823}
815 824