diff options
author | phk <phk@FreeBSD.org> | 2003-02-27 14:46:51 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-02-27 14:46:51 +0000 |
commit | 9011e44e2d7cb002bfbb4230fc0ae63c1eaaddac (patch) | |
tree | 664267e606a2c7d393bf73dab0235b17a41d96bc /sys/kern/kern_conf.c | |
parent | 5b9d37f7e4c990a3fd7e51be8c8bd4c24eecc975 (diff) | |
download | FreeBSD-src-9011e44e2d7cb002bfbb4230fc0ae63c1eaaddac.zip FreeBSD-src-9011e44e2d7cb002bfbb4230fc0ae63c1eaaddac.tar.gz |
Add support for allocating a device driver major number on demand.
To do this, initialize the d_maj member of the cdevsw to MAJOR_AUTO.
When the cdevsw is first passed to make_dev() a free major number
will be assigned.
Until we have a bit more experience with this a printf will announce
this fact.
Major numbers are not reclaimed, so loading/unloading the same
device driver which uses MAJOR_AUTO will eventually deplete the
pool of free major numbers and the system will panic when it can
not allocate one. Still undecided who to invonvenience with the
solution to this.
Diffstat (limited to 'sys/kern/kern_conf.c')
-rw-r--r-- | sys/kern/kern_conf.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index dbc7794..d1b4d86 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -43,6 +43,9 @@ static MALLOC_DEFINE(M_DEVT, "dev_t", "dev_t storage"); +/* Built at compile time from sys/conf/majors */ +extern unsigned char reserved_majors[256]; + /* * This is the number of hash-buckets. Experiements with 'real-life' * udev_t's show that a prime halfway between two powers of two works @@ -281,8 +284,18 @@ make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, const va_list ap; int i; - KASSERT(umajor(makeudev(devsw->d_maj, minor)) == devsw->d_maj, - ("Invalid minor (%d) in make_dev", minor)); + KASSERT((minor & ~0xffff00ff) == 0, + ("Invalid minor (0x%x) in make_dev", minor)); + + if (devsw->d_maj == MAJOR_AUTO) { + for (i = NUMCDEVSW - 1; i > 0; i--) + if (reserved_majors[i] != i) + break; + KASSERT(i > 0, ("Out of major numbers (%s)", devsw->d_name)); + printf("Allocating major#%d to \"%s\"\n", i, devsw->d_name); + devsw->d_maj = i; + reserved_majors[i] = i; + } if (!ready_for_devs) { printf("WARNING: Driver mistake: make_dev(%s) called before SI_SUB_DRIVERS\n", |