diff options
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 14 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_pci.c | 8 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 13 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 17 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpadlpar_core.c | 19 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_core.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/s390_pci_hpc.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 5 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_pci.c | 18 |
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 | ||
301 | int cpci_unconfigure_slot(struct slot* slot) | 307 | int 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 | ||
79 | int pciehp_unconfigure_device(struct slot *p_slot) | 85 | int 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 | ||
81 | int shpchp_unconfigure_device(struct slot *p_slot) | 87 | int 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 | ||