diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-03-19 17:11:19 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-03-19 17:11:19 -0400 |
commit | 30723cbf6f7aec2ab4810bdc4bf12c5749a09e33 (patch) | |
tree | 840833435357419595fee44b2a06f9864f1458c9 | |
parent | 91b4adc983d8e9975bc677c2b8395631edf7b92d (diff) | |
parent | f2e6027b816df3326d3f40d6ce55539a2f381529 (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.c | 6 | ||||
-rw-r--r-- | arch/microblaze/pci/pci-common.c | 5 | ||||
-rw-r--r-- | arch/s390/pci/pci.c | 16 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/leon_pci.c | 5 | ||||
-rw-r--r-- | arch/tile/kernel/pci_gx.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/aperture_64.c | 20 | ||||
-rw-r--r-- | drivers/message/i2o/iop.c | 85 | ||||
-rw-r--r-- | drivers/pci/bus.c | 8 | ||||
-rw-r--r-- | drivers/pci/host-bridge.c | 8 | ||||
-rw-r--r-- | drivers/pci/pci.c | 46 | ||||
-rw-r--r-- | drivers/pci/probe.c | 17 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 5 | ||||
-rw-r--r-- | drivers/pci/rom.c | 2 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 37 | ||||
-rw-r--r-- | include/linux/ioport.h | 12 | ||||
-rw-r--r-- | include/linux/pci.h | 2 | ||||
-rw-r--r-- | kernel/resource.c | 12 | ||||
-rw-r--r-- | lib/vsprintf.c | 13 |
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 | ||
257 | int | ||
258 | pcibios_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 | } |
1295 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | 1295 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); |
1296 | 1296 | ||
1297 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
1298 | { | ||
1299 | return pci_enable_resources(dev, mask); | ||
1300 | } | ||
1301 | |||
1302 | static void pcibios_setup_phb_resources(struct pci_controller *hose, | 1297 | static 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) | |||
686 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | 686 | int 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 | ||
712 | void pcibios_disable_device(struct pci_dev *pdev) | 698 | void 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 | ||
189 | int pcibios_enable_device(struct pci_dev *dev, int mask) | ||
190 | { | ||
191 | return pci_enable_resources(dev, mask); | ||
192 | } | ||
193 | |||
194 | static void __init | 189 | static void __init |
195 | pcibios_bus_report_status_early(struct pci_channel *hose, | 190 | pcibios_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 | ||
102 | int 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 | */ | ||
1074 | int 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 | ||
55 | int fix_aperture __initdata = 1; | 54 | int fix_aperture __initdata = 1; |
56 | 55 | ||
57 | static struct resource gart_resource = { | ||
58 | .name = "GART", | ||
59 | .flags = IORESOURCE_MEM, | ||
60 | }; | ||
61 | |||
62 | static 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 | ||
445 | out: | 431 | out: |
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 | ||
655 | static 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 | ||
133 | static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res, | 133 | static 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 | */ |
203 | int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | 201 | int 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 | ||
35 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
36 | { | ||
37 | return res1->start <= res2->start && res1->end >= res2->end; | ||
38 | } | ||
39 | |||
40 | void pcibios_resource_to_bus(struct pci_bus *bus, struct pci_bus_region *region, | 35 | void 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 | */ |
407 | struct resource * | 406 | struct resource * |
408 | pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | 407 | pci_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 | } |
1179 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); | 1186 | EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state); |
1180 | 1187 | ||
1188 | int __weak pcibios_enable_device(struct pci_dev *dev, int bars) | ||
1189 | { | ||
1190 | return pci_enable_resources(dev, bars); | ||
1191 | } | ||
1192 | |||
1181 | static int do_pci_enable_device(struct pci_dev *dev, int bars) | 1193 | static 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, ®ion); | 1124 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
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, ®ion); | 1131 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
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, ®ion); | 1140 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
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, ®ion); | 1147 | pcibios_bus_to_resource(dev->bus, res, ®ion); |
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 | |||
937 | static void quirk_dunord(struct pci_dev *dev) | 938 | static 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) | |||
197 | void pci_cleanup_rom(struct pci_dev *pdev) | 197 | void 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 | ||
111 | int pci_claim_resource(struct pci_dev *dev, int resource) | 109 | int 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 */ | ||
173 | static 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); | |||
1066 | int __must_check pci_bus_alloc_resource(struct pci_bus *bus, | 1066 | int __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 | ||
435 | static 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) |