linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] PCI, x86: More pci hotplug related cleanup
@ 2012-03-13  7:26 Yinghai Lu
  2012-03-13  7:26 ` [PATCH 01/12] PCI: Add debug print out for pci related dev release Yinghai Lu
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Will claim hw/fw allocated resource.
also add addon_resource support, and make cpc_hotplug/shpchp configure
devices more like pciehp.

The patches need to apply to pci/for-linus and pci/linux-next
and [PATCH 00/36] PCI: pci_host_bridge related cleanup and busn_alloc
and [PATCH v2 00/37] PCI, x86: pci root bus hotplug support

could get from
        git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-pci-hotplug-more

Thanks

Yinghai

Yinghai Lu (12):
  PCI: Add debug print out for pci related dev release
  x86, PCI: Let pcibios_allocate_bus_resources() take bus instead
  PCI: Claim hw/fw allocated resources in hot add path.
  PCI: Kill pci_is_reassignedev()
  PCI: Add addon_resource support for pci_dev
  PCI: Use for_each_pci_dev_resource helper
  PCI: Make piix4 quirk to use addon_resource support
  PCI: Make quirk_io_region to use addon_resource support
  PCI: Use addon_fixed_resource with ati fixed resource
  PCI, pciehp: Separate pci_hp_add_bridge()
  PCI, cphi_hotplug: Simplify configure_slot
  PCI, shpchp: Simplify configure_device

 arch/x86/pci/common.c                  |    3 +-
 arch/x86/pci/i386.c                    |  164 +++++++++++---------
 arch/x86/pci/mrst.c                    |    7 +-
 drivers/pci/bus.c                      |    2 +
 drivers/pci/hotplug-pci.c              |   13 ++
 drivers/pci/hotplug/acpiphp_glue.c     |    4 +-
 drivers/pci/hotplug/cpci_hotplug_pci.c |   35 +----
 drivers/pci/hotplug/pciehp_hpc.c       |    5 +-
 drivers/pci/hotplug/pciehp_pci.c       |   18 +--
 drivers/pci/hotplug/shpchp_pci.c       |   45 ++----
 drivers/pci/iov.c                      |   31 ++--
 drivers/pci/pci-driver.c               |    6 +-
 drivers/pci/pci.c                      |   45 +++---
 drivers/pci/pci.h                      |    1 +
 drivers/pci/probe.c                    |  117 ++++++++++++++-
 drivers/pci/quirks.c                   |  256 +++++++++++++++++++-------------
 drivers/pci/remove.c                   |    5 +-
 drivers/pci/setup-bus.c                |   32 ++--
 drivers/pci/setup-res.c                |   38 +++--
 drivers/pci/xen-pcifront.c             |    4 +-
 include/linux/pci.h                    |   78 +++++++++-
 21 files changed, 564 insertions(+), 345 deletions(-)

-- 
1.7.7


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/12] PCI: Add debug print out for pci related dev release
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 02/12] x86, PCI: Let pcibios_allocate_bus_resources() take bus instead Yinghai Lu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

In some case, they could not be called because some users just use
get_device() without put device back.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/probe.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 0ca213c..972553b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -57,6 +57,7 @@ static void release_pcibus_dev(struct device *dev)
 
 	if (pci_bus->bridge)
 		put_device(pci_bus->bridge);
+	dev_printk(KERN_DEBUG, dev, "freeing pci_bus info\n");
 	pci_bus_remove_resources(pci_bus);
 	pci_release_bus_of_node(pci_bus);
 	kfree(pci_bus);
@@ -1278,6 +1279,7 @@ static void pci_release_dev(struct device *dev)
 {
 	struct pci_dev *pci_dev;
 
+	dev_printk(KERN_DEBUG, dev, "freeing pci_dev info\n");
 	pci_dev = to_pci_dev(dev);
 	pci_release_capabilities(pci_dev);
 	pci_release_of_node(pci_dev);
@@ -1342,6 +1344,7 @@ static void pci_release_bus_bridge_dev(struct device *dev)
 {
 	struct pci_host_bridge *bridge = to_pci_host_bridge(dev);
 
+	dev_printk(KERN_DEBUG, dev, "freeing pci_host_bridge info\n");
 	if (bridge->release_fn)
 		bridge->release_fn(bridge);
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/12] x86, PCI: Let pcibios_allocate_bus_resources() take bus instead
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
  2012-03-13  7:26 ` [PATCH 01/12] PCI: Add debug print out for pci related dev release Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 03/12] PCI: Claim hw/fw allocated resources in hot add path Yinghai Lu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Will need call the same code for one single root bus during hot add.
So try to make it take bus instead of bus_list.

Also separate out pcibios_allocate_bridge_resources and
pcibios_allocate_dev_resources to make code more readable.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/pci/i386.c |   83 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 51 insertions(+), 32 deletions(-)

diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 33e6a0b..111bcef 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -191,46 +191,46 @@ EXPORT_SYMBOL(pcibios_align_resource);
  *	    as well.
  */
 
-static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
+static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
 {
-	struct pci_bus *bus;
-	struct pci_dev *dev;
 	int idx;
 	struct resource *r;
 
-	/* Depth-First Search on bus tree */
-	list_for_each_entry(bus, bus_list, node) {
-		if ((dev = bus->self)) {
-			for (idx = PCI_BRIDGE_RESOURCES;
-			    idx < PCI_NUM_RESOURCES; idx++) {
-				r = &dev->resource[idx];
-				if (!r->flags)
-					continue;
-				if (!r->start ||
-				    pci_claim_resource(dev, idx) < 0) {
-					/*
-					 * Something is wrong with the region.
-					 * Invalidate the resource to prevent
-					 * child resource allocations in this
-					 * range.
-					 */
-					r->start = r->end = 0;
-					r->flags = 0;
-				}
-			}
+	for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+		r = &dev->resource[idx];
+		if (!r->flags)
+			continue;
+		if (!r->start ||
+		    pci_claim_resource(dev, idx) < 0) {
+			/*
+			 * Something is wrong with the region.
+			 * Invalidate the resource to prevent
+			 * child resource allocations in this
+			 * range.
+			 */
+			r->start = r->end = 0;
+			r->flags = 0;
 		}
-		pcibios_allocate_bus_resources(&bus->children);
 	}
 }
+static void pcibios_allocate_bus_resources(struct pci_bus *bus)
+{
+	struct pci_bus *child;
+
+	/* Depth-First Search on bus tree */
+	if (bus->self)
+		pcibios_allocate_bridge_resources(bus->self);
+	list_for_each_entry(child, &bus->children, node)
+		pcibios_allocate_bus_resources(child);
+}
 
 struct pci_check_idx_range {
 	int start;
 	int end;
 };
 
-static void __init pcibios_allocate_resources(int pass)
+static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
 {
-	struct pci_dev *dev = NULL;
 	int idx, disabled, i;
 	u16 command;
 	struct resource *r;
@@ -242,9 +242,8 @@ static void __init pcibios_allocate_resources(int pass)
 #endif
 	};
 
-	for_each_pci_dev(dev) {
-		pci_read_config_word(dev, PCI_COMMAND, &command);
-		for (i = 0; i < ARRAY_SIZE(idx_range); i++)
+	pci_read_config_word(dev, PCI_COMMAND, &command);
+	for (i = 0; i < ARRAY_SIZE(idx_range); i++)
 		for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
 			r = &dev->resource[idx];
 			if (r->parent)		/* Already allocated */
@@ -282,6 +281,19 @@ static void __init pcibios_allocate_resources(int pass)
 						reg & ~PCI_ROM_ADDRESS_ENABLE);
 			}
 		}
+}
+
+void pcibios_allocate_resources(struct pci_bus *bus, int pass)
+{
+	struct pci_dev *dev;
+	struct pci_bus *child;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pcibios_allocate_dev_resources(dev, pass);
+
+		child = dev->subordinate;
+		if (child)
+			pcibios_allocate_resources(child, pass);
 	}
 }
 
@@ -315,10 +327,17 @@ static int __init pcibios_assign_resources(void)
 
 void __init pcibios_resource_survey(void)
 {
+	struct pci_bus *bus;
+
 	DBG("PCI: Allocating resources\n");
-	pcibios_allocate_bus_resources(&pci_root_buses);
-	pcibios_allocate_resources(0);
-	pcibios_allocate_resources(1);
+
+	list_for_each_entry(bus, &pci_root_buses, node)
+		pcibios_allocate_bus_resources(bus);
+
+	list_for_each_entry(bus, &pci_root_buses, node)
+		pcibios_allocate_resources(bus, 0);
+	list_for_each_entry(bus, &pci_root_buses, node)
+		pcibios_allocate_resources(bus, 1);
 
 	e820_reserve_resources_late();
 	/*
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/12] PCI: Claim hw/fw allocated resources in hot add path.
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
  2012-03-13  7:26 ` [PATCH 01/12] PCI: Add debug print out for pci related dev release Yinghai Lu
  2012-03-13  7:26 ` [PATCH 02/12] x86, PCI: Let pcibios_allocate_bus_resources() take bus instead Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 04/12] PCI: Kill pci_is_reassignedev() Yinghai Lu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

During testing remove/rescan root bus 00, found
[  338.142574] bus: 'pci': really_probe: probing driver ata_piix with device 0000:00:01.1
[  338.146788] ata_piix 0000:00:01.1: device not available (can't reserve [io  0x01f0-0x01f7])
[  338.150565] ata_piix: probe of 0000:00:01.1 failed with error -22

because that fixed resource is not claimed from
        arch/x86/pci/i386.c::pcibios_allocate_resources()
that is init path.

Try to claim those resources, so on the remove/rescan will still use old
resources.

It is some kind honoring HW/FW setting in the registers during hot add.
esp root-bus hot add is through acpi, BIOS have chance to set some register
for us.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/pci/i386.c     |   10 ++++++++++
 drivers/pci/bus.c       |    2 ++
 drivers/pci/setup-bus.c |    4 ++++
 include/linux/pci.h     |    1 +
 4 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 111bcef..3e1dd0e 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -325,6 +325,16 @@ static int __init pcibios_assign_resources(void)
 	return 0;
 }
 
+void pcibios_resource_survey_bus(struct pci_bus *bus)
+{
+	dev_printk(KERN_DEBUG, &bus->dev, "Allocating resources\n");
+
+	pcibios_allocate_bus_resources(bus);
+
+	pcibios_allocate_resources(bus, 0);
+	pcibios_allocate_resources(bus, 1);
+}
+
 void __init pcibios_resource_survey(void)
 {
 	struct pci_bus *bus;
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 1eb7944..672ffc8 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -94,6 +94,8 @@ void pci_bus_remove_resources(struct pci_bus *bus)
 	pci_free_resource_list(&bus->resources);
 }
 
+void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
+
 /**
  * pci_bus_alloc_resource - allocate a resource from a parent bus
  * @bus: PCI bus
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index d9a5500..33f0fcd 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1444,6 +1444,8 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
 				  IORESOURCE_PREFETCH;
 
+	pcibios_resource_survey_bus(parent);
+
 again:
 	__pci_bus_size_bridges(parent, &add_list, true);
 	__pci_bridge_assign_resources(bridge, &add_list, &fail_head);
@@ -1499,6 +1501,8 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus)
 	LIST_HEAD(add_list); /* list of resources that
 					want additional resources */
 
+	pcibios_resource_survey_bus(bus);
+
 	down_read(&pci_bus_sem);
 	__pci_bus_size_bridges(bus, &add_list, false);
 	up_read(&pci_bus_sem);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ec8c4cf..161f6c0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -643,6 +643,7 @@ extern struct list_head pci_root_buses;	/* list of all known PCI buses */
 /* Some device drivers need know if pci is initiated */
 extern int no_pci_devices(void);
 
+void pcibios_resource_survey_bus(struct pci_bus *bus);
 void pcibios_fixup_bus(struct pci_bus *);
 int __must_check pcibios_enable_device(struct pci_dev *, int mask);
 char *pcibios_setup(char *str);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/12] PCI: Kill pci_is_reassignedev()
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (2 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 03/12] PCI: Claim hw/fw allocated resources in hot add path Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 05/12] PCI: Add addon_resource support for pci_dev Yinghai Lu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Only one user. Just use pci_specified_resource_alignement() directly.
So could only get get align one time for the dev that in the list

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci.c |   17 +++--------------
 1 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index b832f0f..32ab301 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3682,18 +3682,6 @@ resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
 	return align;
 }
 
