diff mbox

[v3] PCI: Only enable IO window if supported

Message ID CAE9FiQXd3MKjHWzauEiKxHQPeYCL0bqP_YUdD-sj1y3GZMPAHw@mail.gmail.com
State Not Applicable
Headers show

Commit Message

Yinghai Lu Aug. 7, 2015, 1:12 a.m. UTC
On Thu, Aug 6, 2015 at 5:32 PM, Guenter Roeck <linux@roeck-us.net> wrote:
> Assuming case 1) includes case 3), root bridge does not support IO,
> I have both case 1 and 2.
>
> Anyway, I think I am giving up. Sorry, I just fail to understand the
> use case(s) you are trying to cover.
>
> Why don't you submit a patch, I'll test it if it works for my use
> case, and if it works we ask Bjorn to apply it. My problem is quite
> simple: I don't want to get flooded with useless "no IO window" messages.
> How it is solved doesn't matter to me, as long as it is solved.
> Since you have a strong opinion on how it should be solved, we should
> go with your solution and not keep turning in circles forever.

Please check attached patch and post boot log.

Thanks

Yinghai
diff mbox

Patch

From: Guenter Roeck <linux@roeck-us.net>
Subject: [PATCH] PCI: Only try to assign io port only if root bus support that

The PCI subsystem always assumes that I/O is supported on root bus and
tries to assign an I/O window to each child bus even if that is not the
case.

This may result in messages such as:

  pcieport 0000:02:00.0: res[7]=[io  0x1000-0x0fff] get_res_add_size add_size 1000
  pcieport 0000:02:00.0: BAR 7: no space for [io  size 0x1000]
  pcieport 0000:02:00.0: BAR 7: failed to assign [io  size 0x1000]

for each bridge port, even if root does not support I/O in the first place.

To avoid this message, check if root bus supports I/O, then child bus
will inherit the setting from parent bus, and later during sizing and
assigning, check that bus flags and skip those resources.

[bhelgaas: reverse sense of new pci_bus_flags_t value]
[yinghai: only check root bus io port, and use flag on sizing and assigning]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
CC: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

---
 drivers/pci/probe.c     |    5 +++++
 drivers/pci/setup-bus.c |    9 +++++++++
 include/linux/pci.h     |    1 +
 3 files changed, 15 insertions(+)

Index: linux-2.6/drivers/pci/probe.c
===================================================================
--- linux-2.6.orig/drivers/pci/probe.c
+++ linux-2.6/drivers/pci/probe.c
@@ -340,6 +340,9 @@  static void pci_read_bridge_io(struct pc
 	struct pci_bus_region region;
 	struct resource *res;
 
+	if (!(child->bus_flags & PCI_BUS_FLAGS_ROOT_SUPPORTS_IO))
+		return;
+
 	io_mask = PCI_IO_RANGE_MASK;
 	io_granularity = 0x1000;
 	if (dev->io_window_1k) {
@@ -2070,6 +2073,8 @@  struct pci_bus *pci_create_root_bus(stru
 		} else
 			bus_addr[0] = '\0';
 		dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr);
+		if (resource_type(res) == IORESOURCE_IO)
+			b->bus_flags |= PCI_BUS_FLAGS_ROOT_SUPPORTS_IO;
 	}
 
 	down_write(&pci_bus_sem);
Index: linux-2.6/drivers/pci/setup-bus.c
===================================================================
--- linux-2.6.orig/drivers/pci/setup-bus.c
+++ linux-2.6/drivers/pci/setup-bus.c
@@ -156,6 +156,10 @@  static void pdev_sort_resources(struct p
 		if (r->flags & IORESOURCE_PCI_FIXED)
 			continue;
 
+		if ((r->flags & IORESOURCE_IO) &&
+		    !(dev->bus->bus_flags & PCI_BUS_FLAGS_ROOT_SUPPORTS_IO))
+			continue;
+
 		if (!(r->flags) || r->parent)
 			continue;
 
@@ -912,6 +916,11 @@  static void pbus_size_io(struct pci_bus
 	if (!b_res)
 		return;
 
+	if (!(bus->bus_flags & PCI_BUS_FLAGS_ROOT_SUPPORTS_IO)) {
+		b_res->flags = 0;
+		return;
+	}
+
 	min_align = window_alignment(bus, IORESOURCE_IO);
 	list_for_each_entry(dev, &bus->devices, bus_list) {
 		int i;
Index: linux-2.6/include/linux/pci.h
===================================================================
--- linux-2.6.orig/include/linux/pci.h
+++ linux-2.6/include/linux/pci.h
@@ -193,6 +193,7 @@  typedef unsigned short __bitwise pci_bus
 enum pci_bus_flags {
 	PCI_BUS_FLAGS_NO_MSI   = (__force pci_bus_flags_t) 1,
 	PCI_BUS_FLAGS_NO_MMRBC = (__force pci_bus_flags_t) 2,
+	PCI_BUS_FLAGS_ROOT_SUPPORTS_IO = (__force pci_bus_flags_t) 4,
 };
 
 /* These values come from the PCI Express Spec */