aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-01-15 12:53:23 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-01-15 12:53:23 -0500
commit40304618468cae5259f77c15511e4feb7bfb624b (patch)
tree19666e52586c98484a3bf8f1b19c28103feb9006
parent1255dfbb0c77c7a26fec10a5c101b075c3641965 (diff)
parent8a4c5c329de716996eea03d93753ccbb5406072b (diff)
Merge branch 'pci/locking' into next
* pci/locking: PCI: Check parent kobject in pci_destroy_dev() xen/pcifront: Use global PCI rescan-remove locking powerpc/eeh: Use global PCI rescan-remove locking MPT / PCI: Use pci_stop_and_remove_bus_device_locked() platform / x86: Use global PCI rescan-remove locking PCI: hotplug: Use global PCI rescan-remove locking pcmcia: Use global PCI rescan-remove locking ACPI / hotplug / PCI: Use global PCI rescan-remove locking ACPI / PCI: Use global PCI rescan-remove locking in PCI root hotplug PCI: Add global pci_lock_rescan_remove()
-rw-r--r--arch/powerpc/kernel/eeh_driver.c19
-rw-r--r--drivers/acpi/pci_root.c6
-rw-r--r--drivers/message/fusion/mptbase.c2
-rw-r--r--drivers/pci/hotplug/acpiphp.h5
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c43
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c14
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c8
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c13
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c17
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c19
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c4
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c4
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c5
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c18
-rw-r--r--drivers/pci/pci-sysfs.c19
-rw-r--r--drivers/pci/probe.c18
-rw-r--r--drivers/pci/remove.c11
-rw-r--r--drivers/pci/xen-pcifront.c8
-rw-r--r--drivers/pcmcia/cardbus.c7
-rw-r--r--drivers/platform/x86/asus-wmi.c2
-rw-r--r--drivers/platform/x86/eeepc-laptop.c2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c2
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c2
-rw-r--r--include/linux/pci.h3
25 files changed, 209 insertions, 44 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 36bed5a12750..c17f90d0f73c 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -369,7 +369,9 @@ static void *eeh_rmv_device(void *data, void *userdata)
369 edev->mode |= EEH_DEV_DISCONNECTED; 369 edev->mode |= EEH_DEV_DISCONNECTED;
370 (*removed)++; 370 (*removed)++;
371 371
372 pci_lock_rescan_remove();
372 pci_stop_and_remove_bus_device(dev); 373 pci_stop_and_remove_bus_device(dev);
374 pci_unlock_rescan_remove();
373 375
374 return NULL; 376 return NULL;
375} 377}
@@ -416,10 +418,13 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
416 * into pcibios_add_pci_devices(). 418 * into pcibios_add_pci_devices().
417 */ 419 */
418 eeh_pe_state_mark(pe, EEH_PE_KEEP); 420 eeh_pe_state_mark(pe, EEH_PE_KEEP);
419 if (bus) 421 if (bus) {
422 pci_lock_rescan_remove();
420 pcibios_remove_pci_devices(bus); 423 pcibios_remove_pci_devices(bus);
421 else if (frozen_bus) 424 pci_unlock_rescan_remove();
425 } else if (frozen_bus) {
422 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); 426 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed);
427 }
423 428
424 /* Reset the pci controller. (Asserts RST#; resets config space). 429 /* Reset the pci controller. (Asserts RST#; resets config space).
425 * Reconfigure bridges and devices. Don't try to bring the system 430 * Reconfigure bridges and devices. Don't try to bring the system
@@ -429,6 +434,8 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
429 if (rc) 434 if (rc)
430 return rc; 435 return rc;
431 436
437 pci_lock_rescan_remove();
438
432 /* Restore PE */ 439 /* Restore PE */
433 eeh_ops->configure_bridge(pe); 440 eeh_ops->configure_bridge(pe);
434 eeh_pe_restore_bars(pe); 441 eeh_pe_restore_bars(pe);
@@ -462,6 +469,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
462 pe->tstamp = tstamp; 469 pe->tstamp = tstamp;
463 pe->freeze_count = cnt; 470 pe->freeze_count = cnt;
464 471
472 pci_unlock_rescan_remove();
465 return 0; 473 return 0;
466} 474}
467 475
@@ -618,8 +626,11 @@ perm_error:
618 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 626 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
619 627
620 /* Shut down the device drivers for good. */ 628 /* Shut down the device drivers for good. */
621 if (frozen_bus) 629 if (frozen_bus) {
630 pci_lock_rescan_remove();
622 pcibios_remove_pci_devices(frozen_bus); 631 pcibios_remove_pci_devices(frozen_bus);
632 pci_unlock_rescan_remove();
633 }
623} 634}
624 635
625static void eeh_handle_special_event(void) 636static void eeh_handle_special_event(void)
@@ -692,6 +703,7 @@ static void eeh_handle_special_event(void)
692 if (rc == 2 || rc == 1) 703 if (rc == 2 || rc == 1)
693 eeh_handle_normal_event(pe); 704 eeh_handle_normal_event(pe);
694 else { 705 else {
706 pci_lock_rescan_remove();
695 list_for_each_entry_safe(hose, tmp, 707 list_for_each_entry_safe(hose, tmp,
696 &hose_list, list_node) { 708 &hose_list, list_node) {
697 phb_pe = eeh_phb_pe_get(hose); 709 phb_pe = eeh_phb_pe_get(hose);
@@ -703,6 +715,7 @@ static void eeh_handle_special_event(void)
703 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 715 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
704 pcibios_remove_pci_devices(bus); 716 pcibios_remove_pci_devices(bus);
705 } 717 }
718 pci_unlock_rescan_remove();
706 } 719 }
707} 720}
708 721
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 0703bff5e60e..07ee02aa3c51 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -596,7 +596,9 @@ static int acpi_pci_root_add(struct acpi_device *device,
596 pci_assign_unassigned_root_bus_resources(root->bus); 596 pci_assign_unassigned_root_bus_resources(root->bus);
597 } 597 }
598 598
599 pci_lock_rescan_remove();
599 pci_bus_add_devices(root->bus); 600 pci_bus_add_devices(root->bus);
601 pci_unlock_rescan_remove();
600 return 1; 602 return 1;
601 603
602end: 604end:
@@ -608,6 +610,8 @@ static void acpi_pci_root_remove(struct acpi_device *device)
608{ 610{
609 struct acpi_pci_root *root = acpi_driver_data(device); 611 struct acpi_pci_root *root = acpi_driver_data(device);
610 612
613 pci_lock_rescan_remove();
614
611 pci_stop_root_bus(root->bus); 615 pci_stop_root_bus(root->bus);
612 616
613 device_set_run_wake(root->bus->bridge, false); 617 device_set_run_wake(root->bus->bridge, false);
@@ -615,6 +619,8 @@ static void acpi_pci_root_remove(struct acpi_device *device)
615 619
616 pci_remove_root_bus(root->bus); 620 pci_remove_root_bus(root->bus);
617 621
622 pci_unlock_rescan_remove();
623
618 kfree(root); 624 kfree(root);
619} 625}
620 626
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 767ff4d839f4..570b18a113ff 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -346,7 +346,7 @@ static int mpt_remove_dead_ioc_func(void *arg)
346 if ((pdev == NULL)) 346 if ((pdev == NULL))
347 return -1; 347 return -1;
348 348
349 pci_stop_and_remove_bus_device(pdev); 349 pci_stop_and_remove_bus_device_locked(pdev);
350 return 0; 350 return 0;
351} 351}
352 352
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index 1592dbe4f904..b6162be4df40 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -77,6 +77,8 @@ struct acpiphp_bridge {
77 77
78 /* PCI-to-PCI bridge device */ 78 /* PCI-to-PCI bridge device */
79 struct pci_dev *pci_dev; 79 struct pci_dev *pci_dev;
80
81 bool is_going_away;
80}; 82};
81 83
82 84
@@ -150,6 +152,7 @@ struct acpiphp_attention_info
150/* slot flags */ 152/* slot flags */
151 153
152#define SLOT_ENABLED (0x00000001) 154#define SLOT_ENABLED (0x00000001)
155#define SLOT_IS_GOING_AWAY (0x00000002)
153 156
154/* function flags */ 157/* function flags */
155 158
@@ -169,7 +172,7 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *slot);
169typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); 172typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
170 173
171int acpiphp_enable_slot(struct acpiphp_slot *slot); 174int acpiphp_enable_slot(struct acpiphp_slot *slot);
172int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); 175int acpiphp_disable_slot(struct acpiphp_slot *slot);
173u8 acpiphp_get_power_status(struct acpiphp_slot *slot); 176u8 acpiphp_get_power_status(struct acpiphp_slot *slot);
174u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); 177u8 acpiphp_get_attention_status(struct acpiphp_slot *slot);
175u8 acpiphp_get_latch_status(struct acpiphp_slot *slot); 178u8 acpiphp_get_latch_status(struct acpiphp_slot *slot);
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index dca66bc44578..728c31f4c2c5 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -156,7 +156,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
156 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 156 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot));
157 157
158 /* disable the specified slot */ 158 /* disable the specified slot */
159 return acpiphp_disable_and_eject_slot(slot->acpi_slot); 159 return acpiphp_disable_slot(slot->acpi_slot);
160} 160}
161 161
162 162
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 1cf605f67673..641ba6761bd7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -430,6 +430,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
430 pr_err("failed to remove notify handler\n"); 430 pr_err("failed to remove notify handler\n");
431 } 431 }
432 } 432 }
433 slot->flags |= SLOT_IS_GOING_AWAY;
433 if (slot->slot) 434 if (slot->slot)
434 acpiphp_unregister_hotplug_slot(slot); 435 acpiphp_unregister_hotplug_slot(slot);
435 } 436 }
@@ -437,6 +438,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
437 mutex_lock(&bridge_mutex); 438 mutex_lock(&bridge_mutex);
438 list_del(&bridge->list); 439 list_del(&bridge->list);
439 mutex_unlock(&bridge_mutex); 440 mutex_unlock(&bridge_mutex);
441
442 bridge->is_going_away = true;
440} 443}
441 444
442/** 445/**
@@ -736,6 +739,10 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
736{ 739{
737 struct acpiphp_slot *slot; 740 struct acpiphp_slot *slot;
738 741
742 /* Bail out if the bridge is going away. */
743 if (bridge->is_going_away)
744 return;
745
739 list_for_each_entry(slot, &bridge->slots, node) { 746 list_for_each_entry(slot, &bridge->slots, node) {
740 struct pci_bus *bus = slot->bus; 747 struct pci_bus *bus = slot->bus;
741 struct pci_dev *dev, *tmp; 748 struct pci_dev *dev, *tmp;
@@ -805,6 +812,8 @@ void acpiphp_check_host_bridge(acpi_handle handle)
805 } 812 }
806} 813}
807 814
815static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot);
816
808static void hotplug_event(acpi_handle handle, u32 type, void *data) 817static void hotplug_event(acpi_handle handle, u32 type, void *data)
809{ 818{
810 struct acpiphp_context *context = data; 819 struct acpiphp_context *context = data;
@@ -834,6 +843,9 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
834 } else { 843 } else {
835 struct acpiphp_slot *slot = func->slot; 844 struct acpiphp_slot *slot = func->slot;
836 845
846 if (slot->flags & SLOT_IS_GOING_AWAY)
847 break;
848
837 mutex_lock(&slot->crit_sect); 849 mutex_lock(&slot->crit_sect);
838 enable_slot(slot); 850 enable_slot(slot);
839 mutex_unlock(&slot->crit_sect); 851 mutex_unlock(&slot->crit_sect);
@@ -849,6 +861,9 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data)
849 struct acpiphp_slot *slot = func->slot; 861 struct acpiphp_slot *slot = func->slot;
850 int ret; 862 int ret;
851 863
864 if (slot->flags & SLOT_IS_GOING_AWAY)
865 break;
866
852 /* 867 /*
853 * Check if anything has changed in the slot and rescan 868 * Check if anything has changed in the slot and rescan
854 * from the parent if that's the case. 869 * from the parent if that's the case.
@@ -878,9 +893,11 @@ static void hotplug_event_work(void *data, u32 type)
878 acpi_handle handle = context->handle; 893 acpi_handle handle = context->handle;
879 894
880 acpi_scan_lock_acquire(); 895 acpi_scan_lock_acquire();
896 pci_lock_rescan_remove();
881 897
882 hotplug_event(handle, type, context); 898 hotplug_event(handle, type, context);
883 899
900 pci_unlock_rescan_remove();
884 acpi_scan_lock_release(); 901 acpi_scan_lock_release();
885 acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); 902 acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL);
886 put_bridge(context->func.parent); 903 put_bridge(context->func.parent);
@@ -1048,12 +1065,19 @@ void acpiphp_remove_slots(struct pci_bus *bus)
1048 */ 1065 */
1049int acpiphp_enable_slot(struct acpiphp_slot *slot) 1066int acpiphp_enable_slot(struct acpiphp_slot *slot)
1050{ 1067{
1068 pci_lock_rescan_remove();
1069
1070 if (slot->flags & SLOT_IS_GOING_AWAY)
1071 return -ENODEV;
1072
1051 mutex_lock(&slot->crit_sect); 1073 mutex_lock(&slot->crit_sect);
1052 /* configure all functions */ 1074 /* configure all functions */
1053 if (!(slot->flags & SLOT_ENABLED)) 1075 if (!(slot->flags & SLOT_ENABLED))
1054 enable_slot(slot); 1076 enable_slot(slot);
1055 1077
1056 mutex_unlock(&slot->crit_sect); 1078 mutex_unlock(&slot->crit_sect);
1079
1080 pci_unlock_rescan_remove();
1057 return 0; 1081 return 0;
1058} 1082}
1059 1083
@@ -1061,10 +1085,12 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
1061 * acpiphp_disable_and_eject_slot - power off and eject slot 1085 * acpiphp_disable_and_eject_slot - power off and eject slot
1062 * @slot: ACPI PHP slot 1086 * @slot: ACPI PHP slot
1063 */ 1087 */
1064int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) 1088static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
1065{ 1089{
1066 struct acpiphp_func *func; 1090 struct acpiphp_func *func;
1067 int retval = 0; 1091
1092 if (slot->flags & SLOT_IS_GOING_AWAY)
1093 return -ENODEV;
1068 1094
1069 mutex_lock(&slot->crit_sect); 1095 mutex_lock(&slot->crit_sect);
1070 1096
@@ -1082,9 +1108,18 @@ int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot)
1082 } 1108 }
1083 1109
1084 mutex_unlock(&slot->crit_sect); 1110 mutex_unlock(&slot->crit_sect);
1085 return retval; 1111 return 0;
1086} 1112}
1087 1113
1114int acpiphp_disable_slot(struct acpiphp_slot *slot)
1115{
1116 int ret;
1117
1118 pci_lock_rescan_remove();
1119 ret = acpiphp_disable_and_eject_slot(slot);
1120 pci_unlock_rescan_remove();
1121 return ret;
1122}
1088 1123
1089/* 1124/*
1090 * slot enabled: 1 1125 * slot enabled: 1
@@ -1095,7 +1130,6 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
1095 return (slot->flags & SLOT_ENABLED); 1130 return (slot->flags & SLOT_ENABLED);
1096} 1131}
1097 1132
1098
1099/* 1133/*
1100 * latch open: 1 1134 * latch open: 1
1101 * latch closed: 0 1135 * latch closed: 0
@@ -1105,7 +1139,6 @@ u8 acpiphp_get_latch_status(struct acpiphp_slot *slot)
1105 return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI); 1139 return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI);
1106} 1140}
1107 1141
1108
1109/* 1142/*
1110 * adapter presence : 1 1143 * adapter presence : 1
1111 * absence : 0 1144 * absence : 0
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index d3add9819f63..8c1464851768 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -254,9 +254,12 @@ int __ref cpci_configure_slot(struct slot *slot)
254{ 254{
255 struct pci_dev *dev; 255 struct pci_dev *dev;
256 struct pci_bus *parent; 256 struct pci_bus *parent;
257 int ret = 0;
257 258
258 dbg("%s - enter", __func__); 259 dbg("%s - enter", __func__);
259 260
261 pci_lock_rescan_remove();
262
260 if (slot->dev == NULL) { 263 if (slot->dev == NULL) {
261 dbg("pci_dev null, finding %02x:%02x:%x", 264 dbg("pci_dev null, finding %02x:%02x:%x",
262 slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); 265 slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
@@ -277,7 +280,8 @@ int __ref cpci_configure_slot(struct slot *slot)
277 slot->dev = pci_get_slot(slot->bus, slot->devfn); 280 slot->dev = pci_get_slot(slot->bus, slot->devfn);
278 if (slot->dev == NULL) { 281 if (slot->dev == NULL) {
279 err("Could not find PCI device for slot %02x", slot->number); 282 err("Could not find PCI device for slot %02x", slot->number);
280 return -ENODEV; 283 ret = -ENODEV;
284 goto out;
281 } 285 }
282 } 286 }
283 parent = slot->dev->bus; 287 parent = slot->dev->bus;
@@ -294,8 +298,10 @@ int __ref cpci_configure_slot(struct slot *slot)
294 298
295 pci_bus_add_devices(parent); 299 pci_bus_add_devices(parent);
296 300
301 out:
302 pci_unlock_rescan_remove();
297 dbg("%s - exit", __func__); 303 dbg("%s - exit", __func__);
298 return 0; 304 return ret;
299} 305}
300 306
301int cpci_unconfigure_slot(struct slot* slot) 307int cpci_unconfigure_slot(struct slot* slot)
@@ -308,6 +314,8 @@ int cpci_unconfigure_slot(struct slot* slot)
308 return -ENODEV; 314 return -ENODEV;
309 } 315 }
310 316
317 pci_lock_rescan_remove();
318
311 list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { 319 list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {
312 if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) 320 if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
313 continue; 321 continue;
@@ -318,6 +326,8 @@ int cpci_unconfigure_slot(struct slot* slot)
318 pci_dev_put(slot->dev); 326 pci_dev_put(slot->dev);
319 slot->dev = NULL; 327 slot->dev = NULL;
320 328
329 pci_unlock_rescan_remove();
330
321 dbg("%s - exit", __func__); 331 dbg("%s - exit", __func__);
322 return 0; 332 return 0;
323} 333}
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index 6e4a12c91adb..a3e3c2002b58 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -86,6 +86,8 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
86 struct pci_bus *child; 86 struct pci_bus *child;
87 int num; 87 int num;
88 88
89 pci_lock_rescan_remove();
90
89 if (func->pci_dev == NULL) 91 if (func->pci_dev == NULL)
90 func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function)); 92 func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function));
91 93
@@ -100,7 +102,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
100 func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function)); 102 func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
101 if (func->pci_dev == NULL) { 103 if (func->pci_dev == NULL) {
102 dbg("ERROR: pci_dev still null\n"); 104 dbg("ERROR: pci_dev still null\n");
103 return 0; 105 goto out;
104 } 106 }
105 } 107 }
106 108
@@ -113,6 +115,8 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func)
113 115
114 pci_dev_put(func->pci_dev); 116 pci_dev_put(func->pci_dev);
115 117
118 out:
119 pci_unlock_rescan_remove();
116 return 0; 120 return 0;
117} 121}
118 122
@@ -123,6 +127,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
123 127
124 dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); 128 dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function);
125 129
130 pci_lock_rescan_remove();
126 for (j=0; j<8 ; j++) { 131 for (j=0; j<8 ; j++) {
127 struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); 132 struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
128 if (temp) { 133 if (temp) {
@@ -130,6 +135,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
130 pci_stop_and_remove_bus_device(temp); 135 pci_stop_and_remove_bus_device(temp);
131 } 136 }
132 } 137 }
138 pci_unlock_rescan_remove();
133 return 0; 139 return 0;
134} 140}
135 141
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
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 198355112ee7..b07d7cc2d697 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -39,22 +39,26 @@ int pciehp_configure_device(struct slot *p_slot)
39 struct pci_dev *dev; 39 struct pci_dev *dev;
40 struct pci_dev *bridge = p_slot->ctrl->pcie->port; 40 struct pci_dev *bridge = p_slot->ctrl->pcie->port;
41 struct pci_bus *parent = bridge->subordinate; 41 struct pci_bus *parent = bridge->subordinate;
42 int num; 42 int num, ret = 0;
43 struct controller *ctrl = p_slot->ctrl; 43 struct controller *ctrl = p_slot->ctrl;
44 44
45 pci_lock_rescan_remove();
46
45 dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); 47 dev = pci_get_slot(parent, PCI_DEVFN(0, 0));
46 if (dev) { 48 if (dev) {
47 ctrl_err(ctrl, "Device %s already exists " 49 ctrl_err(ctrl, "Device %s already exists "
48 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), 50 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev),
49 pci_domain_nr(parent), parent->number); 51 pci_domain_nr(parent), parent->number);
50 pci_dev_put(dev); 52 pci_dev_put(dev);
51 return -EINVAL; 53 ret = -EINVAL;
54 goto out;
52 } 55 }
53 56
54 num = pci_scan_slot(parent, PCI_DEVFN(0, 0)); 57 num = pci_scan_slot(parent, PCI_DEVFN(0, 0));
55 if (num == 0) { 58 if (num == 0) {
56 ctrl_err(ctrl, "No new device found\n"); 59 ctrl_err(ctrl, "No new device found\n");
57 return -ENODEV; 60 ret = -ENODEV;
61 goto out;
58 } 62 }
59 63
60 list_for_each_entry(dev, &parent->devices, bus_list) 64 list_for_each_entry(dev, &parent->devices, bus_list)
@@ -73,7 +77,9 @@ int pciehp_configure_device(struct slot *p_slot)
73 77
74 pci_bus_add_devices(parent); 78 pci_bus_add_devices(parent);
75 79
76 return 0; 80 out:
81 pci_unlock_rescan_remove();
82 return ret;
77} 83}
78 84
79int pciehp_unconfigure_device(struct slot *p_slot) 85int pciehp_unconfigure_device(struct slot *p_slot)
@@ -90,6 +96,8 @@ int pciehp_unconfigure_device(struct slot *p_slot)
90 __func__, pci_domain_nr(parent), parent->number); 96 __func__, pci_domain_nr(parent), parent->number);
91 pciehp_get_adapter_status(p_slot, &presence); 97 pciehp_get_adapter_status(p_slot, &presence);
92 98
99 pci_lock_rescan_remove();
100
93 /* 101 /*
94 * Stopping an SR-IOV PF device removes all the associated VFs, 102 * Stopping an SR-IOV PF device removes all the associated VFs,
95 * which will update the bus->devices list and confuse the 103 * which will update the bus->devices list and confuse the
@@ -124,5 +132,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
124 pci_dev_put(dev); 132 pci_dev_put(dev);
125 } 133 }
126 134
135 pci_unlock_rescan_remove();
127 return rc; 136 return rc;
128} 137}
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index e9c044d15add..4fcdeedda31b 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -354,10 +354,15 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
354{ 354{
355 struct pci_bus *bus; 355 struct pci_bus *bus;
356 struct slot *slot; 356 struct slot *slot;
357 int ret = 0;
358
359 pci_lock_rescan_remove();
357 360
358 bus = pcibios_find_pci_bus(dn); 361 bus = pcibios_find_pci_bus(dn);
359 if (!bus) 362 if (!bus) {
360 return -EINVAL; 363 ret = -EINVAL;
364 goto out;
365 }
361 366
362 pr_debug("PCI: Removing PCI slot below EADS bridge %s\n", 367 pr_debug("PCI: Removing PCI slot below EADS bridge %s\n",
363 bus->self ? pci_name(bus->self) : "<!PHB!>"); 368 bus->self ? pci_name(bus->self) : "<!PHB!>");
@@ -371,7 +376,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
371 printk(KERN_ERR 376 printk(KERN_ERR
372 "%s: unable to remove hotplug slot %s\n", 377 "%s: unable to remove hotplug slot %s\n",
373 __func__, drc_name); 378 __func__, drc_name);
374 return -EIO; 379 ret = -EIO;
380 goto out;
375 } 381 }
376 } 382 }
377 383
@@ -382,7 +388,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
382 if (pcibios_unmap_io_space(bus)) { 388 if (pcibios_unmap_io_space(bus)) {
383 printk(KERN_ERR "%s: failed to unmap bus range\n", 389 printk(KERN_ERR "%s: failed to unmap bus range\n",
384 __func__); 390 __func__);
385 return -ERANGE; 391 ret = -ERANGE;
392 goto out;
386 } 393 }
387 394
388 /* Remove the EADS bridge device itself */ 395 /* Remove the EADS bridge device itself */
@@ -390,7 +397,9 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn)
390 pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); 397 pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self));
391 pci_stop_and_remove_bus_device(bus->self); 398 pci_stop_and_remove_bus_device(bus->self);
392 399
393 return 0; 400 out:
401 pci_unlock_rescan_remove();
402 return ret;
394} 403}
395 404
396/** 405/**
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index b7fc5c9255a5..4796c15fba94 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -398,7 +398,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
398 return retval; 398 return retval;
399 399
400 if (state == PRESENT) { 400 if (state == PRESENT) {
401 pci_lock_rescan_remove();
401 pcibios_add_pci_devices(slot->bus); 402 pcibios_add_pci_devices(slot->bus);
403 pci_unlock_rescan_remove();
402 slot->state = CONFIGURED; 404 slot->state = CONFIGURED;
403 } else if (state == EMPTY) { 405 } else if (state == EMPTY) {
404 slot->state = EMPTY; 406 slot->state = EMPTY;
@@ -418,7 +420,9 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
418 if (slot->state == NOT_CONFIGURED) 420 if (slot->state == NOT_CONFIGURED)
419 return -EINVAL; 421 return -EINVAL;
420 422
423 pci_lock_rescan_remove();
421 pcibios_remove_pci_devices(slot->bus); 424 pcibios_remove_pci_devices(slot->bus);
425 pci_unlock_rescan_remove();
422 vm_unmap_aliases(); 426 vm_unmap_aliases();
423 427
424 slot->state = NOT_CONFIGURED; 428 slot->state = NOT_CONFIGURED;
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 3c7eb5dd91c6..8d2ce22151eb 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -80,7 +80,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
80 goto out_deconfigure; 80 goto out_deconfigure;
81 81
82 pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); 82 pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN);
83 pci_lock_rescan_remove();
83 pci_bus_add_devices(slot->zdev->bus); 84 pci_bus_add_devices(slot->zdev->bus);
85 pci_unlock_rescan_remove();
84 86
85 return rc; 87 return rc;
86 88
@@ -98,7 +100,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
98 return -EIO; 100 return -EIO;
99 101
100 if (slot->zdev->pdev) 102 if (slot->zdev->pdev)
101 pci_stop_and_remove_bus_device(slot->zdev->pdev); 103 pci_stop_and_remove_bus_device_locked(slot->zdev->pdev);
102 104
103 rc = zpci_disable_device(slot->zdev); 105 rc = zpci_disable_device(slot->zdev);
104 if (rc) 106 if (rc)
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 5b05a68cca6c..613043f7576f 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -459,12 +459,15 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
459 acpi_scan_lock_release(); 459 acpi_scan_lock_release();
460 } 460 }
461 461
462 pci_lock_rescan_remove();
463
462 /* Call the driver for the new device */ 464 /* Call the driver for the new device */
463 pci_bus_add_devices(slot->pci_bus); 465 pci_bus_add_devices(slot->pci_bus);
464 /* Call the drivers for the new devices subordinate to PPB */ 466 /* Call the drivers for the new devices subordinate to PPB */
465 if (new_ppb) 467 if (new_ppb)
466 pci_bus_add_devices(new_bus); 468 pci_bus_add_devices(new_bus);
467 469
470 pci_unlock_rescan_remove();
468 mutex_unlock(&sn_hotplug_mutex); 471 mutex_unlock(&sn_hotplug_mutex);
469 472
470 if (rc == 0) 473 if (rc == 0)
@@ -540,6 +543,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
540 acpi_scan_lock_release(); 543 acpi_scan_lock_release();
541 } 544 }
542 545
546 pci_lock_rescan_remove();
543 /* Free the SN resources assigned to the Linux device.*/ 547 /* Free the SN resources assigned to the Linux device.*/
544 list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { 548 list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {
545 if (PCI_SLOT(dev->devfn) != slot->device_num + 1) 549 if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
@@ -550,6 +554,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
550 pci_stop_and_remove_bus_device(dev); 554 pci_stop_and_remove_bus_device(dev);
551 pci_dev_put(dev); 555 pci_dev_put(dev);
552 } 556 }
557 pci_unlock_rescan_remove();
553 558
554 /* Remove the SSDT for the slot from the ACPI namespace */ 559 /* Remove the SSDT for the slot from the ACPI namespace */
555 if (SN_ACPI_BASE_SUPPORT() && ssdt_id) { 560 if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index b0e83132542e..2bf69fe1926c 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -40,7 +40,9 @@ int __ref shpchp_configure_device(struct slot *p_slot)
40 struct controller *ctrl = p_slot->ctrl; 40 struct controller *ctrl = p_slot->ctrl;
41 struct pci_dev *bridge = ctrl->pci_dev; 41 struct pci_dev *bridge = ctrl->pci_dev;
42 struct pci_bus *parent = bridge->subordinate; 42 struct pci_bus *parent = bridge->subordinate;
43 int num; 43 int num, ret = 0;
44
45 pci_lock_rescan_remove();
44 46
45 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); 47 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
46 if (dev) { 48 if (dev) {
@@ -48,13 +50,15 @@ int __ref shpchp_configure_device(struct slot *p_slot)
48 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev), 50 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev),
49 pci_domain_nr(parent), p_slot->bus, p_slot->device); 51 pci_domain_nr(parent), p_slot->bus, p_slot->device);
50 pci_dev_put(dev); 52 pci_dev_put(dev);
51 return -EINVAL; 53 ret = -EINVAL;
54 goto out;
52 } 55 }
53 56
54 num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); 57 num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
55 if (num == 0) { 58 if (num == 0) {
56 ctrl_err(ctrl, "No new device found\n"); 59 ctrl_err(ctrl, "No new device found\n");
57 return -ENODEV; 60 ret = -ENODEV;
61 goto out;
58 } 62 }
59 63
60 list_for_each_entry(dev, &parent->devices, bus_list) { 64 list_for_each_entry(dev, &parent->devices, bus_list) {
@@ -75,7 +79,9 @@ int __ref shpchp_configure_device(struct slot *p_slot)
75 79
76 pci_bus_add_devices(parent); 80 pci_bus_add_devices(parent);
77 81
78 return 0; 82 out:
83 pci_unlock_rescan_remove();
84 return ret;
79} 85}
80 86
81int shpchp_unconfigure_device(struct slot *p_slot) 87int shpchp_unconfigure_device(struct slot *p_slot)
@@ -89,6 +95,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)
89 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", 95 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",
90 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); 96 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);
91 97
98 pci_lock_rescan_remove();
99
92 list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { 100 list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) {
93 if (PCI_SLOT(dev->devfn) != p_slot->device) 101 if (PCI_SLOT(dev->devfn) != p_slot->device)
94 continue; 102 continue;
@@ -108,6 +116,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)
108 pci_stop_and_remove_bus_device(dev); 116 pci_stop_and_remove_bus_device(dev);
109 pci_dev_put(dev); 117 pci_dev_put(dev);
110 } 118 }
119
120 pci_unlock_rescan_remove();
111 return rc; 121 return rc;
112} 122}
113 123
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c91e6c18debc..276ef9c18802 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -297,7 +297,6 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
297} 297}
298static DEVICE_ATTR_RW(msi_bus); 298static DEVICE_ATTR_RW(msi_bus);
299 299
300static DEFINE_MUTEX(pci_remove_rescan_mutex);
301static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, 300static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
302 size_t count) 301 size_t count)
303{ 302{
@@ -308,10 +307,10 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
308 return -EINVAL; 307 return -EINVAL;
309 308
310 if (val) { 309 if (val) {
311 mutex_lock(&pci_remove_rescan_mutex); 310 pci_lock_rescan_remove();
312 while ((b = pci_find_next_bus(b)) != NULL) 311 while ((b = pci_find_next_bus(b)) != NULL)
313 pci_rescan_bus(b); 312 pci_rescan_bus(b);
314 mutex_unlock(&pci_remove_rescan_mutex); 313 pci_unlock_rescan_remove();
315 } 314 }
316 return count; 315 return count;
317} 316}
@@ -342,9 +341,9 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr,
342 return -EINVAL; 341 return -EINVAL;
343 342
344 if (val) { 343 if (val) {
345 mutex_lock(&pci_remove_rescan_mutex); 344 pci_lock_rescan_remove();
346 pci_rescan_bus(pdev->bus); 345 pci_rescan_bus(pdev->bus);
347 mutex_unlock(&pci_remove_rescan_mutex); 346 pci_unlock_rescan_remove();
348 } 347 }
349 return count; 348 return count;
350} 349}
@@ -354,11 +353,7 @@ static struct device_attribute dev_rescan_attr = __ATTR(rescan,
354 353
355static void remove_callback(struct device *dev) 354static void remove_callback(struct device *dev)
356{ 355{
357 struct pci_dev *pdev = to_pci_dev(dev); 356 pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
358
359 mutex_lock(&pci_remove_rescan_mutex);
360 pci_stop_and_remove_bus_device(pdev);
361 mutex_unlock(&pci_remove_rescan_mutex);
362} 357}
363 358
364static ssize_t 359static ssize_t
@@ -395,12 +390,12 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
395 return -EINVAL; 390 return -EINVAL;
396 391
397 if (val) { 392 if (val) {
398 mutex_lock(&pci_remove_rescan_mutex); 393 pci_lock_rescan_remove();
399 if (!pci_is_root_bus(bus) && list_empty(&bus->devices)) 394 if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
400 pci_rescan_bus_bridge_resize(bus->self); 395 pci_rescan_bus_bridge_resize(bus->self);
401 else 396 else
402 pci_rescan_bus(bus); 397 pci_rescan_bus(bus);
403 mutex_unlock(&pci_remove_rescan_mutex); 398 pci_unlock_rescan_remove();
404 } 399 }
405 return count; 400 return count;
406} 401}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c86c8638d3c4..04796c056d12 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2024,6 +2024,24 @@ EXPORT_SYMBOL(pci_scan_slot);
2024EXPORT_SYMBOL(pci_scan_bridge); 2024EXPORT_SYMBOL(pci_scan_bridge);
2025EXPORT_SYMBOL_GPL(pci_scan_child_bus); 2025EXPORT_SYMBOL_GPL(pci_scan_child_bus);
2026 2026
2027/*
2028 * pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal
2029 * routines should always be executed under this mutex.
2030 */
2031static DEFINE_MUTEX(pci_rescan_remove_lock);
2032
2033void pci_lock_rescan_remove(void)
2034{
2035 mutex_lock(&pci_rescan_remove_lock);
2036}
2037EXPORT_SYMBOL_GPL(pci_lock_rescan_remove);
2038
2039void pci_unlock_rescan_remove(void)
2040{
2041 mutex_unlock(&pci_rescan_remove_lock);
2042}
2043EXPORT_SYMBOL_GPL(pci_unlock_rescan_remove);
2044
2027static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b) 2045static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
2028{ 2046{
2029 const struct pci_dev *a = to_pci_dev(d_a); 2047 const struct pci_dev *a = to_pci_dev(d_a);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index f452148e6d55..4ff36bfa785e 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -20,6 +20,9 @@ static void pci_stop_dev(struct pci_dev *dev)
20 20
21static void pci_destroy_dev(struct pci_dev *dev) 21static void pci_destroy_dev(struct pci_dev *dev)
22{ 22{
23 if (!dev->dev.kobj.parent)
24 return;
25
23 device_del(&dev->dev); 26 device_del(&dev->dev);
24 27
25 put_device(&dev->dev); 28 put_device(&dev->dev);
@@ -95,6 +98,14 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev)
95} 98}
96EXPORT_SYMBOL(pci_stop_and_remove_bus_device); 99EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
97 100
101void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev)
102{
103 pci_lock_rescan_remove();
104 pci_stop_and_remove_bus_device(dev);
105 pci_unlock_rescan_remove();
106}
107EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked);
108
98void pci_stop_root_bus(struct pci_bus *bus) 109void pci_stop_root_bus(struct pci_bus *bus)
99{ 110{
100 struct pci_dev *child, *tmp; 111 struct pci_dev *child, *tmp;
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index f7197a790341..d1cd60f51f87 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -471,12 +471,15 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
471 } 471 }
472 pcifront_init_sd(sd, domain, bus, pdev); 472 pcifront_init_sd(sd, domain, bus, pdev);
473 473
474 pci_lock_rescan_remove();
475
474 b = pci_scan_bus_parented(&pdev->xdev->dev, bus, 476 b = pci_scan_bus_parented(&pdev->xdev->dev, bus,
475 &pcifront_bus_ops, sd); 477 &pcifront_bus_ops, sd);
476 if (!b) { 478 if (!b) {
477 dev_err(&pdev->xdev->dev, 479 dev_err(&pdev->xdev->dev,
478 "Error creating PCI Frontend Bus!\n"); 480 "Error creating PCI Frontend Bus!\n");
479 err = -ENOMEM; 481 err = -ENOMEM;
482 pci_unlock_rescan_remove();
480 goto err_out; 483 goto err_out;
481 } 484 }
482 485
@@ -494,6 +497,7 @@ static int pcifront_scan_root(struct pcifront_device *pdev,
494 /* Create SysFS and notify udev of the devices. Aka: "going live" */ 497 /* Create SysFS and notify udev of the devices. Aka: "going live" */
495 pci_bus_add_devices(b); 498 pci_bus_add_devices(b);
496 499
500 pci_unlock_rescan_remove();
497 return err; 501 return err;
498 502
499err_out: 503err_out:
@@ -556,6 +560,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
556 560
557 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); 561 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n");
558 562
563 pci_lock_rescan_remove();
559 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { 564 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) {
560 list_del(&bus_entry->list); 565 list_del(&bus_entry->list);
561 566
@@ -568,6 +573,7 @@ static void pcifront_free_roots(struct pcifront_device *pdev)
568 573
569 kfree(bus_entry); 574 kfree(bus_entry);
570 } 575 }
576 pci_unlock_rescan_remove();
571} 577}
572 578
573static pci_ers_result_t pcifront_common_process(int cmd, 579static pci_ers_result_t pcifront_common_process(int cmd,
@@ -1043,8 +1049,10 @@ static int pcifront_detach_devices(struct pcifront_device *pdev)
1043 domain, bus, slot, func); 1049 domain, bus, slot, func);
1044 continue; 1050 continue;
1045 } 1051 }
1052 pci_lock_rescan_remove();
1046 pci_stop_and_remove_bus_device(pci_dev); 1053 pci_stop_and_remove_bus_device(pci_dev);
1047 pci_dev_put(pci_dev); 1054 pci_dev_put(pci_dev);
1055 pci_unlock_rescan_remove();
1048 1056
1049 dev_dbg(&pdev->xdev->dev, 1057 dev_dbg(&pdev->xdev->dev,
1050 "PCI device %04x:%02x:%02x.%d removed.\n", 1058 "PCI device %04x:%02x:%02x.%d removed.\n",
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c
index b2a98cdbd0d2..8bde61952d20 100644
--- a/drivers/pcmcia/cardbus.c
+++ b/drivers/pcmcia/cardbus.c
@@ -70,6 +70,8 @@ int __ref cb_alloc(struct pcmcia_socket *s)
70 struct pci_dev *dev; 70 struct pci_dev *dev;
71 unsigned int max, pass; 71 unsigned int max, pass;
72 72
73 pci_lock_rescan_remove();
74
73 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); 75 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
74 pci_fixup_cardbus(bus); 76 pci_fixup_cardbus(bus);
75 77
@@ -93,6 +95,7 @@ int __ref cb_alloc(struct pcmcia_socket *s)
93 95
94 pci_bus_add_devices(bus); 96 pci_bus_add_devices(bus);
95 97
98 pci_unlock_rescan_remove();
96 return 0; 99 return 0;
97} 100}
98 101
@@ -115,6 +118,10 @@ void cb_free(struct pcmcia_socket *s)
115 if (!bus) 118 if (!bus)
116 return; 119 return;
117 120
121 pci_lock_rescan_remove();
122
118 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) 123 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list)
119 pci_stop_and_remove_bus_device(dev); 124 pci_stop_and_remove_bus_device(dev);
125
126 pci_unlock_rescan_remove();
120} 127}
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 19c313b056c3..6fe268f6af91 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -606,6 +606,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus)
606 mutex_unlock(&asus->wmi_lock); 606 mutex_unlock(&asus->wmi_lock);
607 607
608 mutex_lock(&asus->hotplug_lock); 608 mutex_lock(&asus->hotplug_lock);
609 pci_lock_rescan_remove();
609 610
610 if (asus->wlan.rfkill) 611 if (asus->wlan.rfkill)
611 rfkill_set_sw_state(asus->wlan.rfkill, blocked); 612 rfkill_set_sw_state(asus->wlan.rfkill, blocked);
@@ -656,6 +657,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus)
656 } 657 }
657 658
658out_unlock: 659out_unlock:
660 pci_unlock_rescan_remove();
659 mutex_unlock(&asus->hotplug_lock); 661 mutex_unlock(&asus->hotplug_lock);
660} 662}
661 663
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index aefcc32e5634..538521b00948 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -592,6 +592,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle)
592 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked); 592 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
593 593
594 mutex_lock(&eeepc->hotplug_lock); 594 mutex_lock(&eeepc->hotplug_lock);
595 pci_lock_rescan_remove();
595 596
596 if (eeepc->hotplug_slot) { 597 if (eeepc->hotplug_slot) {
597 port = acpi_get_pci_dev(handle); 598 port = acpi_get_pci_dev(handle);
@@ -649,6 +650,7 @@ out_put_dev:
649 } 650 }
650 651
651out_unlock: 652out_unlock:
653 pci_unlock_rescan_remove();
652 mutex_unlock(&eeepc->hotplug_lock); 654 mutex_unlock(&eeepc->hotplug_lock);
653} 655}
654 656
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 3901edc35812..bde63f7452bd 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -128,7 +128,7 @@ static int mpt2sas_remove_dead_ioc_func(void *arg)
128 pdev = ioc->pdev; 128 pdev = ioc->pdev;
129 if ((pdev == NULL)) 129 if ((pdev == NULL))
130 return -1; 130 return -1;
131 pci_stop_and_remove_bus_device(pdev); 131 pci_stop_and_remove_bus_device_locked(pdev);
132 return 0; 132 return 0;
133} 133}
134 134
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index fa785062e97b..0cf4f7000f94 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -131,7 +131,7 @@ static int mpt3sas_remove_dead_ioc_func(void *arg)
131 pdev = ioc->pdev; 131 pdev = ioc->pdev;
132 if ((pdev == NULL)) 132 if ((pdev == NULL))
133 return -1; 133 return -1;
134 pci_stop_and_remove_bus_device(pdev); 134 pci_stop_and_remove_bus_device_locked(pdev);
135 return 0; 135 return 0;
136} 136}
137 137
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9e3ec8b951b7..2087e6b35545 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -775,6 +775,7 @@ struct pci_dev *pci_dev_get(struct pci_dev *dev);
775void pci_dev_put(struct pci_dev *dev); 775void pci_dev_put(struct pci_dev *dev);
776void pci_remove_bus(struct pci_bus *b); 776void pci_remove_bus(struct pci_bus *b);
777void pci_stop_and_remove_bus_device(struct pci_dev *dev); 777void pci_stop_and_remove_bus_device(struct pci_dev *dev);
778void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev);
778void pci_stop_root_bus(struct pci_bus *bus); 779void pci_stop_root_bus(struct pci_bus *bus);
779void pci_remove_root_bus(struct pci_bus *bus); 780void pci_remove_root_bus(struct pci_bus *bus);
780void pci_setup_cardbus(struct pci_bus *bus); 781void pci_setup_cardbus(struct pci_bus *bus);
@@ -1011,6 +1012,8 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev);
1011int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); 1012int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
1012unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge); 1013unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
1013unsigned int pci_rescan_bus(struct pci_bus *bus); 1014unsigned int pci_rescan_bus(struct pci_bus *bus);
1015void pci_lock_rescan_remove(void);
1016void pci_unlock_rescan_remove(void);
1014 1017
1015/* Vital product data routines */ 1018/* Vital product data routines */
1016ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf); 1019ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);