-/**
- * pci_is_reassigndev - check if specified PCI is target device to reassign
- * @dev: the PCI device to check
- *
- * RETURNS: non-zero for PCI device is a target device to reassign,
- *          or zero is not.
- */
-int pci_is_reassigndev(struct pci_dev *dev)
-{
-	return (pci_specified_resource_alignment(dev) != 0);
-}
-
 /*
  * This function disables memory decoding and releases memory resources
  * of the device specified by kernel's boot parameter 'pci=resource_alignment='.
@@ -3708,7 +3696,9 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
 	resource_size_t align, size;
 	u16 command;
 
-	if (!pci_is_reassigndev(dev))
+	/* check if specified PCI is target device to reassign */
+	align = pci_specified_resource_alignment(dev);
+	if (!align)
 		return;
 
 	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
@@ -3724,7 +3714,6 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
 	command &= ~PCI_COMMAND_MEMORY;
 	pci_write_config_word(dev, PCI_COMMAND, command);
 
-	align = pci_specified_resource_alignment(dev);
 	for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
 		r = &dev->resource[i];
 		if (!(r->flags & IORESOURCE_MEM))
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/12] PCI: Add addon_resource support for pci_dev
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (3 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 04/12] PCI: Kill pci_is_reassignedev() Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-15 21:30   ` Bjorn Helgaas
  2012-03-13  7:26 ` [PATCH 06/12] PCI: Use for_each_pci_dev_resource helper Yinghai Lu
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Will add addon_resources list in pci_dev, it will be used for resources
other than stand, rom, sriov, bridges.
Some could be same as std reg, but using different register.
Some could have own way to read/write to them.

Kernel using different way to hack those resources like abusing
pci bridge resource spot on non bridge pci device.

With this patch, will treat addon-resource like standard resource with
special ops.

Also adding bunch of for_each... helpers to make resource loop easier.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/pci.c       |    7 +++
 drivers/pci/probe.c     |  108 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/setup-res.c |   24 ++++++++---
 include/linux/pci.h     |   77 ++++++++++++++++++++++++++++++++-
 4 files changed, 207 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 32ab301..af84abf 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3545,6 +3545,13 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
 		reg = pci_iov_resource_bar(dev, resno, type);
 		if (reg)
 			return reg;
+	} else if (resno >= PCI_NUM_RESOURCES) {
+		struct resource *res = pci_dev_resource_n(dev, resno);
+
+		if (res) {
+			*type = pci_bar_unknown;
+			return to_pci_dev_addon_resource(res)->reg_addr;
+		}
 	}
 
 	dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 972553b..dac829f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -75,6 +75,111 @@ static int __init pcibus_class_init(void)
 }
 postcore_initcall(pcibus_class_init);
 
+struct resource *pci_dev_resource_n(struct pci_dev *dev, int n)
+{
+	struct pci_dev_addon_resource *addon_res;
+
+	if (n < PCI_NUM_RESOURCES)
+		return &dev->resource[n];
+
+	n -= PCI_NUM_RESOURCES;
+	list_for_each_entry(addon_res, &dev->addon_resources, list) {
+		if (n-- == 0)
+			return &addon_res->res;
+	}
+	return NULL;
+}
+
+int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res)
+{
+	int i;
+	struct resource *r;
+
+	for_each_pci_dev_all_resource(dev, r, i)
+		if (r == res)
+			return i;
+
+	return -1;
+}
+
+struct pci_dev_addon_resource *__add_pci_dev_addon_resource(
+		 struct pci_dev *dev, int addr, char *name)
+{
+	struct pci_dev_addon_resource *addon_res;
+
+	addon_res = kzalloc(sizeof(*addon_res), GFP_KERNEL);
+
+	if (!addon_res)
+		return NULL;
+
+	addon_res->reg_addr = addr;
+
+	if (name)
+		addon_res->res.name = name;
+	else
+		addon_res->res.name = pci_name(dev);
+
+	list_add_tail(&addon_res->list, &dev->addon_resources);
+
+	return addon_res;
+}
+
+struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource(
+		 struct pci_dev *dev, int start, int size, int flags,
+		 int addr, char *name)
+{
+	struct pci_dev_addon_resource *addon_res;
+	struct resource *res;
+
+	addon_res = __add_pci_dev_addon_resource(dev, addr, name);
+	if (addon_res)
+		return NULL;
+
+	res = &addon_res->res;
+	res->start = start;
+	res->end = start + size - 1;
+	res->flags = flags | IORESOURCE_PCI_FIXED;
+
+	dev_printk(KERN_DEBUG, &dev->dev,
+		   "addon fixed resource %s %pR added\n", res->name, res);
+
+	return addon_res;
+}
+
+struct pci_dev_addon_resource *add_pci_dev_addon_resource(struct pci_dev *dev,
+		 int addr, int size, struct resource_ops *ops, char *name)
+{
+	struct pci_dev_addon_resource *addon_res;
+	struct resource *res;
+
+	addon_res = __add_pci_dev_addon_resource(dev, addr, name);
+	if (!addon_res)
+		return NULL;
+
+	res = &addon_res->res;
+	if (ops) {
+		addon_res->ops = ops;
+		addon_res->size = size;
+		ops->read(dev, res, addr);
+	} else
+		__pci_read_base(dev, pci_bar_unknown, res, addr);
+
+	dev_printk(KERN_DEBUG, &dev->dev,
+		   "addon resource %s %pR added\n", res->name, res);
+
+	return addon_res;
+}
+
+static void pci_release_dev_addon_res(struct pci_dev *dev)
+{
+	struct pci_dev_addon_resource *addon_res, *tmp;
+
+	list_for_each_entry_safe(addon_res, tmp, &dev->addon_resources, list) {
+		list_del(&addon_res->list);
+		kfree(addon_res);
+	}
+}
+
 static u64 pci_size(u64 base, u64 maxbase, u64 mask)
 {
 	u64 size = mask & maxbase;	/* Find the significant bits */
@@ -1283,6 +1388,7 @@ static void pci_release_dev(struct device *dev)
 	pci_dev = to_pci_dev(dev);
 	pci_release_capabilities(pci_dev);
 	pci_release_of_node(pci_dev);
+	pci_release_dev_addon_res(pci_dev);
 	kfree(pci_dev);
 }
 
@@ -1362,11 +1468,13 @@ struct pci_dev *alloc_pci_dev(void)
 		return NULL;
 
 	INIT_LIST_HEAD(&dev->bus_list);
+	INIT_LIST_HEAD(&dev->addon_resources);
 
 	return dev;
 }
 EXPORT_SYMBOL(alloc_pci_dev);
 
