forked from Minki/linux
Merge branch 'pci/bjorn-cleanup-remove' into next
* pci/bjorn-cleanup-remove: PCI: Remove unused pci_dev_b() sgi-agp: Use list_for_each_entry() for bus->devices traversal parisc/PCI: Use list_for_each_entry() for bus->devices traversal parisc/PCI: Enable PERR/SERR on all devices frv/PCI: Use list_for_each_entry() for bus->devices traversal PCI: Leave normal LIST_POISON in deleted list entries PCI: Rename local variables to conventional names PCI: Remove unused, commented-out, code PCI: Stop and remove devices in one pass PCI: Fold stop and remove helpers into their callers PCI: Use list_for_each_entry() for bus->devices traversal PCI: Remove pci_stop_and_remove_behind_bridge() PCI: Don't export stop_bus_device and remove_bus_device interfaces pcmcia: Use common pci_stop_and_remove_bus_device() PCI: acpiphp: Use common pci_stop_and_remove_bus_device() PCI: acpiphp: Stop disabling bridges on remove
This commit is contained in:
commit
7bf79d8a99
@ -330,10 +330,8 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
|
||||
pci_read_bridge_bases(bus);
|
||||
|
||||
if (bus->number == 0) {
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
|
||||
dev = pci_dev_b(ln);
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->devfn == 0) {
|
||||
dev->resource[0].start = 0;
|
||||
dev->resource[0].end = 0;
|
||||
|
@ -289,12 +289,11 @@ static int __devinit agp_sgi_init(void)
|
||||
|
||||
j = 0;
|
||||
list_for_each_entry(info, &tioca_list, ca_list) {
|
||||
struct list_head *tmp;
|
||||
if (list_empty(info->ca_devices))
|
||||
continue;
|
||||
list_for_each(tmp, info->ca_devices) {
|
||||
list_for_each_entry(pdev, info->ca_devices, bus_list) {
|
||||
u8 cap_ptr;
|
||||
pdev = pci_dev_b(tmp);
|
||||
|
||||
if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
|
||||
continue;
|
||||
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
|
||||
|
@ -477,14 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
|
||||
if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
|
||||
F_EXTEND(0xf0000000UL) | _8MB,
|
||||
F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) {
|
||||
struct list_head *ln, *tmp_ln;
|
||||
struct pci_dev *dev, *tmp;
|
||||
|
||||
printk(KERN_ERR "Dino: cannot attach bus %s\n",
|
||||
dev_name(bus->bridge));
|
||||
/* kill the bus, we can't do anything with it */
|
||||
list_for_each_safe(ln, tmp_ln, &bus->devices) {
|
||||
struct pci_dev *dev = pci_dev_b(ln);
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
|
||||
list_del(&dev->bus_list);
|
||||
}
|
||||
|
||||
@ -549,7 +547,6 @@ dino_card_fixup(struct pci_dev *dev)
|
||||
static void __init
|
||||
dino_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
|
||||
|
||||
@ -596,8 +593,7 @@ dino_fixup_bus(struct pci_bus *bus)
|
||||
}
|
||||
|
||||
|
||||
list_for_each(ln, &bus->devices) {
|
||||
dev = pci_dev_b(ln);
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (is_card_dino(&dino_dev->hba.dev->id))
|
||||
dino_card_fixup(dev);
|
||||
|
||||
|
@ -629,7 +629,7 @@ truncate_pat_collision(struct resource *root, struct resource *new)
|
||||
static void
|
||||
lba_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct list_head *ln;
|
||||
struct pci_dev *dev;
|
||||
#ifdef FBB_SUPPORT
|
||||
u16 status;
|
||||
#endif
|
||||
@ -710,9 +710,8 @@ lba_fixup_bus(struct pci_bus *bus)
|
||||
|
||||
}
|
||||
|
||||
list_for_each(ln, &bus->devices) {
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
int i;
|
||||
struct pci_dev *dev = pci_dev_b(ln);
|
||||
|
||||
DBG("lba_fixup_bus() %s\n", pci_name(dev));
|
||||
|
||||
@ -770,7 +769,7 @@ lba_fixup_bus(struct pci_bus *bus)
|
||||
}
|
||||
|
||||
/* Lastly enable FBB/PERR/SERR on all devices too */
|
||||
list_for_each(ln, &bus->devices) {
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
(void) pci_read_config_word(dev, PCI_COMMAND, &status);
|
||||
status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
|
||||
(void) pci_write_config_word(dev, PCI_COMMAND, status);
|
||||
|
@ -869,17 +869,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void disable_bridges(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->subordinate) {
|
||||
disable_bridges(dev->subordinate);
|
||||
pci_disable_device(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* return first device in slot, acquiring a reference on it */
|
||||
static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
|
||||
{
|
||||
@ -931,12 +920,7 @@ static int disable_device(struct acpiphp_slot *slot)
|
||||
* here.
|
||||
*/
|
||||
while ((pdev = dev_in_slot(slot))) {
|
||||
pci_stop_bus_device(pdev);
|
||||
if (pdev->subordinate) {
|
||||
disable_bridges(pdev->subordinate);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
__pci_remove_bus_device(pdev);
|
||||
pci_stop_and_remove_bus_device(pdev);
|
||||
pci_dev_put(pdev);
|
||||
}
|
||||
|
||||
@ -1477,34 +1461,6 @@ int __init acpiphp_get_num_slots(void)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* acpiphp_for_each_slot - call function for each slot
|
||||
* @fn: callback function
|
||||
* @data: context to be passed to callback function
|
||||
*/
|
||||
static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
|
||||
{
|
||||
struct list_head *node;
|
||||
struct acpiphp_bridge *bridge;
|
||||
struct acpiphp_slot *slot;
|
||||
int retval = 0;
|
||||
|
||||
list_for_each (node, &bridge_list) {
|
||||
bridge = (struct acpiphp_bridge *)node;
|
||||
for (slot = bridge->slots; slot; slot = slot->next) {
|
||||
retval = fn(slot, data);
|
||||
if (!retval)
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
err_exit:
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* acpiphp_enable_slot - power on slot
|
||||
* @slot: ACPI PHP slot
|
||||
|
@ -434,25 +434,6 @@ int pci_proc_detach_device(struct pci_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int pci_proc_attach_bus(struct pci_bus* bus)
|
||||
{
|
||||
struct proc_dir_entry *de = bus->procdir;
|
||||
|
||||
if (!proc_initialized)
|
||||
return -EACCES;
|
||||
|
||||
if (!de) {
|
||||
char name[16];
|
||||
sprintf(name, "%02x", bus->number);
|
||||
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
|
||||
if (!de)
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
int pci_proc_detach_bus(struct pci_bus* bus)
|
||||
{
|
||||
struct proc_dir_entry *de = bus->procdir;
|
||||
|
@ -32,53 +32,30 @@ static void pci_stop_dev(struct pci_dev *dev)
|
||||
|
||||
static void pci_destroy_dev(struct pci_dev *dev)
|
||||
{
|
||||
/* Remove the device from the device lists, and prevent any further
|
||||
* list accesses from this device */
|
||||
down_write(&pci_bus_sem);
|
||||
list_del(&dev->bus_list);
|
||||
dev->bus_list.next = dev->bus_list.prev = NULL;
|
||||
up_write(&pci_bus_sem);
|
||||
|
||||
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.
|
||||
*/
|
||||
#if 0
|
||||
int pci_remove_device_safe(struct pci_dev *dev)
|
||||
void pci_remove_bus(struct pci_bus *bus)
|
||||
{
|
||||
if (pci_dev_driver(dev))
|
||||
return -EBUSY;
|
||||
pci_destroy_dev(dev);
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
void pci_remove_bus(struct pci_bus *pci_bus)
|
||||
{
|
||||
pci_proc_detach_bus(pci_bus);
|
||||
pci_proc_detach_bus(bus);
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
list_del(&pci_bus->node);
|
||||
pci_bus_release_busn_res(pci_bus);
|
||||
list_del(&bus->node);
|
||||
pci_bus_release_busn_res(bus);
|
||||
up_write(&pci_bus_sem);
|
||||
if (!pci_bus->is_added)
|
||||
if (!bus->is_added)
|
||||
return;
|
||||
|
||||
pci_remove_legacy_files(pci_bus);
|
||||
device_unregister(&pci_bus->dev);
|
||||
pci_remove_legacy_files(bus);
|
||||
device_unregister(&bus->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(pci_remove_bus);
|
||||
|
||||
static void __pci_remove_behind_bridge(struct pci_dev *dev);
|
||||
/**
|
||||
* pci_stop_and_remove_bus_device - remove a PCI device and any children
|
||||
* @dev: the device to remove
|
||||
@ -91,93 +68,27 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev);
|
||||
* device lists, remove the /proc entry, and notify userspace
|
||||
* (/sbin/hotplug).
|
||||
*/
|
||||
void __pci_remove_bus_device(struct pci_dev *dev)
|
||||
void pci_stop_and_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
if (dev->subordinate) {
|
||||
struct pci_bus *b = dev->subordinate;
|
||||
struct pci_bus *bus = dev->subordinate;
|
||||
struct pci_dev *child, *tmp;
|
||||
|
||||
__pci_remove_behind_bridge(dev);
|
||||
pci_remove_bus(b);
|
||||
/*
|
||||
* Removing an SR-IOV PF device removes all the associated VFs,
|
||||
* which will update the bus->devices list and confuse the
|
||||
* iterator. Therefore, iterate in reverse so we remove the VFs
|
||||
* first, then the PF.
|
||||
*/
|
||||
if (bus) {
|
||||
list_for_each_entry_safe_reverse(child, tmp,
|
||||
&bus->devices, bus_list)
|
||||
pci_stop_and_remove_bus_device(child);
|
||||
|
||||
pci_remove_bus(bus);
|
||||
dev->subordinate = NULL;
|
||||
}
|
||||
|
||||
pci_stop_dev(dev);
|
||||
pci_destroy_dev(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(__pci_remove_bus_device);
|
||||
|
||||
void pci_stop_and_remove_bus_device(struct pci_dev *dev)
|
||||
{
|
||||
pci_stop_bus_device(dev);
|
||||
__pci_remove_bus_device(dev);
|
||||
}
|
||||
|
||||
static void __pci_remove_behind_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
if (dev->subordinate)
|
||||
list_for_each_safe(l, n, &dev->subordinate->devices)
|
||||
__pci_remove_bus_device(pci_dev_b(l));
|
||||
}
|
||||
|
||||
static void pci_stop_behind_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
if (dev->subordinate)
|
||||
list_for_each_safe(l, n, &dev->subordinate->devices)
|
||||
pci_stop_bus_device(pci_dev_b(l));
|
||||
}
|
||||
|
||||
/**
|
||||
* pci_stop_and_remove_behind_bridge - stop and 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_stop_and_remove_behind_bridge(struct pci_dev *dev)
|
||||
{
|
||||
pci_stop_behind_bridge(dev);
|
||||
__pci_remove_behind_bridge(dev);
|
||||
}
|
||||
|
||||
static void pci_stop_bus_devices(struct pci_bus *bus)
|
||||
{
|
||||
struct list_head *l, *n;
|
||||
|
||||
/*
|
||||
* VFs could be removed by pci_stop_and_remove_bus_device() in the
|
||||
* pci_stop_bus_devices() code path for PF.
|
||||
* aka, bus->devices get updated in the process.
|
||||
* but VFs are inserted after PFs when SRIOV is enabled for PF,
|
||||
* We can iterate the list backwards to get prev valid PF instead
|
||||
* of removed VF.
|
||||
*/
|
||||
list_for_each_prev_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);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
|
||||
EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge);
|
||||
EXPORT_SYMBOL_GPL(pci_stop_bus_device);
|
||||
|
@ -167,44 +167,6 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
|
||||
return rom;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
|
||||
* @pdev: pointer to pci device struct
|
||||
* @size: pointer to receive size of pci window over ROM
|
||||
*
|
||||
* Return: kernel virtual pointer to image of ROM
|
||||
*
|
||||
* Map a PCI ROM into kernel space. If ROM is boot video ROM,
|
||||
* the shadow BIOS copy will be returned instead of the
|
||||
* actual ROM.
|
||||
*/
|
||||
void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
void __iomem *rom;
|
||||
|
||||
rom = pci_map_rom(pdev, size);
|
||||
if (!rom)
|
||||
return NULL;
|
||||
|
||||
if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_SHADOW |
|
||||
IORESOURCE_ROM_BIOS_COPY))
|
||||
return rom;
|
||||
|
||||
res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
|
||||
if (!res->start)
|
||||
return rom;
|
||||
|
||||
res->end = res->start + *size;
|
||||
memcpy_fromio((void*)(unsigned long)res->start, rom, *size);
|
||||
pci_unmap_rom(pdev, rom);
|
||||
res->flags |= IORESOURCE_ROM_COPY;
|
||||
|
||||
return (void __iomem *)(unsigned long)res->start;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/**
|
||||
* pci_unmap_rom - unmap the ROM from kernel space
|
||||
* @pdev: pointer to pci device struct
|
||||
@ -226,27 +188,6 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
|
||||
pci_disable_rom(pdev);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* pci_remove_rom - disable the ROM and remove its sysfs attribute
|
||||
* @pdev: pointer to pci device struct
|
||||
*
|
||||
* Remove the rom file in sysfs and disable ROM decoding.
|
||||
*/
|
||||
void pci_remove_rom(struct pci_dev *pdev)
|
||||
{
|
||||
struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
|
||||
|
||||
if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
|
||||
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
|
||||
if (!(res->flags & (IORESOURCE_ROM_ENABLE |
|
||||
IORESOURCE_ROM_SHADOW |
|
||||
IORESOURCE_ROM_BIOS_COPY |
|
||||
IORESOURCE_ROM_COPY)))
|
||||
pci_disable_rom(pdev);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/**
|
||||
* pci_cleanup_rom - free the ROM copy created by pci_map_rom_copy
|
||||
* @pdev: pointer to pci device struct
|
||||
|
@ -130,16 +130,14 @@ pci_find_next_bus(const struct pci_bus *from)
|
||||
* decrement the reference count by calling pci_dev_put().
|
||||
* If no device is found, %NULL is returned.
|
||||
*/
|
||||
struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn)
|
||||
struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
struct pci_dev *dev;
|
||||
|
||||
WARN_ON(in_interrupt());
|
||||
down_read(&pci_bus_sem);
|
||||
|
||||
list_for_each(tmp, &bus->devices) {
|
||||
dev = pci_dev_b(tmp);
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
if (dev->devfn == devfn)
|
||||
goto out;
|
||||
}
|
||||
|
@ -105,8 +105,17 @@ int __ref cb_alloc(struct pcmcia_socket *s)
|
||||
*/
|
||||
void cb_free(struct pcmcia_socket *s)
|
||||
{
|
||||
struct pci_dev *bridge = s->cb_dev;
|
||||
struct pci_dev *bridge, *dev, *tmp;
|
||||
struct pci_bus *bus;
|
||||
|
||||
if (bridge)
|
||||
pci_stop_and_remove_behind_bridge(bridge);
|
||||
bridge = s->cb_dev;
|
||||
if (!bridge)
|
||||
return;
|
||||
|
||||
bus = bridge->subordinate;
|
||||
if (!bus)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list)
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
}
|
||||
|
@ -369,7 +369,6 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
|
||||
|
||||
extern struct pci_dev *alloc_pci_dev(void);
|
||||
|
||||
#define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list)
|
||||
#define to_pci_dev(n) container_of(n, struct pci_dev, dev)
|
||||
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
|
||||
|
||||
@ -734,9 +733,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp);
|
||||
extern struct pci_dev *pci_dev_get(struct pci_dev *dev);
|
||||
extern void pci_dev_put(struct pci_dev *dev);
|
||||
extern void pci_remove_bus(struct pci_bus *b);
|
||||
extern void __pci_remove_bus_device(struct pci_dev *dev);
|
||||
extern void pci_stop_and_remove_bus_device(struct pci_dev *dev);
|
||||
extern void pci_stop_bus_device(struct pci_dev *dev);
|
||||
void pci_setup_cardbus(struct pci_bus *bus);
|
||||
extern void pci_sort_breadthfirst(void);
|
||||
#define dev_is_pci(d) ((d)->bus == &pci_bus_type)
|
||||
@ -1047,7 +1044,6 @@ void pci_unregister_driver(struct pci_driver *dev);
|
||||
module_driver(__pci_driver, pci_register_driver, \
|
||||
pci_unregister_driver)
|
||||
|
||||
void pci_stop_and_remove_behind_bridge(struct pci_dev *dev);
|
||||
struct pci_driver *pci_dev_driver(const struct pci_dev *dev);
|
||||
int pci_add_dynid(struct pci_driver *drv,
|
||||
unsigned int vendor, unsigned int device,
|
||||
|
Loading…
Reference in New Issue
Block a user