From beea48b2544978c2f42fbdecef0ae77429a3e719 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Thu, 27 Feb 2003 14:46:51 +0000 Subject: [PATCH] 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. --- sys/kern/kern_conf.c | 17 +++++++++++++++-- sys/sys/conf.h | 2 ++ sys/sys/linedisc.h | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index dbc77941d97b..d1b4d8635640 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", diff --git a/sys/sys/conf.h b/sys/sys/conf.h index a6466ea4ad67..9183dcc1b8f7 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -278,6 +278,8 @@ dumper_t nodump; #define NUMCDEVSW 256 +#define MAJOR_AUTO -1 /* XXX: Not GM */ + /* * nopsize is little used, so not worth having dummy functions for. */ diff --git a/sys/sys/linedisc.h b/sys/sys/linedisc.h index a6466ea4ad67..9183dcc1b8f7 100644 --- a/sys/sys/linedisc.h +++ b/sys/sys/linedisc.h @@ -278,6 +278,8 @@ dumper_t nodump; #define NUMCDEVSW 256 +#define MAJOR_AUTO -1 /* XXX: Not GM */ + /* * nopsize is little used, so not worth having dummy functions for. */