Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a21d70d authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

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: default avatarBjorn Helgaas <bhelgaas@google.com>
parent a5390aa6
Loading
Loading
Loading
Loading
+34 −5
Original line number Diff line number Diff line
@@ -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;

	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
	if (!bridge)
		return NULL;

	b = pci_alloc_bus();
	if (!b)
		return NULL;
		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 @@ class_dev_reg_err:
	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;
}

+5 −0
Original line number Diff line number Diff line
@@ -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