diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2014-01-15 12:53:23 -0500 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-01-15 12:53:23 -0500 |
| commit | 40304618468cae5259f77c15511e4feb7bfb624b (patch) | |
| tree | 19666e52586c98484a3bf8f1b19c28103feb9006 | |
| parent | 1255dfbb0c77c7a26fec10a5c101b075c3641965 (diff) | |
| parent | 8a4c5c329de716996eea03d93753ccbb5406072b (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()
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 | ||
| 625 | static void eeh_handle_special_event(void) | 636 | static 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 | ||
| 602 | end: | 604 | end: |
| @@ -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 | |||
