From: David Daney <ddaney.cavm@gmail.com>
To: linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Rafał Miłecki" <zajec5@gmail.com>,
linux-api@vger.kernel.org,
"Sean O. Stalley" <sean.stalley@intel.com>,
yinghai@kernel.org, rajatxjain@gmail.com,
gong.chen@linux.intel.com
Cc: David Daney <david.daney@cavium.com>
Subject: [PATCH v4 5/5] PCI: Handle Enhanced Allocation (EA) capability for bridges
Date: Fri, 2 Oct 2015 15:37:56 -0700 [thread overview]
Message-ID: <1443825476-26880-6-git-send-email-ddaney.cavm@gmail.com> (raw)
In-Reply-To: <1443825476-26880-1-git-send-email-ddaney.cavm@gmail.com>
From: David Daney <david.daney@cavium.com>
PCI bridges may have their properties be specified via EA entries.
Extend the EA parser to extract the bridge resources, and modify
pci_read_bridge_{io,mmio,mmio_pref}() to use resources previously
obtained via EA.
Save the offset to the EA capability in struct pci_dev, and use it to
easily find the EA bridge subordinate and secondary bus numbers.
When assigning the bridge resources a couple of changes are required
so that the EA obtained IORESOURCE_PCI_FIXED are not resized, and
correctly linked into the resource tree.
1) In pbus_size_mem() do not attempt to resize the bridge resources if
they are marked as IORESOURCE_PCI_FIXED.
2) In pci_bus_alloc_from_region()for IORESOURCE_PCI_FIXED resources, just
try to request the resource as is, without attempting to resize it.
Signed-off-by: David Daney <david.daney@cavium.com>
---
drivers/pci/bus.c | 7 +++++++
drivers/pci/pci.c | 13 +++++++++++++
drivers/pci/probe.c | 31 +++++++++++++++++++++++++++++--
drivers/pci/setup-bus.c | 3 +++
include/linux/pci.h | 1 +
5 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6fbd3f2..0556b33 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -153,6 +153,13 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
!(res->flags & IORESOURCE_PREFETCH))
continue;
+ if (res->flags & IORESOURCE_PCI_FIXED) {
+ /* Cannot change it, just try to claim it. */
+ if (request_resource(r, res))
+ continue;
+ return 0;
+ }
+
avail = *r;
pci_clip_resource_to_region(bus, &avail, region);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6750edf..c857632 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2183,6 +2183,17 @@ static struct resource *pci_ea_get_resource(struct pci_dev *dev, u8 bei, u8 prop
(prop == PCI_EA_P_VIRT_MEM || prop == PCI_EA_P_VIRT_MEM_PREFETCH))
return &dev->resource[PCI_IOV_RESOURCES + bei - PCI_EA_BEI_VF_BAR0];
#endif
+ else if (bei == PCI_EA_BEI_BRIDGE)
+ switch (prop) {
+ case PCI_EA_P_BRIDGE_IO:
+ return &dev->resource[PCI_BRIDGE_RESOURCES + 0];
+ case PCI_EA_P_BRIDGE_MEM:
+ return &dev->resource[PCI_BRIDGE_RESOURCES + 1];
+ case PCI_EA_P_BRIDGE_MEM_PREFETCH:
+ return &dev->resource[PCI_BRIDGE_RESOURCES + 2];
+ default:
+ return NULL;
+ }
else if (bei == PCI_EA_BEI_ROM)
return &dev->resource[PCI_ROM_RESOURCE];
else
@@ -2321,6 +2332,8 @@ void pci_ea_init(struct pci_dev *dev)
if (!ea)
return;
+ dev->ea_cap = ea;
+
/* determine the number of entries */
pci_bus_read_config_byte(dev->bus, dev->devfn, ea + PCI_EA_NUM_ENT,
&num_ent);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4293eec..e4bcb0b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -348,6 +348,10 @@ static void pci_read_bridge_io(struct pci_bus *child)
}
res = child->resource[0];
+ if (res->flags & IORESOURCE_PCI_FIXED) {
+ dev_dbg(&dev->dev, " bridge window %pR (fixed)\n", res);
+ return;
+ }
pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo);
pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo);
base = (io_base_lo & io_mask) << 8;
@@ -380,6 +384,10 @@ static void pci_read_bridge_mmio(struct pci_bus *child)
struct resource *res;
res = child->resource[1];
+ if (res->flags & IORESOURCE_PCI_FIXED) {
+ dev_dbg(&dev->dev, " bridge window %pR (fixed)\n", res);
+ return;
+ }
pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
@@ -403,6 +411,10 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
struct resource *res;
res = child->resource[2];
+ if (res->flags & IORESOURCE_PCI_FIXED) {
+ dev_dbg(&dev->dev, " bridge window %pR (fixed)\n", res);
+ return;
+ }
pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
base64 = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
@@ -801,8 +813,23 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses);
primary = buses & 0xFF;
- secondary = (buses >> 8) & 0xFF;
- subordinate = (buses >> 16) & 0xFF;
+ if (dev->ea_cap) {
+ u32 dw1;
+
+ pci_read_config_dword(dev, dev->ea_cap + 4, &dw1);
+ if (dw1 & 0xFF)
+ secondary = dw1 & 0xFF;
+ else
+ secondary = (buses >> 8) & 0xFF;
+
+ if ((dw1 >> 8) & 0xFF)
+ subordinate = (dw1 >> 8) & 0xFF;
+ else
+ subordinate = (buses >> 16) & 0xFF;
+ } else {
+ secondary = (buses >> 8) & 0xFF;
+ subordinate = (buses >> 16) & 0xFF;
+ }
dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
secondary, subordinate, pass);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 8f9ed9b..8b8cc32 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1086,6 +1086,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
}
}
+ if (b_res->flags & IORESOURCE_PCI_FIXED)
+ return 0;
+
min_align = calculate_mem_align(aligns, max_order);
min_align = max(min_align, window_alignment(bus, b_res->flags));
size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b505b50..a8a177c 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -384,6 +384,7 @@ struct pci_dev {
phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
size_t romlen; /* Length of ROM if it's not from the BAR */
char *driver_override; /* Driver name to force a match */
+ u8 ea_cap; /* Enhanced Allocation capability offset */
};
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
--
1.9.1
next prev parent reply other threads:[~2015-10-02 22:37 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-02 22:37 [PATCH v4 0/5] PCI: Add support for PCI Enhanced Allocation "BARs" David Daney
2015-10-02 22:37 ` [PATCH v4 1/5] PCI: Add Enhanced Allocation register entries David Daney
2015-10-02 22:37 ` [PATCH v4 2/5] PCI: Add support for Enhanced Allocation devices David Daney
[not found] ` <1443825476-26880-1-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-10-02 22:37 ` [PATCH v4 3/5] PCI: Handle IORESOURCE_PCI_FIXED when sizing and assigning resources David Daney
2015-10-02 23:14 ` Yinghai Lu
2015-10-02 23:38 ` David Daney
2015-10-03 3:00 ` Yinghai Lu
2015-10-05 22:44 ` Sean O. Stalley
[not found] ` <1443825476-26880-4-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-10-05 22:23 ` Sean O. Stalley
[not found] ` <20151005222351.GA4821-KQ5zpJUXklQTH34CoL1+91DQ4js95KgL@public.gmane.org>
2015-10-06 20:58 ` David Daney
2015-10-02 23:47 ` [PATCH v4 0/5] PCI: Add support for PCI Enhanced Allocation "BARs" Sean O. Stalley
2015-10-03 3:16 ` Yinghai Lu
[not found] ` <CAE9FiQXT0ux42gQ+DhpVv2K=BR4jC++LmNdCSLiK4Wy0BhL=HQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-10-05 16:49 ` David Daney
2015-10-05 23:05 ` Sean O. Stalley
2015-10-06 1:17 ` David Daney
2015-10-06 15:47 ` Sean O. Stalley
2015-10-02 22:37 ` [PATCH v4 4/5] PCI: Handle Enhanced Allocation (EA) capability for SRIOV devices David Daney
2015-10-02 22:37 ` David Daney [this message]
[not found] ` <1443825476-26880-6-git-send-email-ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-10-05 22:54 ` [PATCH v4 5/5] PCI: Handle Enhanced Allocation (EA) capability for bridges Sean O. Stalley
2015-10-05 23:01 ` David Daney
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=1443825476-26880-6-git-send-email-ddaney.cavm@gmail.com \
--to=ddaney.cavm@gmail.com \
--cc=bhelgaas@google.com \
--cc=david.daney@cavium.com \
--cc=gong.chen@linux.intel.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mst@redhat.com \
--cc=rajatxjain@gmail.com \
--cc=sean.stalley@intel.com \
--cc=yinghai@kernel.org \
--cc=zajec5@gmail.com \
/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).