diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-04 22:32:28 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-02-26 16:42:09 -0500 |
commit | 5edb93b89f6cc3089ee283656555e7a9ad36a8a0 (patch) | |
tree | 496964f830aa06af8351de8645ec7e19ef931264 | |
parent | d2e074ccbf84e91819ae07b3ca838120db2c97a9 (diff) |
resource: Add resource_contains()
We have two identical copies of resource_contains() already, and more
places that could use it. This moves it to ioport.h where it can be
shared.
resource_contains(struct resource *r1, struct resource *r2) returns true
iff r1 and r2 are the same type (most callers already checked this
separately) and the r1 address range completely contains r2.
In addition, the new resource_contains() checks that both r1 and r2 have
addresses assigned to them. If a resource is IORESOURCE_UNSET, it doesn't
have a valid address and can't contain or be contained by another resource.
Some callers already check this or for res->start.
No functional change.
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | drivers/pci/host-bridge.c | 8 | ||||
-rw-r--r-- | include/linux/ioport.h | 10 | ||||
-rw-r--r-- | kernel/resource.c | 8 |
3 files changed, 12 insertions, 14 deletions
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/include/linux/ioport.h b/include/linux/ioport.h index 89b7c24a36e9..9fcaac8bc4f6 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -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/kernel/resource.c b/kernel/resource.c index 3f285dce9347..a8344dda7049 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; |