+
 bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
 				 int crs_timeout)
 {
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index eea85da..48251e3 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -33,7 +33,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 	u32 new, check, mask;
 	int reg;
 	enum pci_bar_type type;
-	struct resource *res = dev->resource + resno;
+	struct resource *res = pci_dev_resource_n(dev, resno);
 
 	/*
 	 * Ignore resources for unimplemented BARs and unused resource slots
@@ -50,6 +50,21 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 	if (res->flags & IORESOURCE_PCI_FIXED)
 		return;
 
+	if (resno >= PCI_NUM_RESOURCES) {
+		struct pci_dev_addon_resource *addon_res;
+
+		addon_res = to_pci_dev_addon_resource(res);
+		reg = addon_res->reg_addr;
+		if (addon_res->ops) {
+			addon_res->ops->write(dev, res, reg);
+			return;
+		}
+	} else
+		reg = pci_resource_bar(dev, resno, &type);
+
+	if (!reg)
+		return;
+
 	pcibios_resource_to_bus(dev, &region, res);
 
 	new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
@@ -58,9 +73,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 	else
 		mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
 
-	reg = pci_resource_bar(dev, resno, &type);
-	if (!reg)
-		return;
 	if (type != pci_bar_unknown) {
 		if (!(res->flags & IORESOURCE_ROM_ENABLE))
 			return;
@@ -257,7 +269,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
 		dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
-		if (resno < PCI_BRIDGE_RESOURCES)
+		if (!resno_is_for_bridge(resno))
 			pci_update_resource(dev, resno);
 	}
 	return ret;
@@ -292,7 +304,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
 	if (!ret) {
 		res->flags &= ~IORESOURCE_STARTALIGN;
 		dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
-		if (resno < PCI_BRIDGE_RESOURCES)
+		if (!resno_is_for_bridge(resno))
 			pci_update_resource(dev, resno);
 	}
 	return ret;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 161f6c0..173b8fe 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -299,6 +299,7 @@ struct pci_dev {
 	 */
 	unsigned int	irq;
 	struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
+	struct list_head addon_resources; /* addon I/O and memory resource */
 
 	/* These fields are used by common fixups */
 	unsigned int	transparent:1;	/* Transparent PCI bridge */
@@ -347,6 +348,76 @@ struct pci_dev {
 #endif
 };
 
+struct resource_ops {
+	int (*read)(struct pci_dev *dev, struct resource *res, int addr);
+	int (*write)(struct pci_dev *dev, struct resource *res, int addr);
+};
+
+struct pci_dev_addon_resource {
+	struct list_head list;
+	int reg_addr;
+	int size;
+	struct resource res;
+	struct resource_ops *ops;
+};
+#define	to_pci_dev_addon_resource(n) container_of(n, struct pci_dev_addon_resource, res)
+
+struct resource *pci_dev_resource_n(struct pci_dev *dev, int n);
+int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res);
+struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource(
+		 struct pci_dev *dev, int start, int size, int flags,
+		 int addr, char *name);
+struct pci_dev_addon_resource *add_pci_dev_addon_resource(struct pci_dev *dev,
+		 int addr, int size, struct resource_ops *ops, char *name);
+
+#define resno_is_for_bridge(n) ((n)>=PCI_BRIDGE_RESOURCES && (n)<=PCI_BRIDGE_RESOURCE_END)
+
+/* all (include bridge) resources */
+#define for_each_pci_dev_all_resource(dev, res, i)			\
+	for (i = 0;							\
+	     (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
+	     i++)
+/* exclude bridge resources */
+#define for_each_pci_dev_nobridge_resource(dev, res, i)			\
+	for (i = 0;							\
+	     (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
+	     i = (i != (PCI_BRIDGE_RESOURCES - 1)) ? (i+1) : PCI_NUM_RESOURCES)
+/* exclude bridge and IOV resources */
+#define for_each_pci_dev_base_resource(dev, res, i)			\
+	for (i = 0;							\
+	     (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
+	     i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_NUM_RESOURCES)
+/* exclude ROM and bridge and IOV resources */
+#define for_each_pci_dev_base_norom_resource(dev, res, i)		\
+	for (i = 0;							\
+	     (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
+	     i = (i != (PCI_ROM_RESOURCE-1)) ? (i+1) : PCI_NUM_RESOURCES)
+/* exclude IOV resources */
+#define for_each_pci_dev_noiov_resource(dev, res, i)			\
+	for (i = 0;							\
+	     (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
+	     i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_BRIDGE_RESOURCES)
+/* only std resources */
+#define for_each_pci_dev_std_resource(dev, res, i)			\
+	for (i = PCI_STD_RESOURCES;					\
+	   (res = pci_dev_resource_n(dev, i)) && i < (PCI_STD_RESOURCE_END+1); \
+	     i++)
+/* only IOV resources */
+#define for_each_pci_dev_iov_resource(dev, res, i)			\
+	for (i = PCI_IOV_RESOURCES;					\
+	   (res = pci_dev_resource_n(dev, i)) && i < (PCI_IOV_RESOURCE_END+1); \
+	     i++)
+/* only bridge resources */
+#define for_each_pci_dev_bridge_resource(dev, res, i)			\
+	for (i = PCI_BRIDGE_RESOURCES;					\
+	(res = pci_dev_resource_n(dev, i)) && i < (PCI_BRIDGE_RESOURCE_END+1); \
+	     i++)
+/* only addon resources */
+#define for_each_pci_dev_addon_resource(dev, res, i)			\
+	for (i = PCI_NUM_RESOURCES;					\
+	     (res = pci_dev_resource_n(dev, i));			\
+	     i++)
+
 static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
 {
 #ifdef CONFIG_PCI_IOV
@@ -1348,9 +1419,9 @@ static inline int pci_domain_nr(struct pci_bus *bus)
 
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
-#define pci_resource_start(dev, bar)	((dev)->resource[(bar)].start)
-#define pci_resource_end(dev, bar)	((dev)->resource[(bar)].end)
-#define pci_resource_flags(dev, bar)	((dev)->resource[(bar)].flags)
+#define pci_resource_start(dev, bar)	(pci_dev_resource_n(dev, (bar))->start)
+#define pci_resource_end(dev, bar)	(pci_dev_resource_n(dev, (bar))->end)
+#define pci_resource_flags(dev, bar)	(pci_dev_resource_n(dev, (bar))->flags)
 #define pci_resource_len(dev,bar) \
 	((pci_resource_start((dev), (bar)) == 0 &&	\
 	  pci_resource_end((dev), (bar)) ==		\
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/12] PCI: Use for_each_pci_dev_resource helper
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (4 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 05/12] PCI: Add addon_resource support for pci_dev Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support Yinghai Lu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Replace those open code, and make code more readable.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/pci/common.c              |    3 +-
 arch/x86/pci/i386.c                |   75 +++++++++++++++--------------------
 arch/x86/pci/mrst.c                |    7 ++-
 drivers/pci/hotplug/acpiphp_glue.c |    4 +-
 drivers/pci/hotplug/pciehp_hpc.c   |    5 +-
 drivers/pci/iov.c                  |   31 +++++++--------
 drivers/pci/pci-driver.c           |    6 ++-
 drivers/pci/pci.c                  |   21 +++++-----
 drivers/pci/probe.c                |    6 ++-
 drivers/pci/remove.c               |    5 +-
 drivers/pci/setup-bus.c            |   28 ++++++--------
 drivers/pci/setup-res.c            |   14 +++----
 drivers/pci/xen-pcifront.c         |    4 +-
 13 files changed, 96 insertions(+), 113 deletions(-)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 0ec860f..7ea09f8 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -136,8 +136,7 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
 		* resource so the kernel doesn't attmept to assign
 		* it later on in pci_assign_unassigned_resources
 		*/
-		for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
-			bar_r = &dev->resource[bar];
+		for_each_pci_dev_base_norom_resource(dev, bar_r, bar) {
 			if (bar_r->start == 0 && bar_r->end != 0) {
 				bar_r->flags = 0;
 				bar_r->end = 0;
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 3e1dd0e..29c3e19 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -196,7 +196,7 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
 	int idx;
 	struct resource *r;
 
-	for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+	for_each_pci_dev_bridge_resource(dev, r, idx) {
 		r = &dev->resource[idx];
 		if (!r->flags)
 			continue;
@@ -231,56 +231,45 @@ struct pci_check_idx_range {
 
 static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
 {
-	int idx, disabled, i;
+	int idx, disabled;
 	u16 command;
 	struct resource *r;
 
-	struct pci_check_idx_range idx_range[] = {
-		{ PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
-#ifdef CONFIG_PCI_IOV
-		{ PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
-#endif
-	};
-
 	pci_read_config_word(dev, PCI_COMMAND, &command);
-	for (i = 0; i < ARRAY_SIZE(idx_range); i++)
-		for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
-			r = &dev->resource[idx];
-			if (r->parent)		/* Already allocated */
-				continue;
-			if (!r->start)		/* Address not assigned at all */
-				continue;
-			if (r->flags & IORESOURCE_IO)
-				disabled = !(command & PCI_COMMAND_IO);
-			else
-				disabled = !(command & PCI_COMMAND_MEMORY);
-			if (pass == disabled) {
-				dev_dbg(&dev->dev,
-					"BAR %d: reserving %pr (d=%d, p=%d)\n",
-					idx, r, disabled, pass);
-				if (pci_claim_resource(dev, idx) < 0) {
-					/* We'll assign a new address later */
-					pcibios_save_fw_addr(dev,
-							idx, r->start);
-					r->end -= r->start;
-					r->start = 0;
-				}
+	for_each_pci_dev_base_norom_resource(dev, r, idx) {
+		if (r->parent)		/* Already allocated */
+			continue;
+		if (!r->start)		/* Address not assigned at all */
+			continue;
+		if (r->flags & IORESOURCE_IO)
+			disabled = !(command & PCI_COMMAND_IO);
+		else
+			disabled = !(command & PCI_COMMAND_MEMORY);
+		if (pass == disabled) {
+			dev_dbg(&dev->dev,
+				"BAR %d: reserving %pr (d=%d, p=%d)\n",
+				idx, r, disabled, pass);
+			if (pci_claim_resource(dev, idx) < 0) {
+				/* We'll assign a new address later */
+				pcibios_save_fw_addr(dev, idx, r->start);
+				r->end -= r->start;
+				r->start = 0;
 			}
 		}
-		if (!pass) {
-			r = &dev->resource[PCI_ROM_RESOURCE];
-			if (r->flags & IORESOURCE_ROM_ENABLE) {
-				/* Turn the ROM off, leave the resource region,
-				 * but keep it unregistered. */
-				u32 reg;
-				dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
-				r->flags &= ~IORESOURCE_ROM_ENABLE;
-				pci_read_config_dword(dev,
-						dev->rom_base_reg, &reg);
-				pci_write_config_dword(dev, dev->rom_base_reg,
+	}
+	if (!pass) {
+		r = &dev->resource[PCI_ROM_RESOURCE];
+		if (r->flags & IORESOURCE_ROM_ENABLE) {
+			/* Turn the ROM off, leave the resource region,
+			 * but keep it unregistered. */
+			u32 reg;
+			dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
+			r->flags &= ~IORESOURCE_ROM_ENABLE;
+			pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+			pci_write_config_dword(dev, dev->rom_base_reg,
 						reg & ~PCI_ROM_ADDRESS_ENABLE);
-			}
 		}
+	}
 }
 
 void pcibios_allocate_resources(struct pci_bus *bus, int pass)
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c
index 140942f..55e20d8 100644
--- a/arch/x86/pci/mrst.c
+++ b/arch/x86/pci/mrst.c
@@ -280,6 +280,7 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
 	unsigned long offset;
 	u32 size;
 	int i;
+	struct resource *res;
 
 	if (!pci_soc_mode)
 		return;
@@ -294,10 +295,10 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
 	    PCI_DEVFN(2, 2) == dev->devfn)
 		return;
 
-	for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+	for_each_pci_dev_std_resource(dev, res, i) {
 		pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
-		dev->resource[i].end = dev->resource[i].start + size - 1;
-		dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
+		res->end = res->start + size - 1;
+		res->flags |= IORESOURCE_PCI_FIXED;
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 9f1a195..329d4fc 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1024,10 +1024,10 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
 	struct pci_dev *dev;
 	int i;
 	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+	struct resource *res;
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
-		for (i=0; i<PCI_BRIDGE_RESOURCES; i++) {
-			struct resource *res = &dev->resource[i];
+		for_each_pci_dev_nobridge_resource(dev, res, i) {
 			if ((res->flags & type_mask) && !res->start &&
 					res->end) {
 				/* Could not assign a required resources
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index a960fae..ef10429 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -899,6 +899,7 @@ static inline void dbg_ctrl(struct controller *ctrl)
 	int i;
 	u16 reg16;
 	struct pci_dev *pdev = ctrl->pcie->port;
+	struct resource *res;
 
 	if (!pciehp_debug)
 		return;
@@ -914,11 +915,11 @@ static inline void dbg_ctrl(struct controller *ctrl)
 		  pdev->subsystem_vendor);
 	ctrl_info(ctrl, "  PCIe Cap offset      : 0x%02x\n",
 		  pci_pcie_cap(pdev));
-	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+	for_each_pci_dev_all_resource(pdev, res, i) {
 		if (!pci_resource_len(pdev, i))
 			continue;
 		ctrl_info(ctrl, "  PCI resource [%d]     : %pR\n",
-			  i, &pdev->resource[i]);
+			  i, res);
 	}
 	ctrl_info(ctrl, "Slot Capabilities      : 0x%08x\n", ctrl->slot_cap);
 	ctrl_info(ctrl, "  Physical Slot Number : %d\n", PSN(ctrl));
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 6554e1a..f015764 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -99,17 +99,20 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset)
 	pci_setup_device(virtfn);
 	virtfn->dev.parent = dev->dev.parent;
 
-	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
-		res = dev->resource + PCI_IOV_RESOURCES + i;
+	for_each_pci_dev_iov_resource(dev, res, i) {
+		struct resource *virtfn_res;
+
 		if (!res->parent)
 			continue;
-		virtfn->resource[i].name = pci_name(virtfn);
-		virtfn->resource[i].flags = res->flags;
+
+		virtfn_res = pci_dev_resource_n(virtfn, i - PCI_IOV_RESOURCES);
+		virtfn_res->name = pci_name(virtfn);
+		virtfn_res->flags = res->flags;
 		size = resource_size(res);
 		do_div(size, iov->total);
-		virtfn->resource[i].start = res->start + size * id;
-		virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
-		rc = request_resource(res, &virtfn->resource[i]);
+		virtfn_res->start = res->start + size * id;
+		virtfn_res->end = virtfn_res->start + size - 1;
+		rc = request_resource(res, virtfn_res);
 		BUG_ON(rc);
 	}
 
@@ -313,9 +316,8 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
 		return -EIO;
 
 	nres = 0;
-	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
-		bars |= (1 << (i + PCI_IOV_RESOURCES));
-		res = dev->resource + PCI_IOV_RESOURCES + i;
+	for_each_pci_dev_iov_resource(dev, res, i) {
+		bars |= 1 << i;
 		if (res->parent)
 			nres++;
 	}
@@ -473,10 +475,9 @@ found:
 	pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
 
 	nres = 0;
-	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
-		res = dev->resource + PCI_IOV_RESOURCES + i;
+	for_each_pci_dev_iov_resource(dev, res, i) {
 		i += __pci_read_base(dev, pci_bar_unknown, res,
-				     pos + PCI_SRIOV_BAR + i * 4);
+			     pos + PCI_SRIOV_BAR + (i - PCI_IOV_RESOURCES) * 4);
 		if (!res->flags)
 			continue;
 		if (resource_size(res) & (PAGE_SIZE - 1)) {
@@ -519,10 +520,8 @@ found:
 	return 0;
 
 failed:
-	for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
-		res = dev->resource + PCI_IOV_RESOURCES + i;
+	for_each_pci_dev_iov_resource(dev, res, i)
 		res->flags = 0;
-	}
 
 	return rc;
 }
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 5d19695..a82c66f 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1201,9 +1201,11 @@ pci_dev_driver(const struct pci_dev *dev)
 	if (dev->driver)
 		return dev->driver;
 	else {
+		struct resource *res;
 		int i;
-		for(i=0; i<=PCI_ROM_RESOURCE; i++)
-			if (dev->resource[i].flags & IORESOURCE_BUSY)
+
+		for_each_pci_dev_base_resource((struct pci_dev *)dev, res, i)
+			if (res->flags & IORESOURCE_BUSY)
 				return &pci_compat_driver;
 	}
 	return NULL;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index af84abf..4512db6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -483,8 +483,9 @@ static void
 pci_restore_bars(struct pci_dev *dev)
 {
 	int i;
+	struct resource *res;
 
-	for (i = 0; i < PCI_BRIDGE_RESOURCES; i++)
+	for_each_pci_dev_nobridge_resource(dev, res, i)
 		pci_update_resource(dev, i);
 }
 
@@ -1138,6 +1139,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
 {
 	int err;
 	int i, bars = 0;
+	struct resource *res;
 
 	/*
 	 * Power state could be unknown at this point, either due to a fresh
@@ -1155,12 +1157,11 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
 		return 0;		/* already enabled */
 
 	/* only skip sriov related */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++)
-		if (dev->resource[i].flags & flags)
-			bars |= (1 << i);
-	for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++)
-		if (dev->resource[i].flags & flags)
+	for_each_pci_dev_noiov_resource(dev, res, i) {
+		/* TODO: check i with bits of bars */
+		if (res->flags & flags)
 			bars |= (1 << i);
+	}
 
 	err = do_pci_enable_device(dev, bars);
 	if (err < 0)
@@ -2462,7 +2463,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n
 
 err_out:
 	dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar,
-		 &pdev->resource[bar]);
+		 pci_dev_resource_n(pdev, bar));
 	return -EBUSY;
 }
 
@@ -3721,8 +3722,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
 	command &= ~PCI_COMMAND_MEMORY;
 	pci_write_config_word(dev, PCI_COMMAND, command);
 
-	for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
-		r = &dev->resource[i];
+	for_each_pci_dev_nobridge_resource(dev, r, i) {
 		if (!(r->flags & IORESOURCE_MEM))
 			continue;
 		size = resource_size(r);
@@ -3741,8 +3741,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
 	 */
 	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
 	    (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
-		for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
-			r = &dev->resource[i];
+		for_each_pci_dev_bridge_resource(dev, r, i) {
 			if (!(r->flags & IORESOURCE_MEM))
 				continue;
 			r->end = resource_size(r) - 1;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index dac829f..3143964 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -360,9 +360,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 {
 	unsigned int pos, reg;
+	struct resource *res;
 
-	for (pos = 0; pos < howmany; pos++) {
-		struct resource *res = &dev->resource[pos];
+	for_each_pci_dev_std_resource(dev, res, pos) {
+		if (pos >= howmany)
+			break;
 		reg = PCI_BASE_ADDRESS_0 + (pos << 2);
 		pos += __pci_read_base(dev, pci_bar_unknown, res, reg);
 	}
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 9ffc071..28c9fb8 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -6,15 +6,14 @@
 static void pci_free_resources(struct pci_dev *dev)
 {
 	int i;
+	struct resource *res;
 
  	msi_remove_pci_irq_vectors(dev);
 
 	pci_cleanup_rom(dev);
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *res = dev->resource + i;
+	for_each_pci_dev_all_resource(dev, res, i)
 		if (res->parent)
 			release_resource(res);
-	}
 }
 
 static void pci_stop_dev(struct pci_dev *dev)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 33f0fcd..8540155 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -106,7 +106,7 @@ static resource_size_t get_res_add_size(struct list_head *head,
 
 	list_for_each_entry(dev_res, head, list) {
 		if (dev_res->res == res) {
-			int idx = res - &dev_res->dev->resource[0];
+			int idx = pci_dev_resource_idx(dev_res->dev, res);
 
 			dev_printk(KERN_DEBUG, &dev_res->dev->dev,
 				 "res[%d]=%pR get_res_add_size add_size %llx\n",
@@ -124,15 +124,13 @@ static resource_size_t get_res_add_size(struct list_head *head,
 static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
 {
 	int i;
+	struct resource *r;
 
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *r;
+	for_each_pci_dev_all_resource(dev, r, i) {
 		struct pci_dev_resource *dev_res, *tmp;
 		resource_size_t r_align;
 		struct list_head *n;
 
-		r = &dev->resource[i];
-
 		if (r->flags & IORESOURCE_PCI_FIXED)
 			continue;
 
@@ -237,7 +235,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
 		if (!found_match)/* just skip */
 			continue;
 
-		idx = res - &add_res->dev->resource[0];
+		idx = pci_dev_resource_idx(add_res->dev, res);
 		add_size = add_res->add_size;
 		if (!resource_size(res)) {
 			res->start = add_res->start;
@@ -280,7 +278,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
 
 	list_for_each_entry(dev_res, head, list) {
 		res = dev_res->res;
-		idx = res - &dev_res->dev->resource[0];
+		idx = pci_dev_resource_idx(dev_res->dev, res);
 		if (resource_size(res) &&
 		    pci_assign_resource(dev_res->dev, idx)) {
 			if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) {
@@ -716,9 +714,9 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
+		struct resource *r;
 
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource *r = &dev->resource[i];
+		for_each_pci_dev_all_resource(dev, r, i) {
 			unsigned long r_size;
 
 			if (r->parent || !(r->flags & IORESOURCE_IO))
@@ -798,9 +796,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
 
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
+		struct resource *r;
 
-		for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-			struct resource *r = &dev->resource[i];
+		for_each_pci_dev_all_resource(dev, r, i) {
 			resource_size_t r_size;
 
 			if (r->parent || (r->flags & mask) != type)
@@ -1140,9 +1138,7 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
 				  IORESOURCE_PREFETCH;
 
 	dev = bus->self;
-	for (idx = PCI_BRIDGE_RESOURCES; idx <= PCI_BRIDGE_RESOURCE_END;
-	     idx++) {
-		r = &dev->resource[idx];
+	for_each_pci_dev_bridge_resource(dev, r, idx) {
 		if ((r->flags & type_mask) != type)
 			continue;
 		if (!r->parent)
@@ -1313,9 +1309,9 @@ static void __init pci_realloc_detect(void)
 
 	for_each_pci_dev(dev) {
 		int i;
+		struct resource *r;
 
-		for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) {
-			struct resource *r = &dev->resource[i];
+		for_each_pci_dev_iov_resource(dev, r, i) {
 
 			/* Not assigned, or rejected by kernel ? */
 			if (r->flags && !r->start) {
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 48251e3..4c6c924 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -104,7 +104,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)
 
 int pci_claim_resource(struct pci_dev *dev, int resource)
 {
-	struct resource *res = &dev->resource[resource];
+	struct resource *res = pci_dev_resource_n(dev, resource);
 	struct resource *root, *conflict;
 
 	root = pci_find_parent_resource(dev, res);
@@ -142,7 +142,7 @@ void pci_disable_bridge_window(struct pci_dev *dev)
 static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
 		int resno, resource_size_t size, resource_size_t align)
 {
-	struct resource *res = dev->resource + resno;
+	struct resource *res = pci_dev_resource_n(dev, resno);
 	resource_size_t min;
 	int ret;
 
@@ -220,7 +220,7 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
 
 static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align)
 {
-	struct resource *res = dev->resource + resno;
+	struct resource *res = pci_dev_resource_n(dev, resno);
 	struct pci_bus *bus;
 	int ret;
 	char *type;
@@ -253,7 +253,7 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resour
 int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsize,
 			resource_size_t min_align)
 {
-	struct resource *res = dev->resource + resno;
+	struct resource *res = pci_dev_resource_n(dev, resno);
 	resource_size_t new_size;
 	int ret;
 
@@ -277,7 +277,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
 
 int pci_assign_resource(struct pci_dev *dev, int resno)
 {
-	struct resource *res = dev->resource + resno;
+	struct resource *res = pci_dev_resource_n(dev, resno);
 	resource_size_t align, size;
 	struct pci_bus *bus;
 	int ret;
@@ -319,12 +319,10 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	old_cmd = cmd;
 
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+	for_each_pci_dev_all_resource(dev, r, i) {
 		if (!(mask & (1 << i)))
 			continue;
 
-		r = &dev->resource[i];
-
 		if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
 			continue;
 		if ((i == PCI_ROM_RESOURCE) &&
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 9c43ab4..9ae41ba 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -393,9 +393,7 @@ static int pcifront_claim_resource(struct pci_dev *dev, void *data)
 	int i;
 	struct resource *r;
 
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		r = &dev->resource[i];
-
+	for_each_pci_dev_all_resource(dev, r, i) {
 		if (!r->parent && r->start && r->flags) {
 			dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n",
 				pci_name(dev), i);
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (5 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 06/12] PCI: Use for_each_pci_dev_resource helper Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-15 21:36   ` Bjorn Helgaas
  2012-03-13  7:26 ` [PATCH 08/12] PCI: Make quirk_io_region " Yinghai Lu
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

after they are put in add-on resources, they will be safely claimed later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/quirks.c |   93 +++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 77 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 7ef4183..cbe7dd9 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -383,14 +383,14 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M7101,		quirk_ali7101_acpi);
 
-static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
+static int piix4_read_io(struct pci_dev *dev, struct resource *res, int port)
 {
 	u32 devres;
 	u32 mask, size, base;
+	struct pci_bus_region bus_region;
 
 	pci_read_config_dword(dev, port, &devres);
-	if ((devres & enable) != enable)
-		return;
+
 	mask = (devres >> 16) & 15;
 	base = devres & 0xffff;
 	size = 16;
@@ -400,23 +400,53 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p
 			break;
 		size = bit;
 	}
-	/*
-	 * For now we only print it out. Eventually we'll want to
-	 * reserve it (at least if it's in the 0x1000+ range), but
-	 * let's get enough confirmation reports first. 
-	 */
 	base &= -size;
-	dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base + size - 1);
+
+	bus_region.start = base;
+	bus_region.end = base + size - 1;
+	res->flags |= IORESOURCE_IO;
+	pcibios_bus_to_resource(dev, res, &bus_region);
+	dev_info(&dev->dev, "PIO at %pR\n", res);
+
+	return 0;
 }
+static int piix4_write_io(struct pci_dev *dev, struct resource *res, int port)
+{
+	u32 devres;
+	struct pci_bus_region bus_region;
+
+	pcibios_resource_to_bus(dev, &bus_region, res);
 
-static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
+	pci_read_config_dword(dev, port, &devres);
+	devres &= 0xffff0000;
+	devres |= bus_region.start & 0xffff;
+	pci_write_config_dword(dev, port, devres);
+
+	return 0;
+}
+static struct resource_ops piix4_io_ops = {
+	.read = piix4_read_io,
+	.write = piix4_write_io,
+};
+static void piix4_io_quirk(struct pci_dev *dev, char *name, unsigned int port,
+				unsigned int enable)
 {
 	u32 devres;
-	u32 mask, size, base;
 
 	pci_read_config_dword(dev, port, &devres);
 	if ((devres & enable) != enable)
 		return;
+
+	add_pci_dev_addon_resource(dev, port, 0, &piix4_io_ops, name);
+}
+
+static int piix4_read_mem(struct pci_dev *dev, struct resource *res, int port)
+{
+	u32 devres;
+	u32 mask, size, base;
+	struct pci_bus_region bus_region;
+
+	pci_read_config_dword(dev, port, &devres);
 	base = devres & 0xffff0000;
 	mask = (devres & 0x3f) << 16;
 	size = 128 << 16;
@@ -426,12 +456,43 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
 			break;
 		size = bit;
 	}
-	/*
-	 * For now we only print it out. Eventually we'll want to
-	 * reserve it, but let's get enough confirmation reports first. 
-	 */
 	base &= -size;
-	dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1);
+	bus_region.start = base;
+	bus_region.end = base + size - 1;
+	res->flags |= IORESOURCE_MEM;
+	pcibios_bus_to_resource(dev, res, &bus_region);
+	dev_info(&dev->dev, "MMIO at %pR\n", res);
+
+	return 0;
+}
+static int piix4_write_mem(struct pci_dev *dev, struct resource *res, int port)
+{
+	u32 devres;
+	struct pci_bus_region bus_region;
+
+	pcibios_resource_to_bus(dev, &bus_region, res);
+
+	pci_read_config_dword(dev, port, &devres);
+	devres &= 0x0000ffff;
+	devres |= bus_region.start & 0xffff0000;
+	pci_write_config_dword(dev, port, devres);
+
+	return 0;
+}
+static struct resource_ops piix4_mem_ops = {
+	.read = piix4_read_mem,
+	.write = piix4_write_mem,
+};
+static void piix4_mem_quirk(struct pci_dev *dev, char *name, unsigned int port,
+				unsigned int enable)
+{
+	u32 devres;
+
+	pci_read_config_dword(dev, port, &devres);
+	if ((devres & enable) != enable)
+		return;
+
+	add_pci_dev_addon_resource(dev, port, 0, &piix4_mem_ops, name);
 }
 
 /*
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/12] PCI: Make quirk_io_region to use addon_resource support
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (6 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 09/12] PCI: Use addon_fixed_resource with ati fixed resource Yinghai Lu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

after they are put in add-on resources, they will be safely claimed later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/quirks.c |  155 ++++++++++++++++++++++---------------------------
 1 files changed, 70 insertions(+), 85 deletions(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index cbe7dd9..4561610 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -324,29 +324,61 @@ static void __devinit quirk_cs5536_vsa(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA, quirk_cs5536_vsa);
 
-static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region,
-	unsigned size, int nr, const char *name)
+static int quirk_read_io(struct pci_dev *dev, struct resource *res, int port)
 {
-	region &= ~(size-1);
-	if (region) {
-		struct pci_bus_region bus_region;
-		struct resource *res = dev->resource + nr;
+	struct pci_bus_region bus_region;
+	u16 region;
+	unsigned size = to_pci_dev_addon_resource(res)->size;
 
-		res->name = pci_name(dev);
-		res->start = region;
-		res->end = region + size - 1;
-		res->flags = IORESOURCE_IO;
+	pci_read_config_word(dev, port, &region);
+	region &= ~(size - 1);
 
-		/* Convert from PCI bus to resource space.  */
-		bus_region.start = res->start;
-		bus_region.end = res->end;
-		pcibios_bus_to_resource(dev, res, &bus_region);
+	/* Convert from PCI bus to resource space.  */
+	bus_region.start = region;
+	bus_region.end = region + size - 1;
 
-		if (pci_claim_resource(dev, nr) == 0)
-			dev_info(&dev->dev, "quirk: %pR claimed by %s\n",
-				 res, name);
-	}
-}	
+	pcibios_bus_to_resource(dev, res, &bus_region);
+
+	res->flags |= IORESOURCE_IO;
+	dev_info(&dev->dev, "PIO at %pR\n", res);
+
+	return 0;
+}
+static int quirk_write_io(struct pci_dev *dev, struct resource *res, int port)
+{
+	struct pci_bus_region bus_region;
+	u16 region;
+	unsigned size = to_pci_dev_addon_resource(res)->size;
+
+	pci_read_config_word(dev, port, &region);
+	region &= size - 1;
+
+	/* Convert to PCI bus space.  */
+	pcibios_resource_to_bus(dev, &bus_region, res);
+	region |= bus_region.start & (~(size - 1));
+
+	pci_write_config_word(dev, port, region);
+
+	return 0;
+}
+static struct resource_ops quirk_io_ops = {
+	.read = quirk_read_io,
+	.write = quirk_write_io,
+};
+
+static void __devinit quirk_io_region(struct pci_dev *dev, int port,
+					unsigned size, char *name)
+{
+	u16 region;
+
+	pci_read_config_word(dev, port, &region);
+	region &= size - 1;
+
+	if (!region)
+		return;
+
+	add_pci_dev_addon_resource(dev, port, size, &quirk_io_ops, name);
+}
 
 /*
  *	ATI Northbridge setups MCE the processor if you even
@@ -374,12 +406,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_RS100,   quirk_ati_
  */
 static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
 {
-	u16 region;
-
-	pci_read_config_word(dev, 0xE0, &region);
-	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "ali7101 ACPI");
-	pci_read_config_word(dev, 0xE2, &region);
-	quirk_io_region(dev, region, 32, PCI_BRIDGE_RESOURCES+1, "ali7101 SMB");
+	quirk_io_region(dev, 0xE0, 64, "ali7101 ACPI");
+	quirk_io_region(dev, 0xE2, 32, "ali7101 SMB");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL,	PCI_DEVICE_ID_AL_M7101,		quirk_ali7101_acpi);
 
@@ -503,12 +531,10 @@ static void piix4_mem_quirk(struct pci_dev *dev, char *name, unsigned int port,
  */
 static void __devinit quirk_piix4_acpi(struct pci_dev *dev)
 {
-	u32 region, res_a;
+	u32 res_a;
 
-	pci_read_config_dword(dev, 0x40, &region);
-	quirk_io_region(dev, region, 64, PCI_BRIDGE_RESOURCES, "PIIX4 ACPI");
-	pci_read_config_dword(dev, 0x90, &region);
-	quirk_io_region(dev, region, 16, PCI_BRIDGE_RESOURCES+1, "PIIX4 SMB");
+	quirk_io_region(dev, 0x40, 64, "PIIX4 ACPI");
+	quirk_io_region(dev, 0x90, 16, "PIIX4 SMB");
 
 	/* Device resource A has enables for some of the other ones */
 	pci_read_config_dword(dev, 0x5c, &res_a);
@@ -552,7 +578,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82443MX_3,	qui
  */
 static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
 {
-	u32 region;
 	u8 enable;
 
 	/*
@@ -564,22 +589,12 @@ static void __devinit quirk_ich4_lpc_acpi(struct pci_dev *dev)
 	*/
 
 	pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable);
-	if (enable & ICH4_ACPI_EN) {
-		pci_read_config_dword(dev, ICH_PMBASE, &region);
-		region &= PCI_BASE_ADDRESS_IO_MASK;
-		if (region >= PCIBIOS_MIN_IO)
-			quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES,
-					"ICH4 ACPI/GPIO/TCO");
-	}
+	if (enable & ICH4_ACPI_EN)
+		quirk_io_region(dev, ICH_PMBASE, 128, "ICH4 ACPI/GPIO/TCO");
 
 	pci_read_config_byte(dev, ICH4_GPIO_CNTL, &enable);
-	if (enable & ICH4_GPIO_EN) {
-		pci_read_config_dword(dev, ICH4_GPIOBASE, &region);
-		region &= PCI_BASE_ADDRESS_IO_MASK;
-		if (region >= PCIBIOS_MIN_IO)
-			quirk_io_region(dev, region, 64,
-					PCI_BRIDGE_RESOURCES + 1, "ICH4 GPIO");
-	}
+	if (enable & ICH4_GPIO_EN)
+		quirk_io_region(dev, ICH4_GPIOBASE, 64, "ICH4 GPIO");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AA_0,		quirk_ich4_lpc_acpi);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82801AB_0,		quirk_ich4_lpc_acpi);
@@ -594,26 +609,15 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ESB_1,		qui
 
 static void __devinit ich6_lpc_acpi_gpio(struct pci_dev *dev)
 {
-	u32 region;
 	u8 enable;
 
 	pci_read_config_byte(dev, ICH_ACPI_CNTL, &enable);
-	if (enable & ICH6_ACPI_EN) {
-		pci_read_config_dword(dev, ICH_PMBASE, &region);
-		region &= PCI_BASE_ADDRESS_IO_MASK;
-		if (region >= PCIBIOS_MIN_IO)
-			quirk_io_region(dev, region, 128, PCI_BRIDGE_RESOURCES,
-					"ICH6 ACPI/GPIO/TCO");
-	}
+	if (enable & ICH6_ACPI_EN)
+		quirk_io_region(dev, ICH_PMBASE, 128, "ICH6 ACPI/GPIO/TCO");
 
 	pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable);
-	if (enable & ICH6_GPIO_EN) {
-		pci_read_config_dword(dev, ICH6_GPIOBASE, &region);
-		region &= PCI_BASE_ADDRESS_IO_MASK;
-		if (region >= PCIBIOS_MIN_IO)
-			quirk_io_region(dev, region, 64,
-					PCI_BRIDGE_RESOURCES + 1, "ICH6 GPIO");
-	}
+	if (enable & ICH6_GPIO_EN)
+		quirk_io_region(dev, ICH6_GPIOBASE, 64, "ICH6 GPIO");
 }
 
 static void __devinit ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const char *name, int dynsize)
@@ -711,13 +715,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_ICH10_1, qui
  */
 static void __devinit quirk_vt82c586_acpi(struct pci_dev *dev)
 {
-	u32 region;
-
-	if (dev->revision & 0x10) {
-		pci_read_config_dword(dev, 0x48, &region);
-		region &= PCI_BASE_ADDRESS_IO_MASK;
-		quirk_io_region(dev, region, 256, PCI_BRIDGE_RESOURCES, "vt82c586 ACPI");
-	}
+	if (dev->revision & 0x10)
+		quirk_io_region(dev, 0x48, 256, "vt82c586 ACPI");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_vt82c586_acpi);
 
@@ -729,18 +728,11 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C586_3,	quirk_vt
  */
 static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev)
 {
-	u16 hm;
-	u32 smb;
-
 	quirk_vt82c586_acpi(dev);
 
-	pci_read_config_word(dev, 0x70, &hm);
-	hm &= PCI_BASE_ADDRESS_IO_MASK;
-	quirk_io_region(dev, hm, 128, PCI_BRIDGE_RESOURCES + 1, "vt82c686 HW-mon");
+	quirk_io_region(dev, 0x70, 128, "vt82c686 HW-mon");
 
-	pci_read_config_dword(dev, 0x90, &smb);
-	smb &= PCI_BASE_ADDRESS_IO_MASK;
-	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 2, "vt82c686 SMB");
+	quirk_io_region(dev, 0x90, 16, "vt82c686 SMB");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt82c686_acpi);
 
@@ -751,15 +743,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_82C686_4,	quirk_vt
  */
 static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
 {
-	u16 pm, smb;
-
-	pci_read_config_word(dev, 0x88, &pm);
-	pm &= PCI_BASE_ADDRESS_IO_MASK;
-	quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES, "vt8235 PM");
-
-	pci_read_config_word(dev, 0xd0, &smb);
-	smb &= PCI_BASE_ADDRESS_IO_MASK;
-	quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1, "vt8235 SMB");
+	quirk_io_region(dev, 0x88, 128, "vt8235 PM");
+	quirk_io_region(dev, 0xd0, 16, "vt8235 SMB");
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,	PCI_DEVICE_ID_VIA_8235,	quirk_vt8235_acpi);
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/12] PCI: Use addon_fixed_resource with ati fixed resource
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (7 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 08/12] PCI: Make quirk_io_region " Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge() Yinghai Lu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

after they are put in add-on resources, they will be safely claimed later.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/quirks.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 4561610..76dd901 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -386,10 +386,12 @@ static void __devinit quirk_io_region(struct pci_dev *dev, int port,
  */
 static void __devinit quirk_ati_exploding_mce(struct pci_dev *dev)
 {
-	dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
+	dev_info(&dev->dev, "ATI Northbridge, will reserve I/O ports 0x3b0 to 0x3bb\n");
 	/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
-	request_region(0x3b0, 0x0C, "RadeonIGP");
-	request_region(0x3d3, 0x01, "RadeonIGP");
+	add_pci_dev_addon_fixed_resource(dev, 0x3B0, 0x0C, IORESOURCE_IO, 0,
+					 "RadeonIGP");
+	add_pci_dev_addon_fixed_resource(dev, 0x3d3, 0x01, IORESOURCE_IO, 0,
+					 "RadeonIGP");
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI,	PCI_DEVICE_ID_ATI_RS100,   quirk_ati_exploding_mce);
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge()
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (8 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 09/12] PCI: Use addon_fixed_resource with ati fixed resource Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-15 21:42   ` Bjorn Helgaas
  2012-03-13  7:26 ` [PATCH 11/12] PCI, cphi_hotplug: Simplify configure_slot Yinghai Lu
  2012-03-13  7:26 ` [PATCH 12/12] PCI, shpchp: Simplify configure_device Yinghai Lu
  11 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

Will use it for other pci hp hotplug support

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug-pci.c        |   13 +++++++++++++
 drivers/pci/hotplug/pciehp_pci.c |   18 ++----------------
 drivers/pci/pci.h                |    1 +
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c
index d3509cd..d0999b1 100644
--- a/drivers/pci/hotplug-pci.c
+++ b/drivers/pci/hotplug-pci.c
@@ -4,6 +4,19 @@
 #include <linux/export.h>
 #include "pci.h"
 
+int __ref pci_hp_add_bridge(struct pci_dev *dev)
+{
+	struct pci_bus *parent = dev->bus;
+	int pass, busnr = parent->secondary;
+
+	for (pass = 0; pass < 2; pass++)
+		busnr = pci_scan_bridge(parent, dev, busnr, pass);
+	if (!dev->subordinate)
+		return -1;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_hp_add_bridge);
 
 unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
 {
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index e21171c..b9a9fce 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -34,19 +34,6 @@
 #include "../pci.h"
 #include "pciehp.h"
 
-static int __ref pciehp_add_bridge(struct pci_dev *dev)
-{
-	struct pci_bus *parent = dev->bus;
-	int pass, busnr = parent->secondary;
-
-	for (pass = 0; pass < 2; pass++)
-		busnr = pci_scan_bridge(parent, dev, busnr, pass);
-	if (!dev->subordinate)
-		return -1;
-
-	return 0;
-}
-
 int pciehp_configure_device(struct slot *p_slot)
 {
 	struct pci_dev *dev;
@@ -75,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot)
 		if (!dev)
 			continue;
 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
-				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
-			pciehp_add_bridge(dev);
-		}
+		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
+			pci_hp_add_bridge(dev);
 		pci_dev_put(dev);
 	}
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 13b1159..9378d81 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -124,6 +124,7 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
 #endif
 
 /* Functions for PCI Hotplug drivers to use */
+int pci_hp_add_bridge(struct pci_dev *dev);
 extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
 
 #ifdef HAVE_PCI_LEGACY
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/12] PCI, cphi_hotplug: Simplify configure_slot
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (9 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge() Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  2012-03-13  7:26 ` [PATCH 12/12] PCI, shpchp: Simplify configure_device Yinghai Lu
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

For child p2p bridge hotplug support should use pci_scan_bridge instead.

Make it more simillar to pciehp, just use pci_hp_add_bridge()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug/cpci_hotplug_pci.c |   35 +++++--------------------------
 1 files changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index 4ef80ad..dcc75c7 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -285,42 +285,19 @@ int __ref cpci_configure_slot(struct slot *slot)
 	for (fn = 0; fn < 8; fn++) {
 		struct pci_dev *dev;
 
-		dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
+		dev = pci_get_slot(parent,
+				   PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
 		if (!dev)
 			continue;
 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
-		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
-			/* Find an unused bus number for the new bridge */
-			struct pci_bus *child;
-			unsigned char busnr, start = parent->secondary;
-			unsigned char end = parent->subordinate;
-
-			for (busnr = start; busnr <= end; busnr++) {
-				if (!pci_find_bus(pci_domain_nr(parent),
-						  busnr))
-					break;
-			}
-			if (busnr >= end) {
-				err("No free bus for hot-added bridge\n");
-				pci_dev_put(dev);
-				continue;
-			}
-			child = pci_add_new_bus(parent, dev, busnr);
-			if (!child) {
-				err("Cannot add new bus for %s\n",
-				    pci_name(dev));
-				pci_dev_put(dev);
-				continue;
-			}
-			child->subordinate = pci_do_scan_bus(child);
-			pci_bus_size_bridges_with_self(child);
-		}
+		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
+			pci_hp_add_bridge(dev);
 		pci_dev_put(dev);
 	}
 
-	pci_bus_assign_resources(parent);
+	pci_assign_unassigned_bridge_resources(parent->self);
+
 	pci_bus_add_devices(parent);
-	pci_enable_bridges(parent);
 
 	dbg("%s - exit", __func__);
 	return 0;
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/12] PCI, shpchp: Simplify configure_device
  2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
                   ` (10 preceding siblings ...)
  2012-03-13  7:26 ` [PATCH 11/12] PCI, cphi_hotplug: Simplify configure_slot Yinghai Lu
@ 2012-03-13  7:26 ` Yinghai Lu
  11 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-13  7:26 UTC (permalink / raw)
  To: Jesse Barnes, x86
  Cc: Bjorn Helgaas, Andrew Morton, Linus Torvalds, Greg Kroah-Hartman,
	linux-pci, linux-kernel, Yinghai Lu

For child p2p bridge hotplug support should use pci_scan_bridge instead.

Make it more simillar to pciehp, just use pci_hp_add_bridge()

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/hotplug/shpchp_pci.c |   45 ++++++++++++-------------------------
 1 files changed, 15 insertions(+), 30 deletions(-)

diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index d92807b..c627ed9 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -37,9 +37,10 @@
 int __ref shpchp_configure_device(struct slot *p_slot)
 {
 	struct pci_dev *dev;
-	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
-	int num, fn;
 	struct controller *ctrl = p_slot->ctrl;
+	struct pci_dev *bridge = ctrl->pci_dev;
+	struct pci_bus *parent = bridge->subordinate;
+	int num, fn;
 
 	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
 	if (dev) {
@@ -61,39 +62,23 @@ int __ref shpchp_configure_device(struct slot *p_slot)
 		if (!dev)
 			continue;
 		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
-				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
-			/* Find an unused bus number for the new bridge */
-			struct pci_bus *child;
-			unsigned char busnr, start = parent->secondary;
-			unsigned char end = parent->subordinate;
-			for (busnr = start; busnr <= end; busnr++) {
-				if (!pci_find_bus(pci_domain_nr(parent),
-							busnr))
-					break;
-			}
-			if (busnr > end) {
-				ctrl_err(ctrl,
-					 "No free bus for hot-added bridge\n");
-				pci_dev_put(dev);
-				continue;
-			}
-			child = pci_add_new_bus(parent, dev, busnr);
-			if (!child) {
-				ctrl_err(ctrl, "Cannot add new bus for %s\n",
-					 pci_name(dev));
-				pci_dev_put(dev);
-				continue;
-			}
-			child->subordinate = pci_do_scan_bus(child);
-			pci_bus_size_bridges_with_self(child);
-		}
+		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
+			pci_hp_add_bridge(dev);
+		pci_dev_put(dev);
+	}
+
+	pci_assign_unassigned_bridge_resources(bridge);
+
+	for (fn = 0; fn < 8; fn++) {
+		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
+		if (!dev)
+			continue;
 		pci_configure_slot(dev);
 		pci_dev_put(dev);
 	}
 
-	pci_bus_assign_resources(parent);
 	pci_bus_add_devices(parent);
-	pci_enable_bridges(parent);
+
 	return 0;
 }
 
-- 
1.7.7


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 05/12] PCI: Add addon_resource support for pci_dev
  2012-03-13  7:26 ` [PATCH 05/12] PCI: Add addon_resource support for pci_dev Yinghai Lu
@ 2012-03-15 21:30   ` Bjorn Helgaas
  2012-03-16  3:23     ` Yinghai Lu
  0 siblings, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 21:30 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
	Greg Kroah-Hartman, linux-pci, linux-kernel

On Tue, Mar 13, 2012 at 1:26 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> Will add addon_resources list in pci_dev, it will be used for resources
> other than stand, rom, sriov, bridges.
> Some could be same as std reg, but using different register.
> Some could have own way to read/write to them.
>
> Kernel using different way to hack those resources like abusing
> pci bridge resource spot on non bridge pci device.
>
> With this patch, will treat addon-resource like standard resource with
> special ops.
>
> Also adding bunch of for_each... helpers to make resource loop easier.

There are some interesting ideas here.  Do they all have to be in the
same patch?

  - for_each...() helpers
  - pci_dev_resource_n() stuff
  - addon resource stuff
  - addon resource ops

> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/pci.c       |    7 +++
>  drivers/pci/probe.c     |  108 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/setup-res.c |   24 ++++++++---
>  include/linux/pci.h     |   77 ++++++++++++++++++++++++++++++++-
>  4 files changed, 207 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 32ab301..af84abf 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3545,6 +3545,13 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
>                reg = pci_iov_resource_bar(dev, resno, type);
>                if (reg)
>                        return reg;
> +       } else if (resno >= PCI_NUM_RESOURCES) {
> +               struct resource *res = pci_dev_resource_n(dev, resno);
> +
> +               if (res) {
> +                       *type = pci_bar_unknown;
> +                       return to_pci_dev_addon_resource(res)->reg_addr;
> +               }
>        }
>
>        dev_err(&dev->dev, "BAR %d: invalid resource\n", resno);
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 972553b..dac829f 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -75,6 +75,111 @@ static int __init pcibus_class_init(void)
>  }
>  postcore_initcall(pcibus_class_init);
>
> +struct resource *pci_dev_resource_n(struct pci_dev *dev, int n)
> +{
> +       struct pci_dev_addon_resource *addon_res;
> +
> +       if (n < PCI_NUM_RESOURCES)
> +               return &dev->resource[n];
> +
> +       n -= PCI_NUM_RESOURCES;
> +       list_for_each_entry(addon_res, &dev->addon_resources, list) {
> +               if (n-- == 0)
> +                       return &addon_res->res;
> +       }
> +       return NULL;
> +}
> +
> +int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res)
> +{
> +       int i;
> +       struct resource *r;
> +
> +       for_each_pci_dev_all_resource(dev, r, i)
> +               if (r == res)
> +                       return i;
> +
> +       return -1;
> +}
> +
> +struct pci_dev_addon_resource *__add_pci_dev_addon_resource(
> +                struct pci_dev *dev, int addr, char *name)
> +{
> +       struct pci_dev_addon_resource *addon_res;
> +
> +       addon_res = kzalloc(sizeof(*addon_res), GFP_KERNEL);
> +
> +       if (!addon_res)
> +               return NULL;
> +
> +       addon_res->reg_addr = addr;
> +
> +       if (name)
> +               addon_res->res.name = name;
> +       else
> +               addon_res->res.name = pci_name(dev);
> +
> +       list_add_tail(&addon_res->list, &dev->addon_resources);
> +
> +       return addon_res;
> +}
> +
> +struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource(
> +                struct pci_dev *dev, int start, int size, int flags,
> +                int addr, char *name)
> +{
> +       struct pci_dev_addon_resource *addon_res;
> +       struct resource *res;
> +
> +       addon_res = __add_pci_dev_addon_resource(dev, addr, name);
> +       if (addon_res)
> +               return NULL;
> +
> +       res = &addon_res->res;
> +       res->start = start;
> +       res->end = start + size - 1;
> +       res->flags = flags | IORESOURCE_PCI_FIXED;
> +
> +       dev_printk(KERN_DEBUG, &dev->dev,
> +                  "addon fixed resource %s %pR added\n", res->name, res);
> +
> +       return addon_res;
> +}
> +
> +struct pci_dev_addon_resource *add_pci_dev_addon_resource(struct pci_dev *dev,
> +                int addr, int size, struct resource_ops *ops, char *name)
> +{
> +       struct pci_dev_addon_resource *addon_res;
> +       struct resource *res;
> +
> +       addon_res = __add_pci_dev_addon_resource(dev, addr, name);
> +       if (!addon_res)
> +               return NULL;
> +
> +       res = &addon_res->res;
> +       if (ops) {
> +               addon_res->ops = ops;
> +               addon_res->size = size;
> +               ops->read(dev, res, addr);
> +       } else
> +               __pci_read_base(dev, pci_bar_unknown, res, addr);
> +
> +       dev_printk(KERN_DEBUG, &dev->dev,
> +                  "addon resource %s %pR added\n", res->name, res);
> +
> +       return addon_res;
> +}
> +
> +static void pci_release_dev_addon_res(struct pci_dev *dev)
> +{
> +       struct pci_dev_addon_resource *addon_res, *tmp;
> +
> +       list_for_each_entry_safe(addon_res, tmp, &dev->addon_resources, list) {
> +               list_del(&addon_res->list);
> +               kfree(addon_res);
> +       }
> +}
> +
>  static u64 pci_size(u64 base, u64 maxbase, u64 mask)
>  {
>        u64 size = mask & maxbase;      /* Find the significant bits */
> @@ -1283,6 +1388,7 @@ static void pci_release_dev(struct device *dev)
>        pci_dev = to_pci_dev(dev);
>        pci_release_capabilities(pci_dev);
>        pci_release_of_node(pci_dev);
> +       pci_release_dev_addon_res(pci_dev);
>        kfree(pci_dev);
>  }
>
> @@ -1362,11 +1468,13 @@ struct pci_dev *alloc_pci_dev(void)
>                return NULL;
>
>        INIT_LIST_HEAD(&dev->bus_list);
> +       INIT_LIST_HEAD(&dev->addon_resources);
>
>        return dev;
>  }
>  EXPORT_SYMBOL(alloc_pci_dev);
>
> +
>  bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
>                                 int crs_timeout)
>  {
> diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
> index eea85da..48251e3 100644
> --- a/drivers/pci/setup-res.c
> +++ b/drivers/pci/setup-res.c
> @@ -33,7 +33,7 @@ void pci_update_resource(struct pci_dev *dev, int resno)
>        u32 new, check, mask;
>        int reg;
>        enum pci_bar_type type;
> -       struct resource *res = dev->resource + resno;
> +       struct resource *res = pci_dev_resource_n(dev, resno);
>
>        /*
>         * Ignore resources for unimplemented BARs and unused resource slots
> @@ -50,6 +50,21 @@ void pci_update_resource(struct pci_dev *dev, int resno)
>        if (res->flags & IORESOURCE_PCI_FIXED)
>                return;
>
> +       if (resno >= PCI_NUM_RESOURCES) {
> +               struct pci_dev_addon_resource *addon_res;
> +
> +               addon_res = to_pci_dev_addon_resource(res);
> +               reg = addon_res->reg_addr;
> +               if (addon_res->ops) {
> +                       addon_res->ops->write(dev, res, reg);
> +                       return;
> +               }
> +       } else
> +               reg = pci_resource_bar(dev, resno, &type);
> +
> +       if (!reg)
> +               return;
> +
>        pcibios_resource_to_bus(dev, &region, res);
>
>        new = region.start | (res->flags & PCI_REGION_FLAG_MASK);
> @@ -58,9 +73,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)
>        else
>                mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
>
> -       reg = pci_resource_bar(dev, resno, &type);
> -       if (!reg)
> -               return;
>        if (type != pci_bar_unknown) {
>                if (!(res->flags & IORESOURCE_ROM_ENABLE))
>                        return;
> @@ -257,7 +269,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
>        if (!ret) {
>                res->flags &= ~IORESOURCE_STARTALIGN;
>                dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
> -               if (resno < PCI_BRIDGE_RESOURCES)
> +               if (!resno_is_for_bridge(resno))
>                        pci_update_resource(dev, resno);
>        }
>        return ret;
> @@ -292,7 +304,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
>        if (!ret) {
>                res->flags &= ~IORESOURCE_STARTALIGN;
>                dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
> -               if (resno < PCI_BRIDGE_RESOURCES)
> +               if (!resno_is_for_bridge(resno))
>                        pci_update_resource(dev, resno);
>        }
>        return ret;
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 161f6c0..173b8fe 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -299,6 +299,7 @@ struct pci_dev {
>         */
>        unsigned int    irq;
>        struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
> +       struct list_head addon_resources; /* addon I/O and memory resource */
>
>        /* These fields are used by common fixups */
>        unsigned int    transparent:1;  /* Transparent PCI bridge */
> @@ -347,6 +348,76 @@ struct pci_dev {
>  #endif
>  };
>
> +struct resource_ops {
> +       int (*read)(struct pci_dev *dev, struct resource *res, int addr);
> +       int (*write)(struct pci_dev *dev, struct resource *res, int addr);
> +};
> +
> +struct pci_dev_addon_resource {
> +       struct list_head list;
> +       int reg_addr;
> +       int size;
> +       struct resource res;
> +       struct resource_ops *ops;
> +};
> +#define        to_pci_dev_addon_resource(n) container_of(n, struct pci_dev_addon_resource, res)
> +
> +struct resource *pci_dev_resource_n(struct pci_dev *dev, int n);
> +int pci_dev_resource_idx(struct pci_dev *dev, struct resource *res);
> +struct pci_dev_addon_resource *add_pci_dev_addon_fixed_resource(
> +                struct pci_dev *dev, int start, int size, int flags,
> +                int addr, char *name);
> +struct pci_dev_addon_resource *add_pci_dev_addon_resource(struct pci_dev *dev,
> +                int addr, int size, struct resource_ops *ops, char *name);
> +
> +#define resno_is_for_bridge(n) ((n)>=PCI_BRIDGE_RESOURCES && (n)<=PCI_BRIDGE_RESOURCE_END)
> +
> +/* all (include bridge) resources */
> +#define for_each_pci_dev_all_resource(dev, res, i)                     \
> +       for (i = 0;                                                     \
> +            (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
> +            i++)
> +/* exclude bridge resources */
> +#define for_each_pci_dev_nobridge_resource(dev, res, i)                        \
> +       for (i = 0;                                                     \
> +            (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
> +            i = (i != (PCI_BRIDGE_RESOURCES - 1)) ? (i+1) : PCI_NUM_RESOURCES)
> +/* exclude bridge and IOV resources */
> +#define for_each_pci_dev_base_resource(dev, res, i)                    \
> +       for (i = 0;                                                     \
> +            (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
> +            i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_NUM_RESOURCES)
> +/* exclude ROM and bridge and IOV resources */
> +#define for_each_pci_dev_base_norom_resource(dev, res, i)              \
> +       for (i = 0;                                                     \
> +            (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
> +            i = (i != (PCI_ROM_RESOURCE-1)) ? (i+1) : PCI_NUM_RESOURCES)
> +/* exclude IOV resources */
> +#define for_each_pci_dev_noiov_resource(dev, res, i)                   \
> +       for (i = 0;                                                     \
> +            (res = pci_dev_resource_n(dev, i)) || i < PCI_NUM_RESOURCES; \
> +            i = (i != PCI_ROM_RESOURCE) ? (i+1) : PCI_BRIDGE_RESOURCES)
> +/* only std resources */
> +#define for_each_pci_dev_std_resource(dev, res, i)                     \
> +       for (i = PCI_STD_RESOURCES;                                     \
> +          (res = pci_dev_resource_n(dev, i)) && i < (PCI_STD_RESOURCE_END+1); \
> +            i++)
> +/* only IOV resources */
> +#define for_each_pci_dev_iov_resource(dev, res, i)                     \
> +       for (i = PCI_IOV_RESOURCES;                                     \
> +          (res = pci_dev_resource_n(dev, i)) && i < (PCI_IOV_RESOURCE_END+1); \
> +            i++)
> +/* only bridge resources */
> +#define for_each_pci_dev_bridge_resource(dev, res, i)                  \
> +       for (i = PCI_BRIDGE_RESOURCES;                                  \
> +       (res = pci_dev_resource_n(dev, i)) && i < (PCI_BRIDGE_RESOURCE_END+1); \
> +            i++)
> +/* only addon resources */
> +#define for_each_pci_dev_addon_resource(dev, res, i)                   \
> +       for (i = PCI_NUM_RESOURCES;                                     \
> +            (res = pci_dev_resource_n(dev, i));                        \
> +            i++)
> +
>  static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
>  {
>  #ifdef CONFIG_PCI_IOV
> @@ -1348,9 +1419,9 @@ static inline int pci_domain_nr(struct pci_bus *bus)
>
>  /* these helpers provide future and backwards compatibility
>  * for accessing popular PCI BAR info */
> -#define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
> -#define pci_resource_end(dev, bar)     ((dev)->resource[(bar)].end)
> -#define pci_resource_flags(dev, bar)   ((dev)->resource[(bar)].flags)
> +#define pci_resource_start(dev, bar)   (pci_dev_resource_n(dev, (bar))->start)
> +#define pci_resource_end(dev, bar)     (pci_dev_resource_n(dev, (bar))->end)
> +#define pci_resource_flags(dev, bar)   (pci_dev_resource_n(dev, (bar))->flags)
>  #define pci_resource_len(dev,bar) \
>        ((pci_resource_start((dev), (bar)) == 0 &&      \
>          pci_resource_end((dev), (bar)) ==             \
> --
> 1.7.7
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support
  2012-03-13  7:26 ` [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support Yinghai Lu
@ 2012-03-15 21:36   ` Bjorn Helgaas
  0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 21:36 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
	Greg Kroah-Hartman, linux-pci, linux-kernel

On Tue, Mar 13, 2012 at 1:26 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> after they are put in add-on resources, they will be safely claimed later.

Wow, this seems to do a lot more than you mention in the changelog.
Is this really just doing the same thing as it used to, but using some
new interfaces?  If so, too bad that it requires 60 more lines of code
than it used to.

> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/quirks.c |   93 +++++++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 77 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
> index 7ef4183..cbe7dd9 100644
> --- a/drivers/pci/quirks.c
> +++ b/drivers/pci/quirks.c
> @@ -383,14 +383,14 @@ static void __devinit quirk_ali7101_acpi(struct pci_dev *dev)
>  }
>  DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL,     PCI_DEVICE_ID_AL_M7101,         quirk_ali7101_acpi);
>
> -static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
> +static int piix4_read_io(struct pci_dev *dev, struct resource *res, int port)
>  {
>        u32 devres;
>        u32 mask, size, base;
> +       struct pci_bus_region bus_region;
>
>        pci_read_config_dword(dev, port, &devres);
> -       if ((devres & enable) != enable)
> -               return;
> +
>        mask = (devres >> 16) & 15;
>        base = devres & 0xffff;
>        size = 16;
> @@ -400,23 +400,53 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p
>                        break;
>                size = bit;
>        }
> -       /*
> -        * For now we only print it out. Eventually we'll want to
> -        * reserve it (at least if it's in the 0x1000+ range), but
> -        * let's get enough confirmation reports first.
> -        */
>        base &= -size;
> -       dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base + size - 1);
> +
> +       bus_region.start = base;
> +       bus_region.end = base + size - 1;
> +       res->flags |= IORESOURCE_IO;
> +       pcibios_bus_to_resource(dev, res, &bus_region);
> +       dev_info(&dev->dev, "PIO at %pR\n", res);
> +
> +       return 0;
>  }
> +static int piix4_write_io(struct pci_dev *dev, struct resource *res, int port)
> +{
> +       u32 devres;
> +       struct pci_bus_region bus_region;
> +
> +       pcibios_resource_to_bus(dev, &bus_region, res);
>
> -static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
> +       pci_read_config_dword(dev, port, &devres);
> +       devres &= 0xffff0000;
> +       devres |= bus_region.start & 0xffff;
> +       pci_write_config_dword(dev, port, devres);
> +
> +       return 0;
> +}
> +static struct resource_ops piix4_io_ops = {
> +       .read = piix4_read_io,
> +       .write = piix4_write_io,
> +};
> +static void piix4_io_quirk(struct pci_dev *dev, char *name, unsigned int port,
> +                               unsigned int enable)
>  {
>        u32 devres;
> -       u32 mask, size, base;
>
>        pci_read_config_dword(dev, port, &devres);
>        if ((devres & enable) != enable)
>                return;
> +
> +       add_pci_dev_addon_resource(dev, port, 0, &piix4_io_ops, name);
> +}
> +
> +static int piix4_read_mem(struct pci_dev *dev, struct resource *res, int port)
> +{
> +       u32 devres;
> +       u32 mask, size, base;
> +       struct pci_bus_region bus_region;
> +
> +       pci_read_config_dword(dev, port, &devres);
>        base = devres & 0xffff0000;
>        mask = (devres & 0x3f) << 16;
>        size = 128 << 16;
> @@ -426,12 +456,43 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
>                        break;
>                size = bit;
>        }
> -       /*
> -        * For now we only print it out. Eventually we'll want to
> -        * reserve it, but let's get enough confirmation reports first.
> -        */
>        base &= -size;
> -       dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1);
> +       bus_region.start = base;
> +       bus_region.end = base + size - 1;
> +       res->flags |= IORESOURCE_MEM;
> +       pcibios_bus_to_resource(dev, res, &bus_region);
> +       dev_info(&dev->dev, "MMIO at %pR\n", res);
> +
> +       return 0;
> +}
> +static int piix4_write_mem(struct pci_dev *dev, struct resource *res, int port)
> +{
> +       u32 devres;
> +       struct pci_bus_region bus_region;
> +
> +       pcibios_resource_to_bus(dev, &bus_region, res);
> +
> +       pci_read_config_dword(dev, port, &devres);
> +       devres &= 0x0000ffff;
> +       devres |= bus_region.start & 0xffff0000;
> +       pci_write_config_dword(dev, port, devres);
> +
> +       return 0;
> +}
> +static struct resource_ops piix4_mem_ops = {
> +       .read = piix4_read_mem,
> +       .write = piix4_write_mem,
> +};
> +static void piix4_mem_quirk(struct pci_dev *dev, char *name, unsigned int port,
> +                               unsigned int enable)
> +{
> +       u32 devres;
> +
> +       pci_read_config_dword(dev, port, &devres);
> +       if ((devres & enable) != enable)
> +               return;
> +
> +       add_pci_dev_addon_resource(dev, port, 0, &piix4_mem_ops, name);
>  }
>
>  /*
> --
> 1.7.7
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge()
  2012-03-13  7:26 ` [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge() Yinghai Lu
@ 2012-03-15 21:42   ` Bjorn Helgaas
  0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2012-03-15 21:42 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
	Greg Kroah-Hartman, linux-pci, linux-kernel

On Tue, Mar 13, 2012 at 1:26 AM, Yinghai Lu <yinghai@kernel.org> wrote:
> Will use it for other pci hp hotplug support
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/hotplug-pci.c        |   13 +++++++++++++
>  drivers/pci/hotplug/pciehp_pci.c |   18 ++----------------
>  drivers/pci/pci.h                |    1 +
>  3 files changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pci/hotplug-pci.c b/drivers/pci/hotplug-pci.c
> index d3509cd..d0999b1 100644
> --- a/drivers/pci/hotplug-pci.c
> +++ b/drivers/pci/hotplug-pci.c
> @@ -4,6 +4,19 @@
>  #include <linux/export.h>
>  #include "pci.h"
>
> +int __ref pci_hp_add_bridge(struct pci_dev *dev)
> +{
> +       struct pci_bus *parent = dev->bus;
> +       int pass, busnr = parent->secondary;
> +
> +       for (pass = 0; pass < 2; pass++)
> +               busnr = pci_scan_bridge(parent, dev, busnr, pass);
> +       if (!dev->subordinate)
> +               return -1;
> +
> +       return 0;
> +}
> +EXPORT_SYMBOL(pci_hp_add_bridge);

I'm not sure this is baked enough to use EXPORT_SYMBOL() rather than
EXPORT_SYMBOL_GPL().  For example, maybe we can use the same "add
bridge" interface we normally use, rather than inventing a new
hotplug-specific one.  Using EXPORT_SYMBOL() would force us to keep
this interface longer than we might want to.

>  unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
>  {
> diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
> index e21171c..b9a9fce 100644
> --- a/drivers/pci/hotplug/pciehp_pci.c
> +++ b/drivers/pci/hotplug/pciehp_pci.c
> @@ -34,19 +34,6 @@
>  #include "../pci.h"
>  #include "pciehp.h"
>
> -static int __ref pciehp_add_bridge(struct pci_dev *dev)
> -{
> -       struct pci_bus *parent = dev->bus;
> -       int pass, busnr = parent->secondary;
> -
> -       for (pass = 0; pass < 2; pass++)
> -               busnr = pci_scan_bridge(parent, dev, busnr, pass);
> -       if (!dev->subordinate)
> -               return -1;
> -
> -       return 0;
> -}
> -
>  int pciehp_configure_device(struct slot *p_slot)
>  {
>        struct pci_dev *dev;
> @@ -75,9 +62,8 @@ int pciehp_configure_device(struct slot *p_slot)
>                if (!dev)
>                        continue;
>                if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
> -                               (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
> -                       pciehp_add_bridge(dev);
> -               }
> +                   (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
> +                       pci_hp_add_bridge(dev);
>                pci_dev_put(dev);
>        }
>
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 13b1159..9378d81 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -124,6 +124,7 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
>  #endif
>
>  /* Functions for PCI Hotplug drivers to use */
> +int pci_hp_add_bridge(struct pci_dev *dev);
>  extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
>
>  #ifdef HAVE_PCI_LEGACY
> --
> 1.7.7
>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 05/12] PCI: Add addon_resource support for pci_dev
  2012-03-15 21:30   ` Bjorn Helgaas
@ 2012-03-16  3:23     ` Yinghai Lu
  0 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2012-03-16  3:23 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Jesse Barnes, x86, Andrew Morton, Linus Torvalds,
	Greg Kroah-Hartman, linux-pci, linux-kernel

On Thu, Mar 15, 2012 at 2:30 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>
> There are some interesting ideas here.  Do they all have to be in the
> same patch?
>
>  - for_each...() helpers
>  - pci_dev_resource_n() stuff
>  - addon resource stuff
>  - addon resource ops

ok, will split them to several ones.

Yinghai

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-03-16  3:23 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-13  7:26 [PATCH 00/12] PCI, x86: More pci hotplug related cleanup Yinghai Lu
2012-03-13  7:26 ` [PATCH 01/12] PCI: Add debug print out for pci related dev release Yinghai Lu
2012-03-13  7:26 ` [PATCH 02/12] x86, PCI: Let pcibios_allocate_bus_resources() take bus instead Yinghai Lu
2012-03-13  7:26 ` [PATCH 03/12] PCI: Claim hw/fw allocated resources in hot add path Yinghai Lu
2012-03-13  7:26 ` [PATCH 04/12] PCI: Kill pci_is_reassignedev() Yinghai Lu
2012-03-13  7:26 ` [PATCH 05/12] PCI: Add addon_resource support for pci_dev Yinghai Lu
2012-03-15 21:30   ` Bjorn Helgaas
2012-03-16  3:23     ` Yinghai Lu
2012-03-13  7:26 ` [PATCH 06/12] PCI: Use for_each_pci_dev_resource helper Yinghai Lu
2012-03-13  7:26 ` [PATCH 07/12] PCI: Make piix4 quirk to use addon_resource support Yinghai Lu
2012-03-15 21:36   ` Bjorn Helgaas
2012-03-13  7:26 ` [PATCH 08/12] PCI: Make quirk_io_region " Yinghai Lu
2012-03-13  7:26 ` [PATCH 09/12] PCI: Use addon_fixed_resource with ati fixed resource Yinghai Lu
2012-03-13  7:26 ` [PATCH 10/12] PCI, pciehp: Separate pci_hp_add_bridge() Yinghai Lu
2012-03-15 21:42   ` Bjorn Helgaas
2012-03-13  7:26 ` [PATCH 11/12] PCI, cphi_hotplug: Simplify configure_slot Yinghai Lu
2012-03-13  7:26 ` [PATCH 12/12] PCI, shpchp: Simplify configure_device Yinghai Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).