From: Kumar Gala <galak@kernel.crashing.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 2/2] pci: give preference to non-PCI_REGION_SYS_MEMORY regions when matching
Date: Fri, 6 Feb 2009 09:49:32 -0600 [thread overview]
Message-ID: <1233935372-28001-2-git-send-email-galak@kernel.crashing.org> (raw)
In-Reply-To: <1233935372-28001-1-git-send-email-galak@kernel.crashing.org>
When we search for an address match in pci_hose_{phys_to_bus,bus_to_phys}
we should give preference to memory regions that aren't system memory.
Its possible that we have over mapped system memory in the regions and
we want to avoid depending on the order of the regions.
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
drivers/pci/pci.c | 102 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 78 insertions(+), 24 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e2b05d8..06b56b0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -218,67 +218,121 @@ pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
*
*/
-pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
- phys_addr_t phys_addr,
- unsigned long flags)
+int __pci_hose_phys_to_bus (struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ pci_addr_t *ba)
{
struct pci_region *res;
pci_addr_t bus_addr;
int i;
- if (!hose) {
- printf ("pci_hose_phys_to_bus: %s\n", "invalid hose");
- goto Done;
- }
-
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
+ if (res->flags & skip_mask)
+ continue;
+
bus_addr = phys_addr - res->phys_start + res->bus_start;
if (bus_addr >= res->bus_start &&
bus_addr < res->bus_start + res->size) {
- return bus_addr;
+ *ba = bus_addr;
+ return 0;
}
}
- printf ("pci_hose_phys_to_bus: %s\n", "invalid physical address");
-
-Done:
- return 0;
+ return 1;
}
-phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
- pci_addr_t bus_addr,
- unsigned long flags)
+pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
+ phys_addr_t phys_addr,
+ unsigned long flags)
{
- struct pci_region *res;
- int i;
+ pci_addr_t bus_addr = 0;
+ int ret;
if (!hose) {
- printf ("pci_hose_bus_to_phys: %s\n", "invalid hose");
- goto Done;
+ puts ("pci_hose_phys_to_bus: invalid hose\n");
+ return bus_addr;
+ }
+
+ /* if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_phys_to_bus(hose, phys_addr,
+ flags, PCI_REGION_SYS_MEMORY, &bus_addr);
+ if (!ret)
+ return bus_addr;
}
+ ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);
+
+ if (ret)
+ puts ("pci_hose_phys_to_bus: invalid physical address\n");
+
+ return bus_addr;
+}
+
+int __pci_hose_bus_to_phys (struct pci_controller *hose,
+ pci_addr_t bus_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ phys_addr_t *pa)
+{
+ struct pci_region *res;
+ int i;
+
for (i = 0; i < hose->region_count; i++) {
res = &hose->regions[i];
if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
continue;
+ if (res->flags & skip_mask)
+ continue;
+
if (bus_addr >= res->bus_start &&
bus_addr < res->bus_start + res->size) {
- return bus_addr - res->bus_start + res->phys_start;
+ *pa = (bus_addr - res->bus_start + res->phys_start);
+ return 0;
}
}
- printf ("pci_hose_bus_to_phys: %s\n", "invalid physical address");
+ return 1;
+}
-Done:
- return 0;
+phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
+ pci_addr_t bus_addr,
+ unsigned long flags)
+{
+ phys_addr_t phys_addr = 0;
+ int ret;
+
+ if (!hose) {
+ puts ("pci_hose_bus_to_phys: invalid hose\n");
+ return phys_addr;
+ }
+
+ /* if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_bus_to_phys(hose, bus_addr,
+ flags, PCI_REGION_SYS_MEMORY, &phys_addr);
+ if (!ret)
+ return phys_addr;
+ }
+
+ ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
+
+ if (ret)
+ puts ("pci_hose_bus_to_phys: invalid physical address\n");
+
+ return phys_addr;
}
/*
--
1.5.6.6
next prev parent reply other threads:[~2009-02-06 15:49 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-06 15:49 [U-Boot] [PATCH 1/2] pci: Rename PCI_REGION_MEMORY to PCI_REGION_SYS_MEMORY for clarity Kumar Gala
2009-02-06 15:49 ` Kumar Gala [this message]
2009-02-07 22:50 ` [U-Boot] [PATCH 2/2] pci: give preference to non-PCI_REGION_SYS_MEMORY regions when matching Wolfgang Denk
2009-02-07 22:50 ` [U-Boot] [PATCH 1/2] pci: Rename PCI_REGION_MEMORY to PCI_REGION_SYS_MEMORY for clarity Wolfgang Denk
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=1233935372-28001-2-git-send-email-galak@kernel.crashing.org \
--to=galak@kernel.crashing.org \
--cc=u-boot@lists.denx.de \
/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