Blame view
drivers/pci/remove.c
3.57 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
#include <linux/pci.h> #include <linux/module.h> |
7d715a6c1 PCI: add PCI Expr... |
3 |
#include <linux/pci-aspm.h> |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#include "pci.h" static void pci_free_resources(struct pci_dev *dev) { int i; msi_remove_pci_irq_vectors(dev); pci_cleanup_rom(dev); for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *res = dev->resource + i; if (res->parent) release_resource(res); } } |
24f8aa9b4 PCI: add pci_stop... |
19 |
static void pci_stop_dev(struct pci_dev *dev) |
1da177e4c Linux-2.6.12-rc2 |
20 |
{ |
8a1bc9013 PCI: add is_added... |
21 |
if (dev->is_added) { |
091ca9f06 [PATCH] acpi brid... |
22 23 24 |
pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); device_unregister(&dev->dev); |
8a1bc9013 PCI: add is_added... |
25 |
dev->is_added = 0; |
091ca9f06 [PATCH] acpi brid... |
26 |
} |
7d715a6c1 PCI: add PCI Expr... |
27 28 29 |
if (dev->bus->self) pcie_aspm_exit_link_state(dev); |
24f8aa9b4 PCI: add pci_stop... |
30 31 32 33 |
} static void pci_destroy_dev(struct pci_dev *dev) { |
1da177e4c Linux-2.6.12-rc2 |
34 35 |
/* Remove the device from the device lists, and prevent any further * list accesses from this device */ |
d71374daf [PATCH] PCI: fix ... |
36 |
down_write(&pci_bus_sem); |
1da177e4c Linux-2.6.12-rc2 |
37 |
list_del(&dev->bus_list); |
1da177e4c Linux-2.6.12-rc2 |
38 |
dev->bus_list.next = dev->bus_list.prev = NULL; |
d71374daf [PATCH] PCI: fix ... |
39 |
up_write(&pci_bus_sem); |
1da177e4c Linux-2.6.12-rc2 |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
pci_free_resources(dev); pci_dev_put(dev); } /** * pci_remove_device_safe - remove an unused hotplug device * @dev: the device to remove * * Delete the device structure from the device lists and * notify userspace (/sbin/hotplug), but only if the device * in question is not being used by a driver. * Returns 0 on success. */ |
54c762fe6 [PATCH] PCI: driv... |
54 |
#if 0 |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 |
int pci_remove_device_safe(struct pci_dev *dev) { if (pci_dev_driver(dev)) return -EBUSY; pci_destroy_dev(dev); return 0; } |
54c762fe6 [PATCH] PCI: driv... |
62 |
#endif /* 0 */ |
1da177e4c Linux-2.6.12-rc2 |
63 64 65 66 |
void pci_remove_bus(struct pci_bus *pci_bus) { pci_proc_detach_bus(pci_bus); |
d71374daf [PATCH] PCI: fix ... |
67 |
down_write(&pci_bus_sem); |
1da177e4c Linux-2.6.12-rc2 |
68 |
list_del(&pci_bus->node); |
d71374daf [PATCH] PCI: fix ... |
69 |
up_write(&pci_bus_sem); |
2b5631344 PCI: check if a b... |
70 71 |
if (!pci_bus->is_added) return; |
1da177e4c Linux-2.6.12-rc2 |
72 |
pci_remove_legacy_files(pci_bus); |
fd7d1ced2 PCI: make pci_bus... |
73 |
device_unregister(&pci_bus->dev); |
1da177e4c Linux-2.6.12-rc2 |
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
} EXPORT_SYMBOL(pci_remove_bus); /** * pci_remove_bus_device - remove a PCI device and any children * @dev: the device to remove * * Remove a PCI device from the device lists, informing the drivers * that the device has been removed. We also remove any subordinate * buses and children in a depth-first manner. * * For each device we remove, delete the device structure from the * device lists, remove the /proc entry, and notify userspace * (/sbin/hotplug). */ |
79cc9601c PCI: Only call pc... |
89 |
static void __pci_remove_bus_device(struct pci_dev *dev) |
1da177e4c Linux-2.6.12-rc2 |
90 91 92 93 94 95 96 97 98 99 100 |
{ if (dev->subordinate) { struct pci_bus *b = dev->subordinate; pci_remove_behind_bridge(dev); pci_remove_bus(b); dev->subordinate = NULL; } pci_destroy_dev(dev); } |
79cc9601c PCI: Only call pc... |
101 102 103 104 105 |
void pci_remove_bus_device(struct pci_dev *dev) { pci_stop_bus_device(dev); __pci_remove_bus_device(dev); } |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 109 110 111 112 113 114 115 116 117 |
/** * pci_remove_behind_bridge - remove all devices behind a PCI bridge * @dev: PCI bridge device * * Remove all devices on the bus, except for the parent bridge. * This also removes any child buses, and any devices they may * contain in a depth-first manner. */ void pci_remove_behind_bridge(struct pci_dev *dev) { struct list_head *l, *n; |
11d587429 PCI: fix sparse w... |
118 119 |
if (dev->subordinate) list_for_each_safe(l, n, &dev->subordinate->devices) |
79cc9601c PCI: Only call pc... |
120 |
__pci_remove_bus_device(pci_dev_b(l)); |
1da177e4c Linux-2.6.12-rc2 |
121 |
} |
24f8aa9b4 PCI: add pci_stop... |
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
static void pci_stop_bus_devices(struct pci_bus *bus) { struct list_head *l, *n; list_for_each_safe(l, n, &bus->devices) { struct pci_dev *dev = pci_dev_b(l); pci_stop_bus_device(dev); } } /** * pci_stop_bus_device - stop a PCI device and any children * @dev: the device to stop * * Stop a PCI device (detach the driver, remove from the global list * and so on). This also stop any subordinate buses and children in a * depth-first manner. */ void pci_stop_bus_device(struct pci_dev *dev) { if (dev->subordinate) pci_stop_bus_devices(dev->subordinate); pci_stop_dev(dev); } |
1da177e4c Linux-2.6.12-rc2 |
147 148 |
EXPORT_SYMBOL(pci_remove_bus_device); EXPORT_SYMBOL(pci_remove_behind_bridge); |
24f8aa9b4 PCI: add pci_stop... |
149 |
EXPORT_SYMBOL_GPL(pci_stop_bus_device); |