diff options
Diffstat (limited to 'freebsd/sys/kern/subr_rman.c')
-rw-r--r-- | freebsd/sys/kern/subr_rman.c | 134 |
1 files changed, 85 insertions, 49 deletions
diff --git a/freebsd/sys/kern/subr_rman.c b/freebsd/sys/kern/subr_rman.c index 69f8d359..115d5d8d 100644 --- a/freebsd/sys/kern/subr_rman.c +++ b/freebsd/sys/kern/subr_rman.c @@ -92,18 +92,17 @@ struct resource_i { TAILQ_ENTRY(resource_i) r_link; LIST_ENTRY(resource_i) r_sharelink; LIST_HEAD(, resource_i) *r_sharehead; - u_long r_start; /* index of the first entry in this resource */ - u_long r_end; /* index of the last entry (inclusive) */ + rman_res_t r_start; /* index of the first entry in this resource */ + rman_res_t r_end; /* index of the last entry (inclusive) */ u_int r_flags; void *r_virtual; /* virtual address of this resource */ - struct device *r_dev; /* device which has allocated this resource */ + device_t r_dev; /* device which has allocated this resource */ struct rman *r_rm; /* resource manager from whence this came */ int r_rid; /* optional rid for this resource. */ }; static int rman_debug = 0; -TUNABLE_INT("debug.rman_debug", &rman_debug); -SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RW, +SYSCTL_INT(_debug, OID_AUTO, rman_debug, CTLFLAG_RWTUN, &rman_debug, 0, "rman debug"); #define DPRINTF(params) if (rman_debug) printf params @@ -138,7 +137,7 @@ rman_init(struct rman *rm) } if (rm->rm_start == 0 && rm->rm_end == 0) - rm->rm_end = ~0ul; + rm->rm_end = ~0; if (rm->rm_type == RMAN_UNINIT) panic("rman_init"); if (rm->rm_type == RMAN_GAUGE) @@ -157,11 +156,12 @@ rman_init(struct rman *rm) } int -rman_manage_region(struct rman *rm, u_long start, u_long end) +rman_manage_region(struct rman *rm, rman_res_t start, rman_res_t end) { struct resource_i *r, *s, *t; + int rv = 0; - DPRINTF(("rman_manage_region: <%s> request: start %#lx, end %#lx\n", + DPRINTF(("rman_manage_region: <%s> request: start %#jx, end %#jx\n", rm->rm_descr, start, end)); if (start < rm->rm_start || end > rm->rm_end) return EINVAL; @@ -176,7 +176,7 @@ rman_manage_region(struct rman *rm, u_long start, u_long end) /* Skip entries before us. */ TAILQ_FOREACH(s, &rm->rm_list, r_link) { - if (s->r_end == ULONG_MAX) + if (s->r_end == ~0) break; if (s->r_end + 1 >= r->r_start) break; @@ -187,13 +187,17 @@ rman_manage_region(struct rman *rm, u_long start, u_long end) TAILQ_INSERT_TAIL(&rm->rm_list, r, r_link); } else { /* Check for any overlap with the current region. */ - if (r->r_start <= s->r_end && r->r_end >= s->r_start) - return EBUSY; + if (r->r_start <= s->r_end && r->r_end >= s->r_start) { + rv = EBUSY; + goto out; + } /* Check for any overlap with the next region. */ t = TAILQ_NEXT(s, r_link); - if (t && r->r_start <= t->r_end && r->r_end >= t->r_start) - return EBUSY; + if (t && r->r_start <= t->r_end && r->r_end >= t->r_start) { + rv = EBUSY; + goto out; + } /* * See if this region can be merged with the next region. If @@ -224,9 +228,9 @@ rman_manage_region(struct rman *rm, u_long start, u_long end) TAILQ_INSERT_BEFORE(s, r, r_link); } } - +out: mtx_unlock(rm->rm_mtx); - return 0; + return rv; } int @@ -272,7 +276,7 @@ rman_fini(struct rman *rm) } int -rman_first_free_region(struct rman *rm, u_long *start, u_long *end) +rman_first_free_region(struct rman *rm, rman_res_t *start, rman_res_t *end) { struct resource_i *r; @@ -290,7 +294,7 @@ rman_first_free_region(struct rman *rm, u_long *start, u_long *end) } int -rman_last_free_region(struct rman *rm, u_long *start, u_long *end) +rman_last_free_region(struct rman *rm, rman_res_t *start, rman_res_t *end) { struct resource_i *r; @@ -309,7 +313,7 @@ rman_last_free_region(struct rman *rm, u_long *start, u_long *end) /* Shrink or extend one or both ends of an allocated resource. */ int -rman_adjust_resource(struct resource *rr, u_long start, u_long end) +rman_adjust_resource(struct resource *rr, rman_res_t start, rman_res_t end) { struct resource_i *r, *s, *t, *new; struct rman *rm; @@ -432,18 +436,18 @@ rman_adjust_resource(struct resource *rr, u_long start, u_long end) #define SHARE_TYPE(f) (f & (RF_SHAREABLE | RF_PREFETCHABLE)) struct resource * -rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, - u_long count, u_long bound, u_int flags, - struct device *dev) +rman_reserve_resource_bound(struct rman *rm, rman_res_t start, rman_res_t end, + rman_res_t count, rman_res_t bound, u_int flags, + device_t dev) { u_int new_rflags; struct resource_i *r, *s, *rv; - u_long rstart, rend, amask, bmask; + rman_res_t rstart, rend, amask, bmask; rv = NULL; - DPRINTF(("rman_reserve_resource_bound: <%s> request: [%#lx, %#lx], " - "length %#lx, flags %u, device %s\n", rm->rm_descr, start, end, + DPRINTF(("rman_reserve_resource_bound: <%s> request: [%#jx, %#jx], " + "length %#jx, flags %x, device %s\n", rm->rm_descr, start, end, count, flags, dev == NULL ? "<null>" : device_get_nameunit(dev))); KASSERT((flags & RF_FIRSTSHARE) == 0, @@ -452,19 +456,29 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, mtx_lock(rm->rm_mtx); + r = TAILQ_FIRST(&rm->rm_list); + if (r == NULL) { + DPRINTF(("NULL list head\n")); + } else { + DPRINTF(("rman_reserve_resource_bound: trying %#jx <%#jx,%#jx>\n", + r->r_end, start, count-1)); + } for (r = TAILQ_FIRST(&rm->rm_list); r && r->r_end < start + count - 1; - r = TAILQ_NEXT(r, r_link)) + r = TAILQ_NEXT(r, r_link)) { ; + DPRINTF(("rman_reserve_resource_bound: tried %#jx <%#jx,%#jx>\n", + r->r_end, start, count-1)); + } if (r == NULL) { DPRINTF(("could not find a region\n")); goto out; } - amask = (1ul << RF_ALIGNMENT(flags)) - 1; - KASSERT(start <= ULONG_MAX - amask, - ("start (%#lx) + amask (%#lx) would wrap around", start, amask)); + amask = (1ull << RF_ALIGNMENT(flags)) - 1; + KASSERT(start <= RM_MAX_END - amask, + ("start (%#jx) + amask (%#jx) would wrap around", start, amask)); /* If bound is 0, bmask will also be 0 */ bmask = ~(bound - 1); @@ -472,18 +486,18 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, * First try to find an acceptable totally-unshared region. */ for (s = r; s; s = TAILQ_NEXT(s, r_link)) { - DPRINTF(("considering [%#lx, %#lx]\n", s->r_start, s->r_end)); + DPRINTF(("considering [%#jx, %#jx]\n", s->r_start, s->r_end)); /* * The resource list is sorted, so there is no point in * searching further once r_start is too large. */ if (s->r_start > end - (count - 1)) { - DPRINTF(("s->r_start (%#lx) + count - 1> end (%#lx)\n", + DPRINTF(("s->r_start (%#jx) + count - 1> end (%#jx)\n", s->r_start, end)); break; } - if (s->r_start > ULONG_MAX - amask) { - DPRINTF(("s->r_start (%#lx) + amask (%#lx) too large\n", + if (s->r_start > RM_MAX_END - amask) { + DPRINTF(("s->r_start (%#jx) + amask (%#jx) too large\n", s->r_start, amask)); break; } @@ -491,7 +505,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, DPRINTF(("region is allocated\n")); continue; } - rstart = ulmax(s->r_start, start); + rstart = ummax(s->r_start, start); /* * Try to find a region by adjusting to boundary and alignment * until both conditions are satisfied. This is not an optimal @@ -503,16 +517,16 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, rstart += bound - (rstart & ~bmask); } while ((rstart & amask) != 0 && rstart < end && rstart < s->r_end); - rend = ulmin(s->r_end, ulmax(rstart + count - 1, end)); + rend = ummin(s->r_end, ummax(rstart + count - 1, end)); if (rstart > rend) { DPRINTF(("adjusted start exceeds end\n")); continue; } - DPRINTF(("truncated region: [%#lx, %#lx]; size %#lx (requested %#lx)\n", + DPRINTF(("truncated region: [%#jx, %#jx]; size %#jx (requested %#jx)\n", rstart, rend, (rend - rstart + 1), count)); if ((rend - rstart + 1) >= count) { - DPRINTF(("candidate region: [%#lx, %#lx], size %#lx\n", + DPRINTF(("candidate region: [%#jx, %#jx], size %#jx\n", rstart, rend, (rend - rstart + 1))); if ((s->r_end - s->r_start + 1) == count) { DPRINTF(("candidate region is entire chunk\n")); @@ -543,7 +557,7 @@ rman_reserve_resource_bound(struct rman *rm, u_long start, u_long end, if (s->r_start < rv->r_start && s->r_end > rv->r_end) { DPRINTF(("splitting region in three parts: " - "[%#lx, %#lx]; [%#lx, %#lx]; [%#lx, %#lx]\n", + "[%#jx, %#jx]; [%#jx, %#jx]; [%#jx, %#jx]\n", s->r_start, rv->r_start - 1, rv->r_start, rv->r_end, rv->r_end + 1, s->r_end)); @@ -639,8 +653,8 @@ out: } struct resource * -rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count, - u_int flags, struct device *dev) +rman_reserve_resource(struct rman *rm, rman_res_t start, rman_res_t end, + rman_res_t count, u_int flags, device_t dev) { return (rman_reserve_resource_bound(rm, start, end, count, 0, flags, @@ -801,13 +815,13 @@ rman_make_alignment_flags(uint32_t size) } void -rman_set_start(struct resource *r, u_long start) +rman_set_start(struct resource *r, rman_res_t start) { r->__r_i->r_start = start; } -u_long +rman_res_t rman_get_start(struct resource *r) { @@ -815,20 +829,20 @@ rman_get_start(struct resource *r) } void -rman_set_end(struct resource *r, u_long end) +rman_set_end(struct resource *r, rman_res_t end) { r->__r_i->r_end = end; } -u_long +rman_res_t rman_get_end(struct resource *r) { return (r->__r_i->r_end); } -u_long +rman_res_t rman_get_size(struct resource *r) { @@ -885,6 +899,27 @@ rman_get_bushandle(struct resource *r) } void +rman_set_mapping(struct resource *r, struct resource_map *map) +{ + + KASSERT(rman_get_size(r) == map->r_size, + ("rman_set_mapping: size mismatch")); + rman_set_bustag(r, map->r_bustag); + rman_set_bushandle(r, map->r_bushandle); + rman_set_virtual(r, map->r_vaddr); +} + +void +rman_get_mapping(struct resource *r, struct resource_map *map) +{ + + map->r_bustag = rman_get_bustag(r); + map->r_bushandle = rman_get_bushandle(r); + map->r_size = rman_get_size(r); + map->r_vaddr = rman_get_virtual(r); +} + +void rman_set_rid(struct resource *r, int rid) { @@ -899,13 +934,13 @@ rman_get_rid(struct resource *r) } void -rman_set_device(struct resource *r, struct device *dev) +rman_set_device(struct resource *r, device_t dev) { r->__r_i->r_dev = dev; } -struct device * +device_t rman_get_device(struct resource *r) { @@ -1030,8 +1065,8 @@ dump_rman_header(struct rman *rm) if (db_pager_quit) return; - db_printf("rman %p: %s (0x%lx-0x%lx full range)\n", - rm, rm->rm_descr, rm->rm_start, rm->rm_end); + db_printf("rman %p: %s (0x%jx-0x%jx full range)\n", + rm, rm->rm_descr, (rman_res_t)rm->rm_start, (rman_res_t)rm->rm_end); } static void @@ -1049,7 +1084,8 @@ dump_rman(struct rman *rm) devname = "nomatch"; } else devname = NULL; - db_printf(" 0x%lx-0x%lx ", r->r_start, r->r_end); + db_printf(" 0x%jx-0x%jx (RID=%d) ", + r->r_start, r->r_end, r->r_rid); if (devname != NULL) db_printf("(%s)\n", devname); else |