summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_conf.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-02-27 14:46:51 +0000
committerphk <phk@FreeBSD.org>2003-02-27 14:46:51 +0000
commit9011e44e2d7cb002bfbb4230fc0ae63c1eaaddac (patch)
tree664267e606a2c7d393bf73dab0235b17a41d96bc /sys/kern/kern_conf.c
parent5b9d37f7e4c990a3fd7e51be8c8bd4c24eecc975 (diff)
downloadFreeBSD-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.c17
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",
OpenPOWER on IntegriCloud