diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-02-02 17:41:02 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-02-02 17:41:02 +0100 |
commit | 178cf7de6f1d3b95407f5a76af249fc924d42576 (patch) | |
tree | 4b3e5f3ef6dfa7866fb30811acdc60832a055269 /drivers/pci/bus.c | |
parent | Merge tag 'iio-for-3.20b' of git://git.kernel.org/pub/scm/linux/kernel/git/ji... (diff) | |
parent | Linux 3.19-rc7 (diff) | |
download | linux-178cf7de6f1d3b95407f5a76af249fc924d42576.tar.xz linux-178cf7de6f1d3b95407f5a76af249fc924d42576.zip |
Merge 3.19-rc7 into staging-next
We want those fixes in here for testing.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pci/bus.c')
-rw-r--r-- | drivers/pci/bus.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 73aef51a28f0..8fb16188cd82 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -228,6 +228,49 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, } EXPORT_SYMBOL(pci_bus_alloc_resource); +/* + * The @idx resource of @dev should be a PCI-PCI bridge window. If this + * resource fits inside a window of an upstream bridge, do nothing. If it + * overlaps an upstream window but extends outside it, clip the resource so + * it fits completely inside. + */ +bool pci_bus_clip_resource(struct pci_dev *dev, int idx) +{ + struct pci_bus *bus = dev->bus; + struct resource *res = &dev->resource[idx]; + struct resource orig_res = *res; + struct resource *r; + int i; + + pci_bus_for_each_resource(bus, r, i) { + resource_size_t start, end; + + if (!r) + continue; + + if (resource_type(res) != resource_type(r)) + continue; + + start = max(r->start, res->start); + end = min(r->end, res->end); + + if (start > end) + continue; /* no overlap */ + + if (res->start == start && res->end == end) + return false; /* no change */ + + res->start = start; + res->end = end; + dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", + &orig_res, res); + + return true; + } + + return false; +} + void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { } /** |