aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2014-03-19 17:11:19 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-03-19 17:11:19 -0400
commit30723cbf6f7aec2ab4810bdc4bf12c5749a09e33 (patch)
tree840833435357419595fee44b2a06f9864f1458c9
parent91b4adc983d8e9975bc677c2b8395631edf7b92d (diff)
parentf2e6027b816df3326d3f40d6ce55539a2f381529 (diff)
Merge branch 'pci/resource' into next
* pci/resource: (26 commits) Revert "[PATCH] Insert GART region into resource map" PCI: Log IDE resource quirk in dmesg PCI: Change pci_bus_alloc_resource() type_mask to unsigned long PCI: Check all IORESOURCE_TYPE_BITS in pci_bus_alloc_from_region() resources: Set type in __request_region() PCI: Don't check resource_size() in pci_bus_alloc_resource() s390/PCI: Use generic pci_enable_resources() tile PCI RC: Use default pcibios_enable_device() sparc/PCI: Use default pcibios_enable_device() (Leon only) sh/PCI: Use default pcibios_enable_device() microblaze/PCI: Use default pcibios_enable_device() alpha/PCI: Use default pcibios_enable_device() PCI: Add "weak" generic pcibios_enable_device() implementation PCI: Don't enable decoding if BAR hasn't been assigned an address PCI: Mark 64-bit resource as IORESOURCE_UNSET if we only support 32-bit PCI: Don't try to claim IORESOURCE_UNSET resources PCI: Check IORESOURCE_UNSET before updating BAR PCI: Don't clear IORESOURCE_UNSET when updating BAR PCI: Mark resources as IORESOURCE_UNSET if we can't assign them PCI: Remove pci_find_parent_resource() use for allocation ...
-rw-r--r--arch/alpha/kernel/pci.c6
-rw-r--r--arch/microblaze/pci/pci-common.c5
-rw-r--r--arch/s390/pci/pci.c16
-rw-r--r--arch/sh/drivers/pci/pci.c5
-rw-r--r--arch/sparc/kernel/leon_pci.c5
-rw-r--r--arch/tile/kernel/pci_gx.c12
-rw-r--r--arch/x86/kernel/aperture_64.c20
-rw-r--r--drivers/message/i2o/iop.c85
-rw-r--r--drivers/pci/bus.c8
-rw-r--r--drivers/pci/host-bridge.c8
-rw-r--r--drivers/pci/pci.c46
-rw-r--r--drivers/pci/probe.c17
-rw-r--r--drivers/pci/quirks.c5
-rw-r--r--drivers/pci/rom.c2
-rw-r--r--drivers/pci/setup-res.c37
-rw-r--r--include/linux/ioport.h12
-rw-r--r--include/linux/pci.h2
-rw-r--r--kernel/resource.c12
-rw-r--r--lib/vsprintf.c13
19 files changed, 147 insertions, 169 deletions
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index edb4e0097b75..076c35cd6cde 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -254,12 +254,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
254 } 254 }
255} 255}
256 256
257int
258pcibios_enable_device(struct pci_dev *dev, int mask)
259{
260 return pci_enable_resources(dev, mask);
261}
262
263/* 257/*
264 * If we set up a device for bus mastering, we need to check the latency 258 * If we set up a device for bus mastering, we need to check the latency
265 * timer as certain firmware forgets to set it properly, as seen 259 * timer as certain firmware forgets to set it properly, as seen
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 66804adcacf0..70996cc66aa2 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -1294,11 +1294,6 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus)
1294} 1294}
1295EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); 1295EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus);
1296 1296
1297int pcibios_enable_device(struct pci_dev *dev, int mask)
1298{
1299 return pci_enable_resources(dev, mask);
1300}
1301
1302static void pcibios_setup_phb_resources(struct pci_controller *hose, 1297static void pcibios_setup_phb_resources(struct pci_controller *hose,
1303 struct list_head *resources) 1298 struct list_head *resources)
1304{ 1299{
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 66670ff262a0..1df1d29ac81d 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -686,27 +686,13 @@ int pcibios_add_device(struct pci_dev *pdev)
686int pcibios_enable_device(struct pci_dev *pdev, int mask) 686int pcibios_enable_device(struct pci_dev *pdev, int mask)
687{ 687{
688 struct zpci_dev *zdev = get_zdev(pdev); 688 struct zpci_dev *zdev = get_zdev(pdev);
689 struct resource *res;
690 u16 cmd;
691 int i;
692 689
693 zdev->pdev = pdev; 690 zdev->pdev = pdev;
694 zpci_debug_init_device(zdev); 691 zpci_debug_init_device(zdev);
695 zpci_fmb_enable_device(zdev); 692 zpci_fmb_enable_device(zdev);
696 zpci_map_resources(zdev); 693 zpci_map_resources(zdev);
697 694
698 pci_read_config_word(pdev, PCI_COMMAND, &cmd); 695 return pci_enable_resources(pdev, mask);
699 for (i = 0; i < PCI_BAR_COUNT; i++) {
700 res = &pdev->resource[i];
701
702 if (res->flags & IORESOURCE_IO)
703 return -EINVAL;
704
705 if (res->flags & IORESOURCE_MEM)
706 cmd |= PCI_COMMAND_MEMORY;
707 }
708 pci_write_config_word(pdev, PCI_COMMAND, cmd);
709 return 0;
710} 696}
711 697
712void pcibios_disable_device(struct pci_dev *pdev) 698void pcibios_disable_device(struct pci_dev *pdev)
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 60ed3e1c4b75..1bc09ee7948f 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -186,11 +186,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
186 return start; 186 return start;
187} 187}
188 188
189int pcibios_enable_device(struct pci_dev *dev, int mask)
190{
191 return pci_enable_resources(dev, mask);
192}
193
194static void __init 189static void __init
195pcibios_bus_report_status_early(struct pci_channel *hose, 190pcibios_bus_report_status_early(struct pci_channel *hose,
196 int top_bus, int current_bus, 191 int top_bus, int current_bus,
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c
index 88aaaa57bb64..e16c4157e1ae 100644
--- a/arch/sparc/kernel/leon_pci.c
+++ b/arch/sparc/kernel/leon_pci.c
@@ -99,11 +99,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
99 return res->start; 99 return res->start;
100} 100}
101 101
102int pcibios_enable_device(struct pci_dev *dev, int mask)
103{
104 return pci_enable_resources(dev, mask);
105}
106
107/* in/out routines taken from pcic.c 102/* in/out routines taken from pcic.c
108 * 103 *
109 * This probably belongs here rather than ioport.c because 104 * This probably belongs here rather than ioport.c because
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index a97a6452b812..077b7bc437e5 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1065,18 +1065,6 @@ char *__init pcibios_setup(char *str)
1065} 1065}
1066 1066
1067/* 1067/*
1068 * Enable memory address decoding, as appropriate, for the
1069 * device described by the 'dev' struct.
1070 *
1071 * This is called from the generic PCI layer, and can be called
1072 * for bridges or endpoints.
1073 */
1074int pcibios_enable_device(struct pci_dev *dev, int mask)
1075{
1076 return pci_enable_resources(dev, mask);
1077}
1078
1079/*
1080 * Called for each device after PCI setup is done. 1068 * Called for each device after PCI setup is done.
1081 * We initialize the PCI device capabilities conservatively, assuming that 1069 * We initialize the PCI device capabilities conservatively, assuming that
1082 * all devices can only address the 32-bit DMA space. The exception here is 1070 * all devices can only address the 32-bit DMA space. The exception here is
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index fd972a3e4cbb..9fa8aa051f54 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -18,7 +18,6 @@
18#include <linux/pci_ids.h> 18#include <linux/pci_ids.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <linux/ioport.h>
22#include <linux/suspend.h> 21#include <linux/suspend.h>
23#include <asm/e820.h> 22#include <asm/e820.h>
24#include <asm/io.h> 23#include <asm/io.h>
@@ -54,18 +53,6 @@ int fallback_aper_force __initdata;
54 53
55int fix_aperture __initdata = 1; 54int fix_aperture __initdata = 1;
56 55
57static struct resource gart_resource = {
58 .name = "GART",
59 .flags = IORESOURCE_MEM,
60};
61
62static void __init insert_aperture_resource(u32 aper_base, u32 aper_size)
63{
64 gart_resource.start = aper_base;
65 gart_resource.end = aper_base + aper_size - 1;
66 insert_resource(&iomem_resource, &gart_resource);
67}
68
69/* This code runs before the PCI subsystem is initialized, so just 56/* This code runs before the PCI subsystem is initialized, so just
70 access the northbridge directly. */ 57 access the northbridge directly. */
71 58
@@ -96,7 +83,6 @@ static u32 __init allocate_aperture(void)
96 memblock_reserve(addr, aper_size); 83 memblock_reserve(addr, aper_size);
97 printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n", 84 printk(KERN_INFO "Mapping aperture over %d KB of RAM @ %lx\n",
98 aper_size >> 10, addr); 85 aper_size >> 10, addr);
99 insert_aperture_resource((u32)addr, aper_size);
100 register_nosave_region(addr >> PAGE_SHIFT, 86 register_nosave_region(addr >> PAGE_SHIFT,
101 (addr+aper_size) >> PAGE_SHIFT); 87 (addr+aper_size) >> PAGE_SHIFT);
102 88
@@ -444,12 +430,8 @@ int __init gart_iommu_hole_init(void)
444 430
445out: 431out:
446 if (!fix && !fallback_aper_force) { 432 if (!fix && !fallback_aper_force) {
447 if (last_aper_base) { 433 if (last_aper_base)
448 unsigned long n = (32 * 1024 * 1024) << last_aper_order;
449
450 insert_aperture_resource((u32)last_aper_base, n);
451 return 1; 434 return 1;
452 }
453 return 0; 435 return 0;
454 } 436 }
455 437
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index a8c08f332da0..92752fb5b2d3 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -652,6 +652,44 @@ static int i2o_iop_activate(struct i2o_controller *c)
652 return i2o_hrt_get(c); 652 return i2o_hrt_get(c);
653}; 653};
654 654
655static void i2o_res_alloc(struct i2o_controller *c, unsigned long flags)
656{
657 i2o_status_block *sb = c->status_block.virt;
658 struct resource *res = &c->mem_resource;
659 resource_size_t size, align;
660 int err;
661
662 res->name = c->pdev->bus->name;
663 res->flags = flags;
664 res->start = 0;
665 res->end = 0;
666 osm_info("%s: requires private memory resources.\n", c->name);
667
668 if (flags & IORESOURCE_MEM) {
669 size = sb->desired_mem_size;
670 align = 1 << 20; /* unspecified, use 1Mb and play safe */
671 } else {
672 size = sb->desired_io_size;
673 align = 1 << 12; /* unspecified, use 4Kb and play safe */
674 }
675
676 err = pci_bus_alloc_resource(c->pdev->bus, res, size, align, 0, 0,
677 NULL, NULL);
678 if (err < 0)
679 return;
680
681 if (flags & IORESOURCE_MEM) {
682 c->mem_alloc = 1;
683 sb->current_mem_size = resource_size(res);
684 sb->current_mem_base = res->start;
685 } else if (flags & IORESOURCE_IO) {
686 c->io_alloc = 1;
687 sb->current_io_size = resource_size(res);
688 sb->current_io_base = res->start;
689 }
690 osm_info("%s: allocated PCI space %pR\n", c->name, res);
691}
692
655/** 693/**
656 * i2o_iop_systab_set - Set the I2O System Table of the specified IOP 694 * i2o_iop_systab_set - Set the I2O System Table of the specified IOP
657 * @c: I2O controller to which the system table should be send 695 * @c: I2O controller to which the system table should be send
@@ -665,52 +703,13 @@ static int i2o_iop_systab_set(struct i2o_controller *c)
665 struct i2o_message *msg; 703 struct i2o_message *msg;
666 i2o_status_block *sb = c->status_block.virt; 704 i2o_status_block *sb = c->status_block.virt;
667 struct device *dev = &c->pdev->dev; 705 struct device *dev = &c->pdev->dev;
668 struct resource *root;
669 int rc; 706 int rc;
670 707
671 if (sb->current_mem_size < sb->desired_mem_size) { 708 if (sb->current_mem_size < sb->desired_mem_size)
672 struct resource *res = &c->mem_resource; 709 i2o_res_alloc(c, IORESOURCE_MEM);
673 res->name = c->pdev->bus->name;
674 res->flags = IORESOURCE_MEM;
675 res->start = 0;
676 res->end = 0;
677 osm_info("%s: requires private memory resources.\n", c->name);
678 root = pci_find_parent_resource(c->pdev, res);
679 if (root == NULL)
680 osm_warn("%s: Can't find parent resource!\n", c->name);
681 if (root && allocate_resource(root, res, sb->desired_mem_size, sb->desired_mem_size, sb->desired_mem_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
682 NULL, NULL) >= 0) {
683 c->mem_alloc = 1;
684 sb->current_mem_size = resource_size(res);
685 sb->current_mem_base = res->start;
686 osm_info("%s: allocated %llu bytes of PCI memory at "
687 "0x%016llX.\n", c->name,
688 (unsigned long long)resource_size(res),
689 (unsigned long long)res->start);
690 }
691 }
692 710
693 if (sb->current_io_size < sb->desired_io_size) { 711 if (sb->current_io_size < sb->desired_io_size)
694 struct resource *res = &c->io_resource; 712 i2o_res_alloc(c, IORESOURCE_IO);
695 res->name = c->pdev->bus->name;
696 res->flags = IORESOURCE_IO;
697 res->start = 0;
698 res->end = 0;
699 osm_info("%s: requires private memory resources.\n", c->name);
700 root = pci_find_parent_resource(c->pdev, res);
701 if (root == NULL)
702 osm_warn("%s: Can't find parent resource!\n", c->name);
703 if (root && allocate_resource(root, res, sb->desired_io_size, sb->desired_io_size, sb->desired_io_size, 1 << 20, /* Unspecified, so use 1Mb and play safe */
704 NULL, NULL) >= 0) {
705 c->io_alloc = 1;
706 sb->current_io_size = resource_size(res);
707 sb->current_mem_base = res->start;
708 osm_info("%s: allocated %llu bytes of PCI I/O at "
709 "0x%016llX.\n", c->name,
710 (unsigned long long)resource_size(res),
711 (unsigned long long)res->start);
712 }
713 }
714 713
715 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET); 714 msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
716 if (IS_ERR(msg)) 715 if (IS_ERR(msg))
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 00660cc502c5..fb8aed307c28 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -132,7 +132,7 @@ static void pci_clip_resource_to_region(struct pci_bus *bus,
132 132
133static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, 133static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
134 resource_size_t size, resource_size_t align, 134 resource_size_t size, resource_size_t align,
135 resource_size_t min, unsigned int type_mask, 135 resource_size_t min, unsigned long type_mask,
136 resource_size_t (*alignf)(void *, 136 resource_size_t (*alignf)(void *,
137 const struct resource *, 137 const struct resource *,
138 resource_size_t, 138 resource_size_t,
@@ -144,7 +144,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
144 struct resource *r, avail; 144 struct resource *r, avail;
145 resource_size_t max; 145 resource_size_t max;
146 146
147 type_mask |= IORESOURCE_IO | IORESOURCE_MEM; 147 type_mask |= IORESOURCE_TYPE_BITS;
148 148
149 pci_bus_for_each_resource(bus, r, i) { 149 pci_bus_for_each_resource(bus, r, i) {
150 if (!r) 150 if (!r)
@@ -162,8 +162,6 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
162 162
163 avail = *r; 163 avail = *r;
164 pci_clip_resource_to_region(bus, &avail, region); 164 pci_clip_resource_to_region(bus, &avail, region);
165 if (!resource_size(&avail))
166 continue;
167 165
168 /* 166 /*
169 * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to 167 * "min" is typically PCIBIOS_MIN_IO or PCIBIOS_MIN_MEM to
@@ -202,7 +200,7 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
202 */ 200 */
203int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, 201int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
204 resource_size_t size, resource_size_t align, 202 resource_size_t size, resource_size_t align,
205 resource_size_t min, unsigned int type_mask, 203 resource_size_t min, unsigned long type_mask,
206 resource_size_t (*alignf)(void *, 204 resource_size_t (*alignf)(void *,
207 const struct resource *, 205 const struct resource *,
208 resource_size_t, 206 resource_size_t,
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index 06ace6248c61..47aaf22d814e 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -32,11 +32,6 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
32 bridge->release_data = release_data; 32 bridge->release_data = release_data;
33} 33}
34 34
35static bool resource_contains(struct resource *res1, struct resource *res2)
36{
37 return res1->start <= res2->start && res1->end >= res2->end;
38}
39
40void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, 35void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
41 struct resource *res) 36 struct resource *res)
42{ 37{
@@ -45,9 +40,6 @@ void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region,
45 resource_size_t offset = 0; 40 resource_size_t offset = 0;
46 41
47 list_for_each_entry(window, &bridge->windows, list) { 42 list_for_each_entry(window, &bridge->windows, list) {
48 if (resource_type(res) != resource_type(window->res))
49 continue;
50
51 if (resource_contains(window->res, res)) { 43 if (resource_contains(window->res, res)) {
52 offset = window->offset; 44 offset = window->offset;
53 break; 45 break;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 505fbb670d6a..7325d43bf030 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -401,33 +401,40 @@ EXPORT_SYMBOL_GPL(pci_find_ht_capability);
401 * @res: child resource record for which parent is sought 401 * @res: child resource record for which parent is sought
402 * 402 *
403 * For given resource region of given device, return the resource 403 * For given resource region of given device, return the resource
404 * region of parent bus the given region is contained in or where 404 * region of parent bus the given region is contained in.
405 * it should be allocated from.
406 */ 405 */
407struct resource * 406struct resource *
408pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) 407pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
409{ 408{
410 const struct pci_bus *bus = dev->bus; 409 const struct pci_bus *bus = dev->bus;
410 struct resource *r;
411 int i; 411 int i;
412 struct resource *best = NULL, *r;
413 412
414 pci_bus_for_each_resource(bus, r, i) { 413 pci_bus_for_each_resource(bus, r, i) {
415 if (!r) 414 if (!r)
416 continue; 415 continue;
417 if (res->start && !(res->start >= r->start && res->end <= r->end)) 416 if (res->start && resource_contains(r, res)) {
418 continue; /* Not contained */ 417
419 if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) 418 /*
420 continue; /* Wrong type */ 419 * If the window is prefetchable but the BAR is
421 if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) 420 * not, the allocator made a mistake.
422 return r; /* Exact match */ 421 */
423 /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ 422 if (r->flags & IORESOURCE_PREFETCH &&
424 if (r->flags & IORESOURCE_PREFETCH) 423 !(res->flags & IORESOURCE_PREFETCH))
425 continue; 424 return NULL;
426 /* .. but we can put a prefetchable resource inside a non-prefetchable one */ 425
427 if (!best) 426 /*
428 best = r; 427 * If we're below a transparent bridge, there may
428 * be both a positively-decoded aperture and a
429 * subtractively-decoded region that contain the BAR.
430 * We want the positively-decoded one, so this depends
431 * on pci_bus_for_each_resource() giving us those
432 * first.
433 */
434 return r;
435 }
429 } 436 }
430 return best; 437 return NULL;
431} 438}
432 439
433/** 440/**
@@ -1178,6 +1185,11 @@ int pci_load_and_free_saved_state(struct pci_dev *dev,
1178} 1185}
1179EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); 1186EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
1180 1187
1188int __weak pcibios_enable_device(struct pci_dev *dev, int bars)
1189{
1190 return pci_enable_resources(dev, bars);
1191}
1192
1181static int do_pci_enable_device(struct pci_dev *dev, int bars) 1193static int do_pci_enable_device(struct pci_dev *dev, int bars)
1182{ 1194{
1183 int err; 1195 int err;
@@ -4262,6 +4274,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
4262 "Rounding up size of resource #%d to %#llx.\n", 4274 "Rounding up size of resource #%d to %#llx.\n",
4263 i, (unsigned long long)size); 4275 i, (unsigned long long)size);
4264 } 4276 }
4277 r->flags |= IORESOURCE_UNSET;
4265 r->end = size - 1; 4278 r->end = size - 1;
4266 r->start = 0; 4279 r->start = 0;
4267 } 4280 }
@@ -4275,6 +4288,7 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
4275 r = &dev->resource[i]; 4288 r = &dev->resource[i];
4276 if (!(r->flags & IORESOURCE_MEM)) 4289 if (!(r->flags & IORESOURCE_MEM))
4277 continue; 4290 continue;
4291 r->flags |= IORESOURCE_UNSET;
4278 r->end = resource_size(r) - 1; 4292 r->end = resource_size(r) - 1;
4279 r->start = 0; 4293 r->start = 0;
4280 } 4294 }
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 509494381a7a..ef09f5f2fe6c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -252,6 +252,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
252 /* Address above 32-bit boundary; disable the BAR */ 252 /* Address above 32-bit boundary; disable the BAR */
253 pci_write_config_dword(dev, pos, 0); 253 pci_write_config_dword(dev, pos, 0);
254 pci_write_config_dword(dev, pos + 4, 0); 254 pci_write_config_dword(dev, pos + 4, 0);
255 res->flags |= IORESOURCE_UNSET;
255 region.start = 0; 256 region.start = 0;
256 region.end = sz64; 257 region.end = sz64;
257 bar_disabled = true; 258 bar_disabled = true;
@@ -1107,10 +1108,10 @@ int pci_setup_device(struct pci_dev *dev)
1107 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device); 1108 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &dev->subsystem_device);
1108 1109
1109 /* 1110 /*
1110 * Do the ugly legacy mode stuff here rather than broken chip 1111 * Do the ugly legacy mode stuff here rather than broken chip
1111 * quirk code. Legacy mode ATA controllers have fixed 1112 * quirk code. Legacy mode ATA controllers have fixed
1112 * addresses. These are not always echoed in BAR0-3, and 1113 * addresses. These are not always echoed in BAR0-3, and
1113 * BAR0-3 in a few cases contain junk! 1114 * BAR0-3 in a few cases contain junk!
1114 */ 1115 */
1115 if (class == PCI_CLASS_STORAGE_IDE) { 1116 if (class == PCI_CLASS_STORAGE_IDE) {
1116 u8 progif; 1117 u8 progif;
@@ -1121,11 +1122,15 @@ int pci_setup_device(struct pci_dev *dev)
1121 res = &dev->resource[0]; 1122 res = &dev->resource[0];
1122 res->flags = LEGACY_IO_RESOURCE; 1123 res->flags = LEGACY_IO_RESOURCE;
1123 pcibios_bus_to_resource(dev->bus, res, &region); 1124 pcibios_bus_to_resource(dev->bus, res, &region);
1125 dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n",
1126 res);
1124 region.start = 0x3F6; 1127 region.start = 0x3F6;
1125 region.end = 0x3F6; 1128 region.end = 0x3F6;
1126 res = &dev->resource[1]; 1129 res = &dev->resource[1];
1127 res->flags = LEGACY_IO_RESOURCE; 1130 res->flags = LEGACY_IO_RESOURCE;
1128 pcibios_bus_to_resource(dev->bus, res, &region); 1131 pcibios_bus_to_resource(dev->bus, res, &region);
1132 dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n",
1133 res);
1129 } 1134 }
1130 if ((progif & 4) == 0) { 1135 if ((progif & 4) == 0) {
1131 region.start = 0x170; 1136 region.start = 0x170;
@@ -1133,11 +1138,15 @@ int pci_setup_device(struct pci_dev *dev)
1133 res = &dev->resource[2]; 1138 res = &dev->resource[2];
1134 res->flags = LEGACY_IO_RESOURCE; 1139 res->flags = LEGACY_IO_RESOURCE;
1135 pcibios_bus_to_resource(dev->bus, res, &region); 1140 pcibios_bus_to_resource(dev->bus, res, &region);
1141 dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n",
1142 res);
1136 region.start = 0x376; 1143 region.start = 0x376;
1137 region.end = 0x376; 1144 region.end = 0x376;
1138 res = &dev->resource[3]; 1145 res = &dev->resource[3];
1139 res->flags = LEGACY_IO_RESOURCE; 1146 res->flags = LEGACY_IO_RESOURCE;
1140 pcibios_bus_to_resource(dev->bus, res, &region); 1147 pcibios_bus_to_resource(dev->bus, res, &region);
1148 dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n",
1149 res);
1141 } 1150 }
1142 } 1151 }
1143 break; 1152 break;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ed2ed867c34c..e7292065a1b1 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -296,6 +296,7 @@ static void quirk_s3_64M(struct pci_dev *dev)
296 struct resource *r = &dev->resource[0]; 296 struct resource *r = &dev->resource[0];
297 297
298 if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) { 298 if ((r->start & 0x3ffffff) || r->end != r->start + 0x3ffffff) {
299 r->flags |= IORESOURCE_UNSET;
299 r->start = 0; 300 r->start = 0;
300 r->end = 0x3ffffff; 301 r->end = 0x3ffffff;
301 } 302 }
@@ -937,6 +938,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C
937static void quirk_dunord(struct pci_dev *dev) 938static void quirk_dunord(struct pci_dev *dev)
938{ 939{
939 struct resource *r = &dev->resource [1]; 940 struct resource *r = &dev->resource [1];
941
942 r->flags |= IORESOURCE_UNSET;
940 r->start = 0; 943 r->start = 0;
941 r->end = 0xffffff; 944 r->end = 0xffffff;
942} 945}
@@ -1740,6 +1743,7 @@ static void quirk_tc86c001_ide(struct pci_dev *dev)
1740 struct resource *r = &dev->resource[0]; 1743 struct resource *r = &dev->resource[0];
1741 1744
1742 if (r->start & 0x8) { 1745 if (r->start & 0x8) {
1746 r->flags |= IORESOURCE_UNSET;
1743 r->start = 0; 1747 r->start = 0;
1744 r->end = 0xf; 1748 r->end = 0xf;
1745 } 1749 }
@@ -1769,6 +1773,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev)
1769 dev_info(&dev->dev, 1773 dev_info(&dev->dev,
1770 "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n", 1774 "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
1771 bar); 1775 bar);
1776 r->flags |= IORESOURCE_UNSET;
1772 r->start = 0; 1777 r->start = 0;
1773 r->end = 0xff; 1778 r->end = 0xff;
1774 } 1779 }
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 5d595724e5f4..c1839450d4d6 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -197,8 +197,10 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom)
197void pci_cleanup_rom(struct pci_dev *pdev) 197void pci_cleanup_rom(struct pci_dev *pdev)
198{ 198{
199 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; 199 struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
200
200 if (res->flags & IORESOURCE_ROM_COPY) { 201 if (res->flags & IORESOURCE_ROM_COPY) {
201 kfree((void*)(unsigned long)res->start); 202 kfree((void*)(unsigned long)res->start);
203 res->flags |= IORESOURCE_UNSET;
202 res->flags &= ~IORESOURCE_ROM_COPY; 204 res->flags &= ~IORESOURCE_ROM_COPY;
203 res->start = 0; 205 res->start = 0;
204 res->end = 0; 206 res->end = 0;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 5c060b152ce6..7eed671d5586 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -44,6 +44,9 @@ void pci_update_resource(struct pci_dev *dev, int resno)
44 if (!res->flags) 44 if (!res->flags)
45 return; 45 return;
46 46
47 if (res->flags & IORESOURCE_UNSET)
48 return;
49
47 /* 50 /*
48 * Ignore non-moveable resources. This might be legacy resources for 51 * Ignore non-moveable resources. This might be legacy resources for
49 * which no functional BAR register exists or another important 52 * which no functional BAR register exists or another important
@@ -101,11 +104,6 @@ void pci_update_resource(struct pci_dev *dev, int resno)
101 104
102 if (disable) 105 if (disable)
103 pci_write_config_word(dev, PCI_COMMAND, cmd); 106 pci_write_config_word(dev, PCI_COMMAND, cmd);
104
105 res->flags &= ~IORESOURCE_UNSET;
106 dev_dbg(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx])\n",
107 resno, res, (unsigned long long)region.start,
108 (unsigned long long)region.end);
109} 107}
110 108
111int pci_claim_resource(struct pci_dev *dev, int resource) 109int pci_claim_resource(struct pci_dev *dev, int resource)
@@ -113,18 +111,23 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
113 struct resource *res = &dev->resource[resource]; 111 struct resource *res = &dev->resource[resource];
114 struct resource *root, *conflict; 112 struct resource *root, *conflict;
115 113
114 if (res->flags & IORESOURCE_UNSET) {
115 dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n",
116 resource, res);
117 return -EINVAL;
118 }
119
116 root = pci_find_parent_resource(dev, res); 120 root = pci_find_parent_resource(dev, res);
117 if (!root) { 121 if (!root) {
118 dev_info(&dev->dev, "no compatible bridge window for %pR\n", 122 dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
119 res); 123 resource, res);
120 return -EINVAL; 124 return -EINVAL;
121 } 125 }
122 126
123 conflict = request_resource_conflict(root, res); 127 conflict = request_resource_conflict(root, res);
124 if (conflict) { 128 if (conflict) {
125 dev_info(&dev->dev, 129 dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
126 "address space collision: %pR conflicts with %s %pR\n", 130 resource, res, conflict->name, conflict);
127 res, conflict->name, conflict);
128 return -EBUSY; 131 return -EBUSY;
129 } 132 }
130 133
@@ -263,6 +266,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
263 resource_size_t align, size; 266 resource_size_t align, size;
264 int ret; 267 int ret;
265 268
269 res->flags |= IORESOURCE_UNSET;
266 align = pci_resource_alignment(dev, res); 270 align = pci_resource_alignment(dev, res);
267 if (!align) { 271 if (!align) {
268 dev_info(&dev->dev, "BAR %d: can't assign %pR " 272 dev_info(&dev->dev, "BAR %d: can't assign %pR "
@@ -282,6 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
282 ret = pci_revert_fw_address(res, dev, resno, size); 286 ret = pci_revert_fw_address(res, dev, resno, size);
283 287
284 if (!ret) { 288 if (!ret) {
289 res->flags &= ~IORESOURCE_UNSET;
285 res->flags &= ~IORESOURCE_STARTALIGN; 290 res->flags &= ~IORESOURCE_STARTALIGN;
286 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); 291 dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
287 if (resno < PCI_BRIDGE_RESOURCES) 292 if (resno < PCI_BRIDGE_RESOURCES)
@@ -297,6 +302,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
297 resource_size_t new_size; 302 resource_size_t new_size;
298 int ret; 303 int ret;
299 304
305 res->flags |= IORESOURCE_UNSET;
300 if (!res->parent) { 306 if (!res->parent) {
301 dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " 307 dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR "
302 "\n", resno, res); 308 "\n", resno, res);
@@ -307,6 +313,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
307 new_size = resource_size(res) + addsize; 313 new_size = resource_size(res) + addsize;
308 ret = _pci_assign_resource(dev, resno, new_size, min_align); 314 ret = _pci_assign_resource(dev, resno, new_size, min_align);
309 if (!ret) { 315 if (!ret) {
316 res->flags &= ~IORESOURCE_UNSET;
310 res->flags &= ~IORESOURCE_STARTALIGN; 317 res->flags &= ~IORESOURCE_STARTALIGN;
311 dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); 318 dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
312 if (resno < PCI_BRIDGE_RESOURCES) 319 if (resno < PCI_BRIDGE_RESOURCES)
@@ -336,9 +343,15 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
336 (!(r->flags & IORESOURCE_ROM_ENABLE))) 343 (!(r->flags & IORESOURCE_ROM_ENABLE)))
337 continue; 344 continue;
338 345
346 if (r->flags & IORESOURCE_UNSET) {
347 dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
348 i, r);
349 return -EINVAL;
350 }
351
339 if (!r->parent) { 352 if (!r->parent) {
340 dev_err(&dev->dev, "device not available " 353 dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n",
341 "(can't reserve %pR)\n", r); 354 i, r);
342 return -EINVAL; 355 return -EINVAL;
343 } 356 }
344 357
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 89b7c24a36e9..5e3a906cc089 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -51,7 +51,7 @@ struct resource {
51 51
52#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */ 52#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
53#define IORESOURCE_DISABLED 0x10000000 53#define IORESOURCE_DISABLED 0x10000000
54#define IORESOURCE_UNSET 0x20000000 54#define IORESOURCE_UNSET 0x20000000 /* No address assigned yet */
55#define IORESOURCE_AUTO 0x40000000 55#define IORESOURCE_AUTO 0x40000000
56#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ 56#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */
57 57
@@ -169,6 +169,16 @@ static inline unsigned long resource_type(const struct resource *res)
169{ 169{
170 return res->flags & IORESOURCE_TYPE_BITS; 170 return res->flags & IORESOURCE_TYPE_BITS;
171} 171}
172/* True iff r1 completely contains r2 */
173static inline bool resource_contains(struct resource *r1, struct resource *r2)
174{
175 if (resource_type(r1) != resource_type(r2))
176 return false;
177 if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET)
178 return false;
179 return r1->start <= r2->start && r1->end >= r2->end;
180}
181
172 182
173/* Convenience shorthand with allocation */ 183/* Convenience shorthand with allocation */
174#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0) 184#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d47b352c2e11..aab57b4abe7f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1066,7 +1066,7 @@ void pci_bus_remove_resources(struct pci_bus *bus);
1066int __must_check pci_bus_alloc_resource(struct pci_bus *bus, 1066int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
1067 struct resource *res, resource_size_t size, 1067 struct resource *res, resource_size_t size,
1068 resource_size_t align, resource_size_t min, 1068 resource_size_t align, resource_size_t min,
1069 unsigned int type_mask, 1069 unsigned long type_mask,
1070 resource_size_t (*alignf)(void *, 1070 resource_size_t (*alignf)(void *,
1071 const struct resource *, 1071 const struct resource *,
1072 resource_size_t, 1072 resource_size_t,
diff --git a/kernel/resource.c b/kernel/resource.c
index 3f285dce9347..673061c06da1 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -432,11 +432,6 @@ static void resource_clip(struct resource *res, resource_size_t min,
432 res->end = max; 432 res->end = max;
433} 433}
434 434
435static bool resource_contains(struct resource *res1, struct resource *res2)
436{
437 return res1->start <= res2->start && res1->end >= res2->end;
438}
439
440/* 435/*
441 * Find empty slot in the resource tree with the given range and 436 * Find empty slot in the resource tree with the given range and
442 * alignment constraints 437 * alignment constraints
@@ -471,10 +466,11 @@ static int __find_resource(struct resource *root, struct resource *old,
471 arch_remove_reservations(&tmp); 466 arch_remove_reservations(&tmp);
472 467
473 /* Check for overflow after ALIGN() */ 468 /* Check for overflow after ALIGN() */
474 avail = *new;
475 avail.start = ALIGN(tmp.start, constraint->align); 469 avail.start = ALIGN(tmp.start, constraint->align);
476 avail.end = tmp.end; 470 avail.end = tmp.end;
471 avail.flags = new->flags & ~IORESOURCE_UNSET;
477 if (avail.start >= tmp.start) { 472 if (avail.start >= tmp.start) {
473 alloc.flags = avail.flags;
478 alloc.start = constraint->alignf(constraint->alignf_data, &avail, 474 alloc.start = constraint->alignf(constraint->alignf_data, &avail,
479 size, constraint->align); 475 size, constraint->align);
480 alloc.end = alloc.start + size - 1; 476 alloc.end = alloc.start + size - 1;
@@ -949,8 +945,8 @@ struct resource * __request_region(struct resource *parent,
949 res->name = name; 945 res->name = name;
950 res->start = start; 946 res->start = start;
951 res->end = start + n - 1; 947 res->end = start + n - 1;
952 res->flags = IORESOURCE_BUSY; 948 res->flags = resource_type(parent);
953 res->flags |= flags; 949 res->flags |= IORESOURCE_BUSY | flags;
954 950
955 write_lock(&resource_lock); 951 write_lock(&resource_lock);
956 952
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 185b6d300ebc..5e2cf6f342f8 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -719,10 +719,15 @@ char *resource_string(char *buf, char *end, struct resource *res,
719 specp = &mem_spec; 719 specp = &mem_spec;
720 decode = 0; 720 decode = 0;
721 } 721 }
722 p = number(p, pend, res->start, *specp); 722 if (decode && res->flags & IORESOURCE_UNSET) {
723 if (res->start != res->end) { 723 p = string(p, pend, "size ", str_spec);
724 *p++ = '-'; 724 p = number(p, pend, resource_size(res), *specp);
725 p = number(p, pend, res->end, *specp); 725 } else {
726 p = number(p, pend, res->start, *specp);
727 if (res->start != res->end) {
728 *p++ = '-';
729 p = number(p, pend, res->end, *specp);
730 }
726 } 731 }
727 if (decode) { 732 if (decode) {
728 if (res->flags & IORESOURCE_MEM_64) 733 if (res->flags & IORESOURCE_MEM_64)