Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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()

+209 -44
+16 -3
arch/powerpc/kernel/eeh_driver.c
··· 369 369 edev->mode |= EEH_DEV_DISCONNECTED; 370 370 (*removed)++; 371 371 372 + pci_lock_rescan_remove(); 372 373 pci_stop_and_remove_bus_device(dev); 374 + pci_unlock_rescan_remove(); 373 375 374 376 return NULL; 375 377 } ··· 418 416 * into pcibios_add_pci_devices(). 419 417 */ 420 418 eeh_pe_state_mark(pe, EEH_PE_KEEP); 421 - if (bus) 419 + if (bus) { 420 + pci_lock_rescan_remove(); 422 421 pcibios_remove_pci_devices(bus); 423 - else if (frozen_bus) 422 + pci_unlock_rescan_remove(); 423 + } else if (frozen_bus) { 424 424 eeh_pe_dev_traverse(pe, eeh_rmv_device, &removed); 425 + } 425 426 426 427 /* Reset the pci controller. (Asserts RST#; resets config space). 427 428 * Reconfigure bridges and devices. Don't try to bring the system ··· 433 428 rc = eeh_reset_pe(pe); 434 429 if (rc) 435 430 return rc; 431 + 432 + pci_lock_rescan_remove(); 436 433 437 434 /* Restore PE */ 438 435 eeh_ops->configure_bridge(pe); ··· 469 462 pe->tstamp = tstamp; 470 463 pe->freeze_count = cnt; 471 464 465 + pci_unlock_rescan_remove(); 472 466 return 0; 473 467 } 474 468 ··· 626 618 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 627 619 628 620 /* Shut down the device drivers for good. */ 629 - if (frozen_bus) 621 + if (frozen_bus) { 622 + pci_lock_rescan_remove(); 630 623 pcibios_remove_pci_devices(frozen_bus); 624 + pci_unlock_rescan_remove(); 625 + } 631 626 } 632 627 633 628 static void eeh_handle_special_event(void) ··· 703 692 if (rc == 2 || rc == 1) 704 693 eeh_handle_normal_event(pe); 705 694 else { 695 + pci_lock_rescan_remove(); 706 696 list_for_each_entry_safe(hose, tmp, 707 697 &hose_list, list_node) { 708 698 phb_pe = eeh_phb_pe_get(hose); ··· 715 703 eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); 716 704 pcibios_remove_pci_devices(bus); 717 705 } 706 + pci_unlock_rescan_remove(); 718 707 } 719 708 } 720 709
+6
drivers/acpi/pci_root.c
··· 596 596 pci_assign_unassigned_root_bus_resources(root->bus); 597 597 } 598 598 599 + pci_lock_rescan_remove(); 599 600 pci_bus_add_devices(root->bus); 601 + pci_unlock_rescan_remove(); 600 602 return 1; 601 603 602 604 end: ··· 610 608 { 611 609 struct acpi_pci_root *root = acpi_driver_data(device); 612 610 611 + pci_lock_rescan_remove(); 612 + 613 613 pci_stop_root_bus(root->bus); 614 614 615 615 device_set_run_wake(root->bus->bridge, false); 616 616 pci_acpi_remove_bus_pm_notifier(device); 617 617 618 618 pci_remove_root_bus(root->bus); 619 + 620 + pci_unlock_rescan_remove(); 619 621 620 622 kfree(root); 621 623 }
+1 -1
drivers/message/fusion/mptbase.c
··· 346 346 if ((pdev == NULL)) 347 347 return -1; 348 348 349 - pci_stop_and_remove_bus_device(pdev); 349 + pci_stop_and_remove_bus_device_locked(pdev); 350 350 return 0; 351 351 } 352 352
+4 -1
drivers/pci/hotplug/acpiphp.h
··· 77 77 78 78 /* PCI-to-PCI bridge device */ 79 79 struct pci_dev *pci_dev; 80 + 81 + bool is_going_away; 80 82 }; 81 83 82 84 ··· 152 150 /* slot flags */ 153 151 154 152 #define SLOT_ENABLED (0x00000001) 153 + #define SLOT_IS_GOING_AWAY (0x00000002) 155 154 156 155 /* function flags */ 157 156 ··· 172 169 typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); 173 170 174 171 int acpiphp_enable_slot(struct acpiphp_slot *slot); 175 - int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); 172 + int acpiphp_disable_slot(struct acpiphp_slot *slot); 176 173 u8 acpiphp_get_power_status(struct acpiphp_slot *slot); 177 174 u8 acpiphp_get_attention_status(struct acpiphp_slot *slot); 178 175 u8 acpiphp_get_latch_status(struct acpiphp_slot *slot);
+1 -1
drivers/pci/hotplug/acpiphp_core.c
··· 156 156 pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); 157 157 158 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
+38 -5
drivers/pci/hotplug/acpiphp_glue.c
··· 430 430 pr_err("failed to remove notify handler\n"); 431 431 } 432 432 } 433 + slot->flags |= SLOT_IS_GOING_AWAY; 433 434 if (slot->slot) 434 435 acpiphp_unregister_hotplug_slot(slot); 435 436 } ··· 438 437 mutex_lock(&bridge_mutex); 439 438 list_del(&bridge->list); 440 439 mutex_unlock(&bridge_mutex); 440 + 441 + bridge->is_going_away = true; 441 442 } 442 443 443 444 /** ··· 739 736 { 740 737 struct acpiphp_slot *slot; 741 738 739 + /* Bail out if the bridge is going away. */ 740 + if (bridge->is_going_away) 741 + return; 742 + 742 743 list_for_each_entry(slot, &bridge->slots, node) { 743 744 struct pci_bus *bus = slot->bus; 744 745 struct pci_dev *dev, *tmp; ··· 812 805 } 813 806 } 814 807 808 + static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot); 809 + 815 810 static void hotplug_event(acpi_handle handle, u32 type, void *data) 816 811 { 817 812 struct acpiphp_context *context = data; ··· 843 834 } else { 844 835 struct acpiphp_slot *slot = func->slot; 845 836 837 + if (slot->flags & SLOT_IS_GOING_AWAY) 838 + break; 839 + 846 840 mutex_lock(&slot->crit_sect); 847 841 enable_slot(slot); 848 842 mutex_unlock(&slot->crit_sect); ··· 860 848 } else { 861 849 struct acpiphp_slot *slot = func->slot; 862 850 int ret; 851 + 852 + if (slot->flags & SLOT_IS_GOING_AWAY) 853 + break; 863 854 864 855 /* 865 856 * Check if anything has changed in the slot and rescan ··· 893 878 acpi_handle handle = context->handle; 894 879 895 880 acpi_scan_lock_acquire(); 881 + pci_lock_rescan_remove(); 896 882 897 883 hotplug_event(handle, type, context); 898 884 885 + pci_unlock_rescan_remove(); 899 886 acpi_scan_lock_release(); 900 887 acpi_evaluate_hotplug_ost(handle, type, ACPI_OST_SC_SUCCESS, NULL); 901 888 put_bridge(context->func.parent); ··· 1065 1048 */ 1066 1049 int acpiphp_enable_slot(struct acpiphp_slot *slot) 1067 1050 { 1051 + pci_lock_rescan_remove(); 1052 + 1053 + if (slot->flags & SLOT_IS_GOING_AWAY) 1054 + return -ENODEV; 1055 + 1068 1056 mutex_lock(&slot->crit_sect); 1069 1057 /* configure all functions */ 1070 1058 if (!(slot->flags & SLOT_ENABLED)) 1071 1059 enable_slot(slot); 1072 1060 1073 1061 mutex_unlock(&slot->crit_sect); 1062 + 1063 + pci_unlock_rescan_remove(); 1074 1064 return 0; 1075 1065 } 1076 1066 ··· 1085 1061 * acpiphp_disable_and_eject_slot - power off and eject slot 1086 1062 * @slot: ACPI PHP slot 1087 1063 */ 1088 - int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) 1064 + static int acpiphp_disable_and_eject_slot(struct acpiphp_slot *slot) 1089 1065 { 1090 1066 struct acpiphp_func *func; 1091 - int retval = 0; 1067 + 1068 + if (slot->flags & SLOT_IS_GOING_AWAY) 1069 + return -ENODEV; 1092 1070 1093 1071 mutex_lock(&slot->crit_sect); 1094 1072 ··· 1108 1082 } 1109 1083 1110 1084 mutex_unlock(&slot->crit_sect); 1111 - return retval; 1085 + return 0; 1112 1086 } 1113 1087 1088 + int acpiphp_disable_slot(struct acpiphp_slot *slot) 1089 + { 1090 + int ret; 1091 + 1092 + pci_lock_rescan_remove(); 1093 + ret = acpiphp_disable_and_eject_slot(slot); 1094 + pci_unlock_rescan_remove(); 1095 + return ret; 1096 + } 1114 1097 1115 1098 /* 1116 1099 * slot enabled: 1 ··· 1130 1095 return (slot->flags & SLOT_ENABLED); 1131 1096 } 1132 1097 1133 - 1134 1098 /* 1135 1099 * latch open: 1 1136 1100 * latch closed: 0 ··· 1138 1104 { 1139 1105 return !(get_slot_status(slot) & ACPI_STA_DEVICE_UI); 1140 1106 } 1141 - 1142 1107 1143 1108 /* 1144 1109 * adapter presence : 1
+12 -2
drivers/pci/hotplug/cpci_hotplug_pci.c
··· 254 254 { 255 255 struct pci_dev *dev; 256 256 struct pci_bus *parent; 257 + int ret = 0; 257 258 258 259 dbg("%s - enter", __func__); 260 + 261 + pci_lock_rescan_remove(); 259 262 260 263 if (slot->dev == NULL) { 261 264 dbg("pci_dev null, finding %02x:%02x:%x", ··· 280 277 slot->dev = pci_get_slot(slot->bus, slot->devfn); 281 278 if (slot->dev == NULL) { 282 279 err("Could not find PCI device for slot %02x", slot->number); 283 - return -ENODEV; 280 + ret = -ENODEV; 281 + goto out; 284 282 } 285 283 } 286 284 parent = slot->dev->bus; ··· 298 294 299 295 pci_bus_add_devices(parent); 300 296 297 + out: 298 + pci_unlock_rescan_remove(); 301 299 dbg("%s - exit", __func__); 302 - return 0; 300 + return ret; 303 301 } 304 302 305 303 int cpci_unconfigure_slot(struct slot* slot) ··· 314 308 return -ENODEV; 315 309 } 316 310 311 + pci_lock_rescan_remove(); 312 + 317 313 list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { 318 314 if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) 319 315 continue; ··· 325 317 } 326 318 pci_dev_put(slot->dev); 327 319 slot->dev = NULL; 320 + 321 + pci_unlock_rescan_remove(); 328 322 329 323 dbg("%s - exit", __func__); 330 324 return 0;
+7 -1
drivers/pci/hotplug/cpqphp_pci.c
··· 86 86 struct pci_bus *child; 87 87 int num; 88 88 89 + pci_lock_rescan_remove(); 90 + 89 91 if (func->pci_dev == NULL) 90 92 func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function)); 91 93 ··· 102 100 func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function)); 103 101 if (func->pci_dev == NULL) { 104 102 dbg("ERROR: pci_dev still null\n"); 105 - return 0; 103 + goto out; 106 104 } 107 105 } 108 106 ··· 115 113 116 114 pci_dev_put(func->pci_dev); 117 115 116 + out: 117 + pci_unlock_rescan_remove(); 118 118 return 0; 119 119 } 120 120 ··· 127 123 128 124 dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); 129 125 126 + pci_lock_rescan_remove(); 130 127 for (j=0; j<8 ; j++) { 131 128 struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); 132 129 if (temp) { ··· 135 130 pci_stop_and_remove_bus_device(temp); 136 131 } 137 132 } 133 + pci_unlock_rescan_remove(); 138 134 return 0; 139 135 } 140 136
+11 -2
drivers/pci/hotplug/ibmphp_core.c
··· 718 718 func->device, func->function); 719 719 debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0); 720 720 721 + pci_lock_rescan_remove(); 722 + 721 723 for (j = 0; j < 0x08; j++) { 722 724 temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); 723 725 if (temp) { ··· 727 725 pci_dev_put(temp); 728 726 } 729 727 } 728 + 730 729 pci_dev_put(func->dev); 730 + 731 + pci_unlock_rescan_remove(); 731 732 } 732 733 733 734 /* ··· 785 780 int flag = 0; /* this is to make sure we don't double scan the bus, 786 781 for bridged devices primarily */ 787 782 783 + pci_lock_rescan_remove(); 784 + 788 785 if (!(bus_structure_fixup(func->busno))) 789 786 flag = 1; 790 787 if (func->dev == NULL) ··· 796 789 if (func->dev == NULL) { 797 790 struct pci_bus *bus = pci_find_bus(0, func->busno); 798 791 if (!bus) 799 - return 0; 792 + goto out; 800 793 801 794 num = pci_scan_slot(bus, 802 795 PCI_DEVFN(func->device, func->function)); ··· 807 800 PCI_DEVFN(func->device, func->function)); 808 801 if (func->dev == NULL) { 809 802 err("ERROR... : pci_dev still NULL\n"); 810 - return 0; 803 + goto out; 811 804 } 812 805 } 813 806 if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { ··· 817 810 pci_bus_add_devices(child); 818 811 } 819 812 813 + out: 814 + pci_unlock_rescan_remove(); 820 815 return 0; 821 816 } 822 817
+13 -4
drivers/pci/hotplug/pciehp_pci.c
··· 39 39 struct pci_dev *dev; 40 40 struct pci_dev *bridge = p_slot->ctrl->pcie->port; 41 41 struct pci_bus *parent = bridge->subordinate; 42 - int num; 42 + int num, ret = 0; 43 43 struct controller *ctrl = p_slot->ctrl; 44 + 45 + pci_lock_rescan_remove(); 44 46 45 47 dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); 46 48 if (dev) { ··· 50 48 "at %04x:%02x:00, cannot hot-add\n", pci_name(dev), 51 49 pci_domain_nr(parent), parent->number); 52 50 pci_dev_put(dev); 53 - return -EINVAL; 51 + ret = -EINVAL; 52 + goto out; 54 53 } 55 54 56 55 num = pci_scan_slot(parent, PCI_DEVFN(0, 0)); 57 56 if (num == 0) { 58 57 ctrl_err(ctrl, "No new device found\n"); 59 - return -ENODEV; 58 + ret = -ENODEV; 59 + goto out; 60 60 } 61 61 62 62 list_for_each_entry(dev, &parent->devices, bus_list) ··· 77 73 78 74 pci_bus_add_devices(parent); 79 75 80 - return 0; 76 + out: 77 + pci_unlock_rescan_remove(); 78 + return ret; 81 79 } 82 80 83 81 int pciehp_unconfigure_device(struct slot *p_slot) ··· 95 89 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:00\n", 96 90 __func__, pci_domain_nr(parent), parent->number); 97 91 pciehp_get_adapter_status(p_slot, &presence); 92 + 93 + pci_lock_rescan_remove(); 98 94 99 95 /* 100 96 * Stopping an SR-IOV PF device removes all the associated VFs, ··· 132 124 pci_dev_put(dev); 133 125 } 134 126 127 + pci_unlock_rescan_remove(); 135 128 return rc; 136 129 }
+14 -5
drivers/pci/hotplug/rpadlpar_core.c
··· 354 354 { 355 355 struct pci_bus *bus; 356 356 struct slot *slot; 357 + int ret = 0; 358 + 359 + pci_lock_rescan_remove(); 357 360 358 361 bus = pcibios_find_pci_bus(dn); 359 - if (!bus) 360 - return -EINVAL; 362 + if (!bus) { 363 + ret = -EINVAL; 364 + goto out; 365 + } 361 366 362 367 pr_debug("PCI: Removing PCI slot below EADS bridge %s\n", 363 368 bus->self ? pci_name(bus->self) : "<!PHB!>"); ··· 376 371 printk(KERN_ERR 377 372 "%s: unable to remove hotplug slot %s\n", 378 373 __func__, drc_name); 379 - return -EIO; 374 + ret = -EIO; 375 + goto out; 380 376 } 381 377 } 382 378 ··· 388 382 if (pcibios_unmap_io_space(bus)) { 389 383 printk(KERN_ERR "%s: failed to unmap bus range\n", 390 384 __func__); 391 - return -ERANGE; 385 + ret = -ERANGE; 386 + goto out; 392 387 } 393 388 394 389 /* Remove the EADS bridge device itself */ ··· 397 390 pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); 398 391 pci_stop_and_remove_bus_device(bus->self); 399 392 400 - return 0; 393 + out: 394 + pci_unlock_rescan_remove(); 395 + return ret; 401 396 } 402 397 403 398 /**
+4
drivers/pci/hotplug/rpaphp_core.c
··· 398 398 return retval; 399 399 400 400 if (state == PRESENT) { 401 + pci_lock_rescan_remove(); 401 402 pcibios_add_pci_devices(slot->bus); 403 + pci_unlock_rescan_remove(); 402 404 slot->state = CONFIGURED; 403 405 } else if (state == EMPTY) { 404 406 slot->state = EMPTY; ··· 420 418 if (slot->state == NOT_CONFIGURED) 421 419 return -EINVAL; 422 420 421 + pci_lock_rescan_remove(); 423 422 pcibios_remove_pci_devices(slot->bus); 423 + pci_unlock_rescan_remove(); 424 424 vm_unmap_aliases(); 425 425 426 426 slot->state = NOT_CONFIGURED;
+3 -1
drivers/pci/hotplug/s390_pci_hpc.c
··· 80 80 goto out_deconfigure; 81 81 82 82 pci_scan_slot(slot->zdev->bus, ZPCI_DEVFN); 83 + pci_lock_rescan_remove(); 83 84 pci_bus_add_devices(slot->zdev->bus); 85 + pci_unlock_rescan_remove(); 84 86 85 87 return rc; 86 88 ··· 100 98 return -EIO; 101 99 102 100 if (slot->zdev->pdev) 103 - pci_stop_and_remove_bus_device(slot->zdev->pdev); 101 + pci_stop_and_remove_bus_device_locked(slot->zdev->pdev); 104 102 105 103 rc = zpci_disable_device(slot->zdev); 106 104 if (rc)
+5
drivers/pci/hotplug/sgi_hotplug.c
··· 459 459 acpi_scan_lock_release(); 460 460 } 461 461 462 + pci_lock_rescan_remove(); 463 + 462 464 /* Call the driver for the new device */ 463 465 pci_bus_add_devices(slot->pci_bus); 464 466 /* Call the drivers for the new devices subordinate to PPB */ 465 467 if (new_ppb) 466 468 pci_bus_add_devices(new_bus); 467 469 470 + pci_unlock_rescan_remove(); 468 471 mutex_unlock(&sn_hotplug_mutex); 469 472 470 473 if (rc == 0) ··· 543 540 acpi_scan_lock_release(); 544 541 } 545 542 543 + pci_lock_rescan_remove(); 546 544 /* Free the SN resources assigned to the Linux device.*/ 547 545 list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { 548 546 if (PCI_SLOT(dev->devfn) != slot->device_num + 1) ··· 554 550 pci_stop_and_remove_bus_device(dev); 555 551 pci_dev_put(dev); 556 552 } 553 + pci_unlock_rescan_remove(); 557 554 558 555 /* Remove the SSDT for the slot from the ACPI namespace */ 559 556 if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {
+14 -4
drivers/pci/hotplug/shpchp_pci.c
··· 40 40 struct controller *ctrl = p_slot->ctrl; 41 41 struct pci_dev *bridge = ctrl->pci_dev; 42 42 struct pci_bus *parent = bridge->subordinate; 43 - int num; 43 + int num, ret = 0; 44 + 45 + pci_lock_rescan_remove(); 44 46 45 47 dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); 46 48 if (dev) { ··· 50 48 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev), 51 49 pci_domain_nr(parent), p_slot->bus, p_slot->device); 52 50 pci_dev_put(dev); 53 - return -EINVAL; 51 + ret = -EINVAL; 52 + goto out; 54 53 } 55 54 56 55 num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0)); 57 56 if (num == 0) { 58 57 ctrl_err(ctrl, "No new device found\n"); 59 - return -ENODEV; 58 + ret = -ENODEV; 59 + goto out; 60 60 } 61 61 62 62 list_for_each_entry(dev, &parent->devices, bus_list) { ··· 79 75 80 76 pci_bus_add_devices(parent); 81 77 82 - return 0; 78 + out: 79 + pci_unlock_rescan_remove(); 80 + return ret; 83 81 } 84 82 85 83 int shpchp_unconfigure_device(struct slot *p_slot) ··· 94 88 95 89 ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", 96 90 __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); 91 + 92 + pci_lock_rescan_remove(); 97 93 98 94 list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { 99 95 if (PCI_SLOT(dev->devfn) != p_slot->device) ··· 116 108 pci_stop_and_remove_bus_device(dev); 117 109 pci_dev_put(dev); 118 110 } 111 + 112 + pci_unlock_rescan_remove(); 119 113 return rc; 120 114 } 121 115
+7 -12
drivers/pci/pci-sysfs.c
··· 297 297 } 298 298 static DEVICE_ATTR_RW(msi_bus); 299 299 300 - static DEFINE_MUTEX(pci_remove_rescan_mutex); 301 300 static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, 302 301 size_t count) 303 302 { ··· 307 308 return -EINVAL; 308 309 309 310 if (val) { 310 - mutex_lock(&pci_remove_rescan_mutex); 311 + pci_lock_rescan_remove(); 311 312 while ((b = pci_find_next_bus(b)) != NULL) 312 313 pci_rescan_bus(b); 313 - mutex_unlock(&pci_remove_rescan_mutex); 314 + pci_unlock_rescan_remove(); 314 315 } 315 316 return count; 316 317 } ··· 341 342 return -EINVAL; 342 343 343 344 if (val) { 344 - mutex_lock(&pci_remove_rescan_mutex); 345 + pci_lock_rescan_remove(); 345 346 pci_rescan_bus(pdev->bus); 346 - mutex_unlock(&pci_remove_rescan_mutex); 347 + pci_unlock_rescan_remove(); 347 348 } 348 349 return count; 349 350 } ··· 353 354 354 355 static void remove_callback(struct device *dev) 355 356 { 356 - struct pci_dev *pdev = to_pci_dev(dev); 357 - 358 - mutex_lock(&pci_remove_rescan_mutex); 359 - pci_stop_and_remove_bus_device(pdev); 360 - mutex_unlock(&pci_remove_rescan_mutex); 357 + pci_stop_and_remove_bus_device_locked(to_pci_dev(dev)); 361 358 } 362 359 363 360 static ssize_t ··· 390 395 return -EINVAL; 391 396 392 397 if (val) { 393 - mutex_lock(&pci_remove_rescan_mutex); 398 + pci_lock_rescan_remove(); 394 399 if (!pci_is_root_bus(bus) && list_empty(&bus->devices)) 395 400 pci_rescan_bus_bridge_resize(bus->self); 396 401 else 397 402 pci_rescan_bus(bus); 398 - mutex_unlock(&pci_remove_rescan_mutex); 403 + pci_unlock_rescan_remove(); 399 404 } 400 405 return count; 401 406 }
+18
drivers/pci/probe.c
··· 2024 2024 EXPORT_SYMBOL(pci_scan_bridge); 2025 2025 EXPORT_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 + */ 2031 + static DEFINE_MUTEX(pci_rescan_remove_lock); 2032 + 2033 + void pci_lock_rescan_remove(void) 2034 + { 2035 + mutex_lock(&pci_rescan_remove_lock); 2036 + } 2037 + EXPORT_SYMBOL_GPL(pci_lock_rescan_remove); 2038 + 2039 + void pci_unlock_rescan_remove(void) 2040 + { 2041 + mutex_unlock(&pci_rescan_remove_lock); 2042 + } 2043 + EXPORT_SYMBOL_GPL(pci_unlock_rescan_remove); 2044 + 2027 2045 static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b) 2028 2046 { 2029 2047 const struct pci_dev *a = to_pci_dev(d_a);
+11
drivers/pci/remove.c
··· 20 20 21 21 static void pci_destroy_dev(struct pci_dev *dev) 22 22 { 23 + if (!dev->dev.kobj.parent) 24 + return; 25 + 23 26 device_del(&dev->dev); 24 27 25 28 put_device(&dev->dev); ··· 97 94 pci_remove_bus_device(dev); 98 95 } 99 96 EXPORT_SYMBOL(pci_stop_and_remove_bus_device); 97 + 98 + void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev) 99 + { 100 + pci_lock_rescan_remove(); 101 + pci_stop_and_remove_bus_device(dev); 102 + pci_unlock_rescan_remove(); 103 + } 104 + EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked); 100 105 101 106 void pci_stop_root_bus(struct pci_bus *bus) 102 107 {
+8
drivers/pci/xen-pcifront.c
··· 471 471 } 472 472 pcifront_init_sd(sd, domain, bus, pdev); 473 473 474 + pci_lock_rescan_remove(); 475 + 474 476 b = pci_scan_bus_parented(&pdev->xdev->dev, bus, 475 477 &pcifront_bus_ops, sd); 476 478 if (!b) { 477 479 dev_err(&pdev->xdev->dev, 478 480 "Error creating PCI Frontend Bus!\n"); 479 481 err = -ENOMEM; 482 + pci_unlock_rescan_remove(); 480 483 goto err_out; 481 484 } 482 485 ··· 497 494 /* Create SysFS and notify udev of the devices. Aka: "going live" */ 498 495 pci_bus_add_devices(b); 499 496 497 + pci_unlock_rescan_remove(); 500 498 return err; 501 499 502 500 err_out: ··· 560 556 561 557 dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); 562 558 559 + pci_lock_rescan_remove(); 563 560 list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { 564 561 list_del(&bus_entry->list); 565 562 ··· 573 568 574 569 kfree(bus_entry); 575 570 } 571 + pci_unlock_rescan_remove(); 576 572 } 577 573 578 574 static pci_ers_result_t pcifront_common_process(int cmd, ··· 1049 1043 domain, bus, slot, func); 1050 1044 continue; 1051 1045 } 1046 + pci_lock_rescan_remove(); 1052 1047 pci_stop_and_remove_bus_device(pci_dev); 1053 1048 pci_dev_put(pci_dev); 1049 + pci_unlock_rescan_remove(); 1054 1050 1055 1051 dev_dbg(&pdev->xdev->dev, 1056 1052 "PCI device %04x:%02x:%02x.%d removed.\n",
+7
drivers/pcmcia/cardbus.c
··· 70 70 struct pci_dev *dev; 71 71 unsigned int max, pass; 72 72 73 + pci_lock_rescan_remove(); 74 + 73 75 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); 74 76 pci_fixup_cardbus(bus); 75 77 ··· 95 93 96 94 pci_bus_add_devices(bus); 97 95 96 + pci_unlock_rescan_remove(); 98 97 return 0; 99 98 } 100 99 ··· 118 115 if (!bus) 119 116 return; 120 117 118 + pci_lock_rescan_remove(); 119 + 121 120 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) 122 121 pci_stop_and_remove_bus_device(dev); 122 + 123 + pci_unlock_rescan_remove(); 123 124 }
+2
drivers/platform/x86/asus-wmi.c
··· 606 606 mutex_unlock(&asus->wmi_lock); 607 607 608 608 mutex_lock(&asus->hotplug_lock); 609 + pci_lock_rescan_remove(); 609 610 610 611 if (asus->wlan.rfkill) 611 612 rfkill_set_sw_state(asus->wlan.rfkill, blocked); ··· 657 656 } 658 657 659 658 out_unlock: 659 + pci_unlock_rescan_remove(); 660 660 mutex_unlock(&asus->hotplug_lock); 661 661 } 662 662
+2
drivers/platform/x86/eeepc-laptop.c
··· 592 592 rfkill_set_sw_state(eeepc->wlan_rfkill, blocked); 593 593 594 594 mutex_lock(&eeepc->hotplug_lock); 595 + pci_lock_rescan_remove(); 595 596 596 597 if (eeepc->hotplug_slot) { 597 598 port = acpi_get_pci_dev(handle); ··· 650 649 } 651 650 652 651 out_unlock: 652 + pci_unlock_rescan_remove(); 653 653 mutex_unlock(&eeepc->hotplug_lock); 654 654 } 655 655
+1 -1
drivers/scsi/mpt2sas/mpt2sas_base.c
··· 128 128 pdev = ioc->pdev; 129 129 if ((pdev == NULL)) 130 130 return -1; 131 - pci_stop_and_remove_bus_device(pdev); 131 + pci_stop_and_remove_bus_device_locked(pdev); 132 132 return 0; 133 133 } 134 134
+1 -1
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 131 131 pdev = ioc->pdev; 132 132 if ((pdev == NULL)) 133 133 return -1; 134 - pci_stop_and_remove_bus_device(pdev); 134 + pci_stop_and_remove_bus_device_locked(pdev); 135 135 return 0; 136 136 } 137 137
+3
include/linux/pci.h
··· 775 775 void pci_dev_put(struct pci_dev *dev); 776 776 void pci_remove_bus(struct pci_bus *b); 777 777 void pci_stop_and_remove_bus_device(struct pci_dev *dev); 778 + void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev); 778 779 void pci_stop_root_bus(struct pci_bus *bus); 779 780 void pci_remove_root_bus(struct pci_bus *bus); 780 781 void pci_setup_cardbus(struct pci_bus *bus); ··· 1012 1011 int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); 1013 1012 unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge); 1014 1013 unsigned int pci_rescan_bus(struct pci_bus *bus); 1014 + void pci_lock_rescan_remove(void); 1015 + void pci_unlock_rescan_remove(void); 1015 1016 1016 1017 /* Vital product data routines */ 1017 1018 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);