forked from luck/tmp_suning_uos_patched
PCI: add struct pci_host_bridge and a list of all bridges found
This adds a list of all PCI host bridges we find and a way to look up the host bridge from a pci_dev. Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
a5390aa6dc
commit
5a21d70dbd
@ -15,6 +15,8 @@
|
||||
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
|
||||
#define CARDBUS_RESERVE_BUSNR 3
|
||||
|
||||
static LIST_HEAD(pci_host_bridges);
|
||||
|
||||
/* Ugh. Need to stop exporting this to modules. */
|
||||
LIST_HEAD(pci_root_buses);
|
||||
EXPORT_SYMBOL(pci_root_buses);
|
||||
@ -42,6 +44,23 @@ int no_pci_devices(void)
|
||||
}
|
||||
EXPORT_SYMBOL(no_pci_devices);
|
||||
|
||||
static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_bus *bus;
|
||||
struct pci_host_bridge *bridge;
|
||||
|
||||
bus = dev->bus;
|
||||
while (bus->parent)
|
||||
bus = bus->parent;
|
||||
|
||||
list_for_each_entry(bridge, &pci_host_bridges, list) {
|
||||
if (bridge->bus == bus)
|
||||
return bridge;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* PCI Bus Class
|
||||
*/
|
||||
@ -1544,20 +1563,23 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
struct pci_ops *ops, void *sysdata, struct list_head *resources)
|
||||
{
|
||||
int error, i;
|
||||
struct pci_host_bridge *bridge;
|
||||
struct pci_bus *b, *b2;
|
||||
struct device *dev;
|
||||
struct pci_bus_resource *bus_res, *n;
|
||||
struct resource *res;
|
||||
|
||||
b = pci_alloc_bus();
|
||||
if (!b)
|
||||
bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
|
||||
if (!bridge)
|
||||
return NULL;
|
||||
|
||||
b = pci_alloc_bus();
|
||||
if (!b)
|
||||
goto err_bus;
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev) {
|
||||
kfree(b);
|
||||
return NULL;
|
||||
}
|
||||
if (!dev)
|
||||
goto err_dev;
|
||||
|
||||
b->sysdata = sysdata;
|
||||
b->ops = ops;
|
||||
@ -1594,6 +1616,8 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
|
||||
b->number = b->secondary = bus;
|
||||
|
||||
bridge->bus = b;
|
||||
|
||||
/* Add initial resources to the bus */
|
||||
list_for_each_entry_safe(bus_res, n, resources, list)
|
||||
list_move_tail(&bus_res->list, &b->resources);
|
||||
@ -1609,6 +1633,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
}
|
||||
|
||||
down_write(&pci_bus_sem);
|
||||
list_add_tail(&bridge->list, &pci_host_bridges);
|
||||
list_add_tail(&b->node, &pci_root_buses);
|
||||
up_write(&pci_bus_sem);
|
||||
|
||||
@ -1618,11 +1643,15 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
|
||||
device_unregister(dev);
|
||||
dev_reg_err:
|
||||
down_write(&pci_bus_sem);
|
||||
list_del(&bridge->list);
|
||||
list_del(&b->node);
|
||||
up_write(&pci_bus_sem);
|
||||
err_out:
|
||||
kfree(dev);
|
||||
err_dev:
|
||||
kfree(b);
|
||||
err_bus:
|
||||
kfree(bridge);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -368,6 +368,11 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
|
||||
return (pdev->error_state != pci_channel_io_normal);
|
||||
}
|
||||
|
||||
struct pci_host_bridge {
|
||||
struct list_head list;
|
||||
struct pci_bus *bus; /* root bus */
|
||||
};
|
||||
|
||||
/*
|
||||
* The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
|
||||
* to P2P or CardBus bridge windows) go in a table. Additional ones (for
|
||||
|
Loading…
Reference in New Issue
Block a user