linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Guo Chao <yan@linux.vnet.ibm.com>
To: linux-pci@vger.kernel.org
Cc: bhelgaas@google.com, yinghai@kernel.org
Subject: [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address
Date: Tue, 19 Nov 2013 14:36:56 +0800	[thread overview]
Message-ID: <1384843018-9479-2-git-send-email-yan@linux.vnet.ibm.com> (raw)
In-Reply-To: <1384843018-9479-1-git-send-email-yan@linux.vnet.ibm.com>

In resource assignment code, limits are exerted to restrict allocated
resource range. However these limits are PCI address but compared to
CPU address in the end. Translated them before comparing.

We can't just use pcibios_bus_to_resource because the limits may not
included in the host bridge window. Introduce a help function to
do this translation, if address missed, return an approximate one.

Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com>
---
 drivers/pci/bus.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index fc1b740..532c0a4 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -99,6 +99,64 @@ void pci_bus_remove_resources(struct pci_bus *bus)
 }
 
 /**
+ * pci_bus_to_resource
+ *
+ * Much like pcibios_bus_to_resource() except it takes a single address
+ * and returns an approximate one if target address is not included
+ * in the bridge window. The approximate address is smaller than required
+ * one is 'bound' is 1, larger than required one if 'bound' is 0.
+ */
+static resource_size_t pci_bus_to_resource(struct pci_bus *bus, int flags,
+				    int mask, resource_size_t addr, int bound)
+{
+	struct pci_host_bridge *bridge;
+	struct pci_host_bridge_window *window, *match = NULL;
+	resource_size_t max = 0, min = -1;
+	resource_size_t offset = -1, start, end;
+
+	while (bus->parent)
+		bus = bus->parent;
+
+	bridge = to_pci_host_bridge(bus->bridge);
+
+	list_for_each_entry(window, &bridge->windows, list) {
+		if ((flags ^ window->res->flags) & mask)
+			continue;
+
+		start = window->res->start - window->offset;
+		end = window->res->end - window->offset;
+
+		if (addr >= start && addr <= end) {
+			offset = window->offset;
+			break;
+		}
+
+		if (bound && addr > end && end > max) {
+			max = end;
+			match = window;
+		} else if (!bound && addr < start && start < min) {
+			min = start;
+			match = window;
+		}
+	}
+
+	if (offset == -1) {
+		/*
+		 * Not even found the matched type. This may happen,
+		 * for example, if try to translate IO address in a HB
+		 * without IO window. Just return the original address,
+		 * it will fail later anyway.
+		 */
+		if (match == NULL)
+			return addr;
+
+		return (bound ? max : min) + match->offset;
+	}
+
+	return addr + offset;
+}
+
+/**
  * pci_bus_alloc_resource - allocate a resource from a parent bus
  * @bus: PCI bus
  * @res: resource to allocate
@@ -129,9 +187,12 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
 
 	type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
 
-	/* don't allocate too high if the pref mem doesn't support 64bit*/
+	/* don't allocate too high if the pref mem doesn't support 64bit */
 	if (!(res->flags & IORESOURCE_MEM_64))
-		max = PCIBIOS_MAX_MEM_32;
+		max = pci_bus_to_resource(bus, res->flags, type_mask,
+							PCIBIOS_MAX_MEM_32, 1);
+
+	min = pci_bus_to_resource(bus, res->flags, type_mask, min, 0);
 
 	pci_bus_for_each_resource(bus, r, i) {
 		if (!r)
-- 
1.8.3.2


  reply	other threads:[~2013-11-19  6:37 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-19  6:36 [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work Guo Chao
2013-11-19  6:36 ` Guo Chao [this message]
2013-11-19 19:31   ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Yinghai Lu
2013-11-19 19:35     ` Yinghai Lu
2013-11-19 23:48     ` Bjorn Helgaas
2013-11-19  6:36 ` [RFC PATCH 2/3] PCI: set proper default value of PCIBIOS_MAX_MEM_32 Guo Chao
2013-11-19  6:36 ` [RFC PATCH 3/3] PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR Guo Chao

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1384843018-9479-2-git-send-email-yan@linux.vnet.ibm.com \
    --to=yan@linux.vnet.ibm.com \
    --cc=bhelgaas@google.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).