aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
9 files changed, 83 insertions, 19 deletions
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