diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-21 12:57:20 -0400 | 
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-09-21 12:57:20 -0400 | 
| commit | 168ae6a08aa6e0cf8b0166dedeb675a20af1fbb7 (patch) | |
| tree | 31f19d4d3ca748c526e0bb82a670613c6c71ca40 /drivers/pci/remove.c | |
| parent | 9b9a6d261616bed589302bc6244c5bd7c99a733f (diff) | |
| parent | 3891b6acb4f443cbe2e99367ee5e67c6bc29d446 (diff) | |
Merge branch 'pci/yinghai-revert-pci_find_bus-and-remove-cleanup' into next
* pci/yinghai-revert-pci_find_bus-and-remove-cleanup:
  PCI: Stop all children first, before removing all children
  Revert "PCI: Use hotplug-safe pci_get_domain_bus_and_slot()"
Diffstat (limited to 'drivers/pci/remove.c')
| -rw-r--r-- | drivers/pci/remove.c | 51 | 
1 files changed, 35 insertions, 16 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 4f9ca9162895..513972f3ed13 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c  | |||
| @@ -56,25 +56,13 @@ void pci_remove_bus(struct pci_bus *bus) | |||
| 56 | } | 56 | } | 
| 57 | EXPORT_SYMBOL(pci_remove_bus); | 57 | EXPORT_SYMBOL(pci_remove_bus); | 
| 58 | 58 | ||
| 59 | /** | 59 | static void pci_stop_bus_device(struct pci_dev *dev) | 
| 60 | * pci_stop_and_remove_bus_device - remove a PCI device and any children | ||
| 61 | * @dev: the device to remove | ||
| 62 | * | ||
| 63 | * Remove a PCI device from the device lists, informing the drivers | ||
| 64 | * that the device has been removed. We also remove any subordinate | ||
| 65 | * buses and children in a depth-first manner. | ||
| 66 | * | ||
| 67 | * For each device we remove, delete the device structure from the | ||
| 68 | * device lists, remove the /proc entry, and notify userspace | ||
| 69 | * (/sbin/hotplug). | ||
| 70 | */ | ||
| 71 | void pci_stop_and_remove_bus_device(struct pci_dev *dev) | ||
| 72 | { | 60 | { | 
| 73 | struct pci_bus *bus = dev->subordinate; | 61 | struct pci_bus *bus = dev->subordinate; | 
| 74 | struct pci_dev *child, *tmp; | 62 | struct pci_dev *child, *tmp; | 
| 75 | 63 | ||
| 76 | /* | 64 | /* | 
| 77 | * Removing an SR-IOV PF device removes all the associated VFs, | 65 | * Stopping an SR-IOV PF device removes all the associated VFs, | 
| 78 | * which will update the bus->devices list and confuse the | 66 | * which will update the bus->devices list and confuse the | 
| 79 | * iterator. Therefore, iterate in reverse so we remove the VFs | 67 | * iterator. Therefore, iterate in reverse so we remove the VFs | 
| 80 | * first, then the PF. | 68 | * first, then the PF. | 
| @@ -82,13 +70,44 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) | |||
| 82 | if (bus) { | 70 | if (bus) { | 
| 83 | list_for_each_entry_safe_reverse(child, tmp, | 71 | list_for_each_entry_safe_reverse(child, tmp, | 
| 84 | &bus->devices, bus_list) | 72 | &bus->devices, bus_list) | 
| 85 | pci_stop_and_remove_bus_device(child); | 73 | pci_stop_bus_device(child); | 
| 74 | } | ||
| 75 | |||
| 76 | pci_stop_dev(dev); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void pci_remove_bus_device(struct pci_dev *dev) | ||
| 80 | { | ||
| 81 | struct pci_bus *bus = dev->subordinate; | ||
| 82 | struct pci_dev *child, *tmp; | ||
| 83 | |||
| 84 | if (bus) { | ||
| 85 | list_for_each_entry_safe(child, tmp, | ||
| 86 | &bus->devices, bus_list) | ||
| 87 | pci_remove_bus_device(child); | ||
| 86 | 88 | ||
| 87 | pci_remove_bus(bus); | 89 | pci_remove_bus(bus); | 
| 88 | dev->subordinate = NULL; | 90 | dev->subordinate = NULL; | 
| 89 | } | 91 | } | 
| 90 | 92 | ||
| 91 | pci_stop_dev(dev); | ||
| 92 | pci_destroy_dev(dev); | 93 | pci_destroy_dev(dev); | 
| 93 | } | 94 | } | 
| 95 | |||
| 96 | /** | ||
| 97 | * pci_stop_and_remove_bus_device - remove a PCI device and any children | ||
| 98 | * @dev: the device to remove | ||
| 99 | * | ||
| 100 | * Remove a PCI device from the device lists, informing the drivers | ||
| 101 | * that the device has been removed. We also remove any subordinate | ||
| 102 | * buses and children in a depth-first manner. | ||
| 103 | * | ||
| 104 | * For each device we remove, delete the device structure from the | ||
| 105 | * device lists, remove the /proc entry, and notify userspace | ||
| 106 | * (/sbin/hotplug). | ||
| 107 | */ | ||
| 108 | void pci_stop_and_remove_bus_device(struct pci_dev *dev) | ||
| 109 | { | ||
| 110 | pci_stop_bus_device(dev); | ||
| 111 | pci_remove_bus_device(dev); | ||
| 112 | } | ||
| 94 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); | 113 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); | 
