kern_conf.c revision 46676
139213Sgibbs/*-
239213Sgibbs * Parts Copyright (c) 1995 Terrence R. Lambert
339213Sgibbs * Copyright (c) 1995 Julian R. Elischer
439213Sgibbs * All rights reserved.
539213Sgibbs *
639213Sgibbs * Redistribution and use in source and binary forms, with or without
739213Sgibbs * modification, are permitted provided that the following conditions
839213Sgibbs * are met:
939213Sgibbs * 1. Redistributions of source code must retain the above copyright
1039213Sgibbs *    notice, this list of conditions and the following disclaimer.
1139213Sgibbs * 2. Redistributions in binary form must reproduce the above copyright
1239213Sgibbs *    notice, this list of conditions and the following disclaimer in the
1339213Sgibbs *    documentation and/or other materials provided with the distribution.
1439213Sgibbs * 3. All advertising materials mentioning features or use of this software
1539213Sgibbs *    must display the following acknowledgement:
1639213Sgibbs *      This product includes software developed by Terrence R. Lambert.
1739213Sgibbs * 4. The name Terrence R. Lambert may not be used to endorse or promote
1839213Sgibbs *    products derived from this software without specific prior written
1939213Sgibbs *    permission.
2039213Sgibbs *
2139213Sgibbs * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY
2239213Sgibbs * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2339213Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2439213Sgibbs * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
2539213Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2639213Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2739213Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2850477Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2939213Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3039213Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3139213Sgibbs * SUCH DAMAGE.
3239213Sgibbs *
3339213Sgibbs * $Id: kern_conf.c,v 1.32 1999/05/07 10:10:50 phk Exp $
3439213Sgibbs */
3539213Sgibbs
3660041Sphk#include <sys/param.h>
3739213Sgibbs#include <sys/systm.h>
3839213Sgibbs#include <sys/module.h>
3939213Sgibbs#include <sys/conf.h>
4050073Sken#include <sys/vnode.h>
4139213Sgibbs
4239213Sgibbs#define NUMCDEV 256
4339213Sgibbs#define cdevsw_ALLOCSTART	(NUMCDEV/2)
4439213Sgibbs
4539213Sgibbsstruct cdevsw 	*cdevsw[NUMCDEV];
4639213Sgibbsint	nchrdev = NUMCDEV;
4739213Sgibbs
4839213Sgibbsint	bmaj2cmaj[NUMCDEV];
4939213Sgibbsint	nblkdev = NUMCDEV;
5039213Sgibbs
5139213Sgibbs/*
5250073Sken * Routine to convert from character to block device number.
5350073Sken *
5439213Sgibbs * A minimal stub routine can always return NODEV.
5539213Sgibbs */
5639213Sgibbsdev_t
5739213Sgibbschrtoblk(dev_t dev)
5839213Sgibbs{
5939213Sgibbs	struct cdevsw *cd;
6039213Sgibbs
6139213Sgibbs	if((cd = devsw(dev)) != NULL) {
6239213Sgibbs          if (cd->d_bmaj != -1)
6339213Sgibbs	    return(makedev(cd->d_bmaj,minor(dev)));
6439213Sgibbs	}
6539213Sgibbs	return(NODEV);
6639213Sgibbs}
6739213Sgibbs
6839213Sgibbsint
6939213Sgibbscdevsw_add(dev_t *descrip,
7039213Sgibbs		struct cdevsw *newentry,
7139213Sgibbs		struct cdevsw **oldentry)
7239213Sgibbs{
7339213Sgibbs	int i ;
7439213Sgibbs
7539213Sgibbs	if ( (int)*descrip == NODEV) {	/* auto (0 is valid) */
7639213Sgibbs		/*
7739213Sgibbs		 * Search the table looking for a slot...
7859249Sphk		 */
79112006Sphk		for (i = cdevsw_ALLOCSTART; i < nchrdev; i++)
8060938Sjake			if (cdevsw[i] == NULL)
8139213Sgibbs				break;		/* found one! */
8239213Sgibbs		/* out of allocable slots? */
8339213Sgibbs		if (i >= nchrdev) {
8450073Sken			return ENFILE;
8553257Sken		}
8639213Sgibbs	} else {				/* assign */
8739213Sgibbs		i = major(*descrip);
8839213Sgibbs		if (i < 0 || i >= nchrdev) {
8939213Sgibbs			return EINVAL;
9039213Sgibbs		}
9139213Sgibbs	}
9239213Sgibbs
9339213Sgibbs	/* maybe save old */
9439213Sgibbs        if (oldentry) {
9540603Sken		*oldentry = cdevsw[i];
9639213Sgibbs	}
9739213Sgibbs	if (newentry) {
9839213Sgibbs		newentry->d_bmaj = -1;
9939213Sgibbs		newentry->d_maj = i;
10050073Sken	}
10139213Sgibbs	/* replace with new */
10239213Sgibbs	cdevsw[i] = newentry;
10339213Sgibbs
10439213Sgibbs	/* done!  let them know where we put it */
10539213Sgibbs	*descrip = makedev(i,0);
10639213Sgibbs	return 0;
10739213Sgibbs}
10839213Sgibbs
10939213Sgibbs/*
11039213Sgibbs * note must call cdevsw_add before bdevsw_add due to d_bmaj hack.
11139213Sgibbs */
11239213Sgibbsvoid
11339213Sgibbscdevsw_add_generic(int bmaj, int cmaj, struct cdevsw *cdevsw)
11439213Sgibbs{
11539213Sgibbs	dev_t dev;
11672119Speter
11739213Sgibbs	dev = makedev(cmaj, 0);
11839213Sgibbs	cdevsw_add(&dev, cdevsw, NULL);
11939213Sgibbs	bmaj2cmaj[bmaj] = cmaj;
12047625Sphk}
121111815Sphk
122111815Sphkint
123111815Sphkdevsw_module_handler(module_t mod, int what, void* arg)
124111815Sphk{
125111815Sphk	struct devsw_module_data* data = (struct devsw_module_data*) arg;
126111815Sphk	int error;
127111815Sphk
128111815Sphk	switch (what) {
12939213Sgibbs	case MOD_LOAD:
13039213Sgibbs		error = cdevsw_add(&data->cdev, data->cdevsw, NULL);
13150073Sken		if (!error && data->cdevsw->d_strategy != nostrategy) {
13250073Sken			if (data->bdev == NODEV)
13350073Sken				data->bdev = data->cdev;
13450073Sken			bmaj2cmaj[major(data->bdev)] = major(data->cdev);
13539213Sgibbs		}
13683366Sjulian		if (!error && data->chainevh)
13739213Sgibbs			error = data->chainevh(mod, what, data->chainarg);
13839213Sgibbs		return error;
13939213Sgibbs
14039213Sgibbs	case MOD_UNLOAD:
14139213Sgibbs		if (data->chainevh) {
14240603Sken			error = data->chainevh(mod, what, data->chainarg);
14339213Sgibbs			if (error)
14439213Sgibbs				return error;
145101940Snjl		}
14639213Sgibbs		if (data->cdevsw->d_strategy != nostrategy)
14739213Sgibbs			bmaj2cmaj[major(data->bdev)] = 0;
14839213Sgibbs		error = cdevsw_add(&data->cdev, NULL, NULL);
14939213Sgibbs		return error;
15039213Sgibbs	}
15140603Sken
15240603Sken	if (data->chainevh)
15340603Sken		return data->chainevh(mod, what, data->chainarg);
15440603Sken	else
15540603Sken		return 0;
15640603Sken}
15739213Sgibbs