__find_resource_space() currently uses resource_contains() but for tentative resources that are not yet crafted into the resource tree. As resource_contains() checks that IORESOURCE_UNSET is not set for either of the resources, the caller has to hack around this problem by clearing the IORESOURCE_UNSET flag (essentially lying to resource_contains()). Instead of the hack, introduce __resource_contains_unbound() for cases like this.
Unified · Split
| @@ -304,14 +304,28 @@ static inline unsigned long resource_ext_type(const struct resource *res) · 303 unmodified lines | ||
| 304 | 304 | { |
| 305 | 305 | return res->flags & IORESOURCE_EXT_TYPE_BITS; |
| 306 | 306 | } |
| 307 | −/* True iff r1 completely contains r2 */ | |
| 308 | −static inline bool resource_contains(const struct resource *r1, const struct resource *r2) | |
| 307 | + | |
| 308 | +/* | |
| 309 | + * For checking if @r1 completely contains @r2 for resources that have real | |
| 310 | + * addresses but are not yet crafted into the resource tree. Normally | |
| 311 | + * resource_contains() should be used instead of this function as it checks | |
| 312 | + * also IORESOURCE_UNSET flag. | |
| 313 | + */ | |
| 314 | +static inline bool __resource_contains_unbound(const struct resource *r1, | |
| 315 | + const struct resource *r2) | |
| 309 | 316 | { |
| 310 | 317 | if (resource_type(r1) != resource_type(r2)) |
| 311 | 318 | return false; |
| 319 | + | |
| 320 | + return r1->start <= r2->start && r1->end >= r2->end; | |
| 321 | +} | |
| 322 | +/* True iff r1 completely contains r2 */ | |
| 323 | +static inline bool resource_contains(const struct resource *r1, const struct resource *r2) | |
| 324 | +{ | |
| 312 | 325 | if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET) |
| 313 | 326 | return false; |
| 314 | − return r1->start <= r2->start && r1->end >= r2->end; | |
| 327 | + | |
| 328 | + return __resource_contains_unbound(r1, r2); | |
| 315 | 329 | } |
| 316 | 330 | |
| 317 | 331 | /* True if any part of r1 overlaps r2 */ |
| @@ -754,7 +754,7 @@ static int __find_resource_space(struct resource *root, struct resource *old, · 753 unmodified lines | ||
| 754 | 754 | /* Check for overflow after ALIGN() */ |
| 755 | 755 | avail.start = ALIGN(tmp.start, constraint->align); |
| 756 | 756 | avail.end = tmp.end; |
| 757 | − avail.flags = new->flags & ~IORESOURCE_UNSET; | |
| 757 | + avail.flags = new->flags; | |
| 758 | 758 | if (avail.start >= tmp.start) { |
| 759 | 759 | alloc.flags = avail.flags; |
| 760 | 760 | if (alignf) { |
| @@ -765,7 +765,7 @@ static int __find_resource_space(struct resource *root, struct resource *old, · 4 unmodified lines | ||
| 765 | 765 | } |
| 766 | 766 | alloc.end = alloc.start + size - 1; |
| 767 | 767 | if (alloc.start <= alloc.end && |
| 768 | − resource_contains(&avail, &alloc)) { | |
| 768 | + __resource_contains_unbound(&avail, &alloc)) { | |
| 769 | 769 | new->start = alloc.start; |
| 770 | 770 | new->end = alloc.end; |
| 771 | 771 | return 0; |