Shrink or extend one or both ends of an allocated resource. */
| 312 | |
| 313 | /* Shrink or extend one or both ends of an allocated resource. */ |
| 314 | int |
| 315 | rman_adjust_resource(struct resource *rr, rman_res_t start, rman_res_t end) |
| 316 | { |
| 317 | struct resource_i *r, *s, *t, *new; |
| 318 | struct rman *rm; |
| 319 | |
| 320 | /* Not supported for shared resources. */ |
| 321 | r = rr->__r_i; |
| 322 | if (r->r_flags & RF_SHAREABLE) |
| 323 | return (EINVAL); |
| 324 | |
| 325 | /* |
| 326 | * This does not support wholesale moving of a resource. At |
| 327 | * least part of the desired new range must overlap with the |
| 328 | * existing resource. |
| 329 | */ |
| 330 | if (end < r->r_start || r->r_end < start) |
| 331 | return (EINVAL); |
| 332 | |
| 333 | /* |
| 334 | * Find the two resource regions immediately adjacent to the |
| 335 | * allocated resource. |
| 336 | */ |
| 337 | rm = r->r_rm; |
| 338 | mtx_lock(rm->rm_mtx); |
| 339 | #ifdef INVARIANTS |
| 340 | TAILQ_FOREACH(s, &rm->rm_list, r_link) { |
| 341 | if (s == r) |
| 342 | break; |
| 343 | } |
| 344 | if (s == NULL) |
| 345 | panic("resource not in list"); |
| 346 | #endif |
| 347 | s = TAILQ_PREV(r, resource_head, r_link); |
| 348 | t = TAILQ_NEXT(r, r_link); |
| 349 | KASSERT(s == NULL || s->r_end + 1 == r->r_start, |
| 350 | ("prev resource mismatch")); |
| 351 | KASSERT(t == NULL || r->r_end + 1 == t->r_start, |
| 352 | ("next resource mismatch")); |
| 353 | |
| 354 | /* |
| 355 | * See if the changes are permitted. Shrinking is always allowed, |
| 356 | * but growing requires sufficient room in the adjacent region. |
| 357 | */ |
| 358 | if (start < r->r_start && (s == NULL || (s->r_flags & RF_ALLOCATED) || |
| 359 | s->r_start > start)) { |
| 360 | mtx_unlock(rm->rm_mtx); |
| 361 | return (EBUSY); |
| 362 | } |
| 363 | if (end > r->r_end && (t == NULL || (t->r_flags & RF_ALLOCATED) || |
| 364 | t->r_end < end)) { |
| 365 | mtx_unlock(rm->rm_mtx); |
| 366 | return (EBUSY); |
| 367 | } |
| 368 | |
| 369 | /* |
| 370 | * While holding the lock, grow either end of the resource as |
| 371 | * needed and shrink either end if the shrinking does not require |
no test coverage detected