| 435 | #define SHARE_TYPE(f) (f & (RF_SHAREABLE | RF_PREFETCHABLE)) |
| 436 | |
| 437 | struct resource * |
| 438 | rman_reserve_resource_bound(struct rman *rm, rman_res_t start, rman_res_t end, |
| 439 | rman_res_t count, rman_res_t bound, u_int flags, |
| 440 | device_t dev) |
| 441 | { |
| 442 | u_int new_rflags; |
| 443 | struct resource_i *r, *s, *rv; |
| 444 | rman_res_t rstart, rend, amask, bmask; |
| 445 | |
| 446 | rv = NULL; |
| 447 | |
| 448 | DPRINTF(("rman_reserve_resource_bound: <%s> request: [%#jx, %#jx], " |
| 449 | "length %#jx, flags %x, device %s\n", rm->rm_descr, start, end, |
| 450 | count, flags, |
| 451 | dev == NULL ? "<null>" : device_get_nameunit(dev))); |
| 452 | KASSERT((flags & RF_FIRSTSHARE) == 0, |
| 453 | ("invalid flags %#x", flags)); |
| 454 | new_rflags = (flags & ~RF_FIRSTSHARE) | RF_ALLOCATED; |
| 455 | |
| 456 | mtx_lock(rm->rm_mtx); |
| 457 | |
| 458 | r = TAILQ_FIRST(&rm->rm_list); |
| 459 | if (r == NULL) { |
| 460 | DPRINTF(("NULL list head\n")); |
| 461 | } else { |
| 462 | DPRINTF(("rman_reserve_resource_bound: trying %#jx <%#jx,%#jx>\n", |
| 463 | r->r_end, start, count-1)); |
| 464 | } |
| 465 | for (r = TAILQ_FIRST(&rm->rm_list); |
| 466 | r && r->r_end < start + count - 1; |
| 467 | r = TAILQ_NEXT(r, r_link)) { |
| 468 | ; |
| 469 | DPRINTF(("rman_reserve_resource_bound: tried %#jx <%#jx,%#jx>\n", |
| 470 | r->r_end, start, count-1)); |
| 471 | } |
| 472 | |
| 473 | if (r == NULL) { |
| 474 | DPRINTF(("could not find a region\n")); |
| 475 | goto out; |
| 476 | } |
| 477 | |
| 478 | amask = (1ull << RF_ALIGNMENT(flags)) - 1; |
| 479 | KASSERT(start <= RM_MAX_END - amask, |
| 480 | ("start (%#jx) + amask (%#jx) would wrap around", start, amask)); |
| 481 | |
| 482 | /* If bound is 0, bmask will also be 0 */ |
| 483 | bmask = ~(bound - 1); |
| 484 | /* |
| 485 | * First try to find an acceptable totally-unshared region. |
| 486 | */ |
| 487 | for (s = r; s; s = TAILQ_NEXT(s, r_link)) { |
| 488 | DPRINTF(("considering [%#jx, %#jx]\n", s->r_start, s->r_end)); |
| 489 | /* |
| 490 | * The resource list is sorted, so there is no point in |
| 491 | * searching further once r_start is too large. |
| 492 | */ |
| 493 | if (s->r_start > end - (count - 1)) { |
| 494 | DPRINTF(("s->r_start (%#jx) + count - 1> end (%#jx)\n", |
no test coverage detected