__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 | return res->flags & IORESOURCE_EXT_TYPE_BITS; | 305 | return res->flags & IORESOURCE_EXT_TYPE_BITS; |
| 306 | } | 306 | } |
| 307 | /* True iff r1 completely contains r2 */ | 307 | |
| 308 | static inline bool resource_contains(const struct resource *r1, const struct resource *r2) | 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 | if (resource_type(r1) != resource_type(r2)) | 317 | if (resource_type(r1) != resource_type(r2)) |
| 311 | return false; | 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 | if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET) | 325 | if (r1->flags & IORESOURCE_UNSET || r2->flags & IORESOURCE_UNSET) |
| 313 | return false; | 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 | /* True if any part of r1 overlaps r2 */ | 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 | /* Check for overflow after ALIGN() */ | 754 | /* Check for overflow after ALIGN() */ |
| 755 | avail.start = ALIGN(tmp.start, constraint->align); | 755 | avail.start = ALIGN(tmp.start, constraint->align); |
| 756 | avail.end = tmp.end; | 756 | avail.end = tmp.end; |
| 757 | avail.flags = new->flags & ~IORESOURCE_UNSET; | 757 | avail.flags = new->flags; |
| 758 | if (avail.start >= tmp.start) { | 758 | if (avail.start >= tmp.start) { |
| 759 | alloc.flags = avail.flags; | 759 | alloc.flags = avail.flags; |
| 760 | if (alignf) { | 760 | if (alignf) { |
| @@ -765,7 +765,7 @@ static int __find_resource_space(struct resource *root, struct resource *old, · 4 unmodified lines | |||
| 765 | } | 765 | } |
| 766 | alloc.end = alloc.start + size - 1; | 766 | alloc.end = alloc.start + size - 1; |
| 767 | if (alloc.start <= alloc.end && | 767 | if (alloc.start <= alloc.end && |
| 768 | resource_contains(&avail, &alloc)) { | 768 | __resource_contains_unbound(&avail, &alloc)) { |
| 769 | new->start = alloc.start; | 769 | new->start = alloc.start; |
| 770 | new->end = alloc.end; | 770 | new->end = alloc.end; |
| 771 | return 0; | 771 | return 0; |