Deleted Added
full compact
subr_rman.c (45569) subr_rman.c (45720)
1/*
2 * Copyright 1998 Massachusetts Institute of Technology
3 *
4 * Permission to use, copy, modify, and distribute this software and
5 * its documentation for any purpose and without fee is hereby
6 * granted, provided that both the above copyright notice and this
7 * permission notice appear in all copies, that both the above
8 * copyright notice and this permission notice appear in all

--- 12 unchanged lines hidden (view full) ---

21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*
2 * Copyright 1998 Massachusetts Institute of Technology
3 *
4 * Permission to use, copy, modify, and distribute this software and
5 * its documentation for any purpose and without fee is hereby
6 * granted, provided that both the above copyright notice and this
7 * permission notice appear in all copies, that both the above
8 * copyright notice and this permission notice appear in all

--- 12 unchanged lines hidden (view full) ---

21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id: subr_rman.c,v 1.5 1999/03/29 08:30:17 dfr Exp $
29 * $Id: subr_rman.c,v 1.6 1999/04/11 02:27:06 eivind Exp $
30 */
31
32/*
33 * The kernel resource manager. This code is responsible for keeping track
34 * of hardware resources which are apportioned out to various drivers.
35 * It does not actually assign those resources, and it is not expected
36 * that end-device drivers will call into this code directly. Rather,
37 * the code which implements the buses that those devices are attached to,

--- 19 unchanged lines hidden (view full) ---

57 * permitted.
58 */
59
60#include <sys/param.h>
61#include <sys/systm.h>
62#include <sys/kernel.h>
63#include <sys/lock.h>
64#include <sys/malloc.h>
30 */
31
32/*
33 * The kernel resource manager. This code is responsible for keeping track
34 * of hardware resources which are apportioned out to various drivers.
35 * It does not actually assign those resources, and it is not expected
36 * that end-device drivers will call into this code directly. Rather,
37 * the code which implements the buses that those devices are attached to,

--- 19 unchanged lines hidden (view full) ---

57 * permitted.
58 */
59
60#include <sys/param.h>
61#include <sys/systm.h>
62#include <sys/kernel.h>
63#include <sys/lock.h>
64#include <sys/malloc.h>
65#include <sys/rman.h>
66#include <sys/bus.h> /* XXX debugging */
65#include <sys/bus.h> /* XXX debugging */
66#include <machine/bus.h>
67#include <sys/rman.h>
67
68static MALLOC_DEFINE(M_RMAN, "rman", "Resource manager");
69
70struct rman_head rman_head;
71#ifndef NULL_SIMPLELOCKS
72static struct simplelock rman_lock; /* mutex to protect rman_head */
73#endif
74static int int_rman_activate_resource(struct rman *rm, struct resource *r,
75 struct resource **whohas);
68
69static MALLOC_DEFINE(M_RMAN, "rman", "Resource manager");
70
71struct rman_head rman_head;
72#ifndef NULL_SIMPLELOCKS
73static struct simplelock rman_lock; /* mutex to protect rman_head */
74#endif
75static int int_rman_activate_resource(struct rman *rm, struct resource *r,
76 struct resource **whohas);
77static int int_rman_deactivate_resource(struct resource *r);
76static int int_rman_release_resource(struct rman *rm, struct resource *r);
77
78#define CIRCLEQ_TERMCOND(var, head) (var == (void *)&(head))
79
80int
81rman_init(struct rman *rm)
82{
83 static int once;

--- 28 unchanged lines hidden (view full) ---

112int
113rman_manage_region(struct rman *rm, u_long start, u_long end)
114{
115 struct resource *r, *s;
116
117 r = malloc(sizeof *r, M_RMAN, M_NOWAIT);
118 if (r == 0)
119 return ENOMEM;
78static int int_rman_release_resource(struct rman *rm, struct resource *r);
79
80#define CIRCLEQ_TERMCOND(var, head) (var == (void *)&(head))
81
82int
83rman_init(struct rman *rm)
84{
85 static int once;

--- 28 unchanged lines hidden (view full) ---

114int
115rman_manage_region(struct rman *rm, u_long start, u_long end)
116{
117 struct resource *r, *s;
118
119 r = malloc(sizeof *r, M_RMAN, M_NOWAIT);
120 if (r == 0)
121 return ENOMEM;
122 bzero(r, sizeof *r);
120 r->r_sharehead = 0;
121 r->r_start = start;
122 r->r_end = end;
123 r->r_flags = 0;
124 r->r_dev = 0;
125 r->r_rm = rm;
126
127 simple_lock(rm->rm_slock);

--- 15 unchanged lines hidden (view full) ---

143int
144rman_fini(struct rman *rm)
145{
146 struct resource *r;
147
148 simple_lock(rm->rm_slock);
149 for (r = rm->rm_list.cqh_first; !CIRCLEQ_TERMCOND(r, rm->rm_list);
150 r = r->r_link.cqe_next) {
123 r->r_sharehead = 0;
124 r->r_start = start;
125 r->r_end = end;
126 r->r_flags = 0;
127 r->r_dev = 0;
128 r->r_rm = rm;
129
130 simple_lock(rm->rm_slock);

--- 15 unchanged lines hidden (view full) ---

146int
147rman_fini(struct rman *rm)
148{
149 struct resource *r;
150
151 simple_lock(rm->rm_slock);
152 for (r = rm->rm_list.cqh_first; !CIRCLEQ_TERMCOND(r, rm->rm_list);
153 r = r->r_link.cqe_next) {
151 if (r->r_flags & RF_ALLOCATED)
154 if (r->r_flags & RF_ALLOCATED) {
155 simple_unlock(rm->rm_slock);
152 return EBUSY;
156 return EBUSY;
157 }
153 }
154
155 /*
156 * There really should only be one of these if we are in this
157 * state and the code is working properly, but it can't hurt.
158 */
159 for (r = rm->rm_list.cqh_first; !CIRCLEQ_TERMCOND(r, rm->rm_list);
160 r = rm->rm_list.cqh_first) {

--- 88 unchanged lines hidden (view full) ---

249 * s->r_end > rstart + count - 1, then
250 * we need to split the region into three pieces
251 * (the middle one will get returned to the user).
252 * Otherwise, we are allocating at either the
253 * beginning or the end of s, so we only need to
254 * split it in two. The first case requires
255 * two new allocations; the second requires but one.
256 */
158 }
159
160 /*
161 * There really should only be one of these if we are in this
162 * state and the code is working properly, but it can't hurt.
163 */
164 for (r = rm->rm_list.cqh_first; !CIRCLEQ_TERMCOND(r, rm->rm_list);
165 r = rm->rm_list.cqh_first) {

--- 88 unchanged lines hidden (view full) ---

254 * s->r_end > rstart + count - 1, then
255 * we need to split the region into three pieces
256 * (the middle one will get returned to the user).
257 * Otherwise, we are allocating at either the
258 * beginning or the end of s, so we only need to
259 * split it in two. The first case requires
260 * two new allocations; the second requires but one.
261 */
257 rv = malloc(sizeof *r, M_RMAN, M_NOWAIT);
262 rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT);
258 if (rv == 0)
259 goto out;
263 if (rv == 0)
264 goto out;
265 bzero(rv, sizeof *rv);
260 rv->r_start = rstart;
261 rv->r_end = rstart + count - 1;
262 rv->r_flags = flags | RF_ALLOCATED;
263 rv->r_dev = dev;
264 rv->r_sharehead = 0;
266 rv->r_start = rstart;
267 rv->r_end = rstart + count - 1;
268 rv->r_flags = flags | RF_ALLOCATED;
269 rv->r_dev = dev;
270 rv->r_sharehead = 0;
271 rv->r_rm = rm;
265
266 if (s->r_start < rv->r_start && s->r_end > rv->r_end) {
267#ifdef RMAN_DEBUG
268 printf("splitting region in three parts: "
269 "[%#lx, %#lx]; [%#lx, %#lx]; [%#lx, %#lx]\n",
270 s->r_start, rv->r_start - 1,
271 rv->r_start, rv->r_end,
272 rv->r_end + 1, s->r_end);
273#endif /* RMAN_DEBUG */
274 /*
275 * We are allocating in the middle.
276 */
277 r = malloc(sizeof *r, M_RMAN, M_NOWAIT);
278 if (r == 0) {
279 free(rv, M_RMAN);
280 rv = 0;
281 goto out;
282 }
272
273 if (s->r_start < rv->r_start && s->r_end > rv->r_end) {
274#ifdef RMAN_DEBUG
275 printf("splitting region in three parts: "
276 "[%#lx, %#lx]; [%#lx, %#lx]; [%#lx, %#lx]\n",
277 s->r_start, rv->r_start - 1,
278 rv->r_start, rv->r_end,
279 rv->r_end + 1, s->r_end);
280#endif /* RMAN_DEBUG */
281 /*
282 * We are allocating in the middle.
283 */
284 r = malloc(sizeof *r, M_RMAN, M_NOWAIT);
285 if (r == 0) {
286 free(rv, M_RMAN);
287 rv = 0;
288 goto out;
289 }
290 bzero(r, sizeof *r);
283 r->r_start = rv->r_end + 1;
284 r->r_end = s->r_end;
285 r->r_flags = s->r_flags;
286 r->r_dev = 0;
287 r->r_sharehead = 0;
291 r->r_start = rv->r_end + 1;
292 r->r_end = s->r_end;
293 r->r_flags = s->r_flags;
294 r->r_dev = 0;
295 r->r_sharehead = 0;
296 r->r_rm = rm;
288 s->r_end = rv->r_start - 1;
289 CIRCLEQ_INSERT_AFTER(&rm->rm_list, s, rv,
290 r_link);
291 CIRCLEQ_INSERT_AFTER(&rm->rm_list, rv, r,
292 r_link);
293 } else if (s->r_start == rv->r_start) {
294#ifdef RMAN_DEBUG
295 printf("allocating from the beginning\n");

--- 41 unchanged lines hidden (view full) ---

337 continue;
338 rstart = max(s->r_start, start);
339 rend = min(s->r_end, max(start + count, end));
340 if (s->r_start >= start && s->r_end <= end
341 && (s->r_end - s->r_start + 1) == count) {
342 rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT);
343 if (rv == 0)
344 goto out;
297 s->r_end = rv->r_start - 1;
298 CIRCLEQ_INSERT_AFTER(&rm->rm_list, s, rv,
299 r_link);
300 CIRCLEQ_INSERT_AFTER(&rm->rm_list, rv, r,
301 r_link);
302 } else if (s->r_start == rv->r_start) {
303#ifdef RMAN_DEBUG
304 printf("allocating from the beginning\n");

--- 41 unchanged lines hidden (view full) ---

346 continue;
347 rstart = max(s->r_start, start);
348 rend = min(s->r_end, max(start + count, end));
349 if (s->r_start >= start && s->r_end <= end
350 && (s->r_end - s->r_start + 1) == count) {
351 rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT);
352 if (rv == 0)
353 goto out;
354 bzero(rv, sizeof *rv);
345 rv->r_start = s->r_start;
346 rv->r_end = s->r_end;
347 rv->r_flags = s->r_flags &
348 (RF_ALLOCATED | RF_SHAREABLE | RF_TIMESHARE);
349 rv->r_dev = dev;
350 rv->r_rm = rm;
351 if (s->r_sharehead == 0) {
352 s->r_sharehead = malloc(sizeof *s->r_sharehead,
353 M_RMAN, M_NOWAIT);
354 if (s->r_sharehead == 0) {
355 free(rv, M_RMAN);
356 rv = 0;
357 goto out;
358 }
355 rv->r_start = s->r_start;
356 rv->r_end = s->r_end;
357 rv->r_flags = s->r_flags &
358 (RF_ALLOCATED | RF_SHAREABLE | RF_TIMESHARE);
359 rv->r_dev = dev;
360 rv->r_rm = rm;
361 if (s->r_sharehead == 0) {
362 s->r_sharehead = malloc(sizeof *s->r_sharehead,
363 M_RMAN, M_NOWAIT);
364 if (s->r_sharehead == 0) {
365 free(rv, M_RMAN);
366 rv = 0;
367 goto out;
368 }
369 bzero(s->r_sharehead, sizeof *s->r_sharehead);
359 LIST_INIT(s->r_sharehead);
360 LIST_INSERT_HEAD(s->r_sharehead, s,
361 r_sharelink);
362 s->r_flags |= RF_FIRSTSHARE;
363 }
364 rv->r_sharehead = s->r_sharehead;
365 LIST_INSERT_HEAD(s->r_sharehead, rv, r_sharelink);
366 goto out;

--- 79 unchanged lines hidden (view full) ---

446 struct resource *whohas;
447 struct rman *rm;
448
449 rm = r->r_rm;
450 for (;;) {
451 simple_lock(rm->rm_slock);
452 rv = int_rman_activate_resource(rm, r, &whohas);
453 if (rv != EBUSY)
370 LIST_INIT(s->r_sharehead);
371 LIST_INSERT_HEAD(s->r_sharehead, s,
372 r_sharelink);
373 s->r_flags |= RF_FIRSTSHARE;
374 }
375 rv->r_sharehead = s->r_sharehead;
376 LIST_INSERT_HEAD(s->r_sharehead, rv, r_sharelink);
377 goto out;

--- 79 unchanged lines hidden (view full) ---

457 struct resource *whohas;
458 struct rman *rm;
459
460 rm = r->r_rm;
461 for (;;) {
462 simple_lock(rm->rm_slock);
463 rv = int_rman_activate_resource(rm, r, &whohas);
464 if (rv != EBUSY)
454 return (rv);
465 return (rv); /* returns with simplelock */
455
456 if (r->r_sharehead == 0)
457 panic("rman_await_resource");
458 /*
459 * splhigh hopefully will prevent a race between
460 * simple_unlock and tsleep where a process
461 * could conceivably get in and release the resource
462 * before we have a chance to sleep on it.

--- 6 unchanged lines hidden (view full) ---

469 splx(s);
470 return rv;
471 }
472 simple_lock(rm->rm_slock);
473 splx(s);
474 }
475}
476
466
467 if (r->r_sharehead == 0)
468 panic("rman_await_resource");
469 /*
470 * splhigh hopefully will prevent a race between
471 * simple_unlock and tsleep where a process
472 * could conceivably get in and release the resource
473 * before we have a chance to sleep on it.

--- 6 unchanged lines hidden (view full) ---

480 splx(s);
481 return rv;
482 }
483 simple_lock(rm->rm_slock);
484 splx(s);
485 }
486}
487
477int
478rman_deactivate_resource(struct resource *r)
488static int
489int_rman_deactivate_resource(struct resource *r)
479{
480 struct rman *rm;
481
482 rm = r->r_rm;
490{
491 struct rman *rm;
492
493 rm = r->r_rm;
483 simple_lock(rm->rm_slock);
484 r->r_flags &= ~RF_ACTIVE;
485 if (r->r_flags & RF_WANTED) {
486 r->r_flags &= ~RF_WANTED;
487 wakeup(r->r_sharehead);
488 }
494 r->r_flags &= ~RF_ACTIVE;
495 if (r->r_flags & RF_WANTED) {
496 r->r_flags &= ~RF_WANTED;
497 wakeup(r->r_sharehead);
498 }
499 return 0;
500}
501
502int
503rman_deactivate_resource(struct resource *r)
504{
505 struct rman *rm;
506
507 rm = r->r_rm;
508 simple_lock(rm->rm_slock);
509 int_rman_deactivate_resource(r);
489 simple_unlock(rm->rm_slock);
490 return 0;
491}
492
493static int
494int_rman_release_resource(struct rman *rm, struct resource *r)
495{
496 struct resource *s, *t;
497
498 if (r->r_flags & RF_ACTIVE)
510 simple_unlock(rm->rm_slock);
511 return 0;
512}
513
514static int
515int_rman_release_resource(struct rman *rm, struct resource *r)
516{
517 struct resource *s, *t;
518
519 if (r->r_flags & RF_ACTIVE)
499 return EBUSY;
520 int_rman_deactivate_resource(r);
500
501 /*
502 * Check for a sharing list first. If there is one, then we don't
503 * have to think as hard.
504 */
505 if (r->r_sharehead) {
506 /*
507 * If a sharing list exists, then we know there are at

--- 84 unchanged lines hidden ---
521
522 /*
523 * Check for a sharing list first. If there is one, then we don't
524 * have to think as hard.
525 */
526 if (r->r_sharehead) {
527 /*
528 * If a sharing list exists, then we know there are at

--- 84 unchanged lines hidden ---