kern_conf.c revision 46676
111126Sjulian/*-
211126Sjulian * Parts Copyright (c) 1995 Terrence R. Lambert
311126Sjulian * Copyright (c) 1995 Julian R. Elischer
411126Sjulian * All rights reserved.
511126Sjulian *
611126Sjulian * Redistribution and use in source and binary forms, with or without
711126Sjulian * modification, are permitted provided that the following conditions
811126Sjulian * are met:
911126Sjulian * 1. Redistributions of source code must retain the above copyright
1011126Sjulian *    notice, this list of conditions and the following disclaimer.
1111126Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1211126Sjulian *    notice, this list of conditions and the following disclaimer in the
1311126Sjulian *    documentation and/or other materials provided with the distribution.
1411126Sjulian * 3. All advertising materials mentioning features or use of this software
1511126Sjulian *    must display the following acknowledgement:
1611126Sjulian *      This product includes software developed by Terrence R. Lambert.
1711126Sjulian * 4. The name Terrence R. Lambert may not be used to endorse or promote
1811126Sjulian *    products derived from this software without specific prior written
1911126Sjulian *    permission.
2011126Sjulian *
2111126Sjulian * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY
2211126Sjulian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311126Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411126Sjulian * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
2511126Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2611126Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2711126Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2811126Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2911126Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3011126Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3111126Sjulian * SUCH DAMAGE.
3211126Sjulian *
3346676Sphk * $Id: kern_conf.c,v 1.32 1999/05/07 10:10:50 phk Exp $
3411126Sjulian */
3511126Sjulian
3611126Sjulian#include <sys/param.h>
3711127Sjulian#include <sys/systm.h>
3836735Sdfr#include <sys/module.h>
3911126Sjulian#include <sys/conf.h>
4012954Sjulian#include <sys/vnode.h>
4111126Sjulian
4217675Sjulian#define NUMCDEV 256
4317675Sjulian#define cdevsw_ALLOCSTART	(NUMCDEV/2)
4412954Sjulian
4512954Sjulianstruct cdevsw 	*cdevsw[NUMCDEV];
4612954Sjulianint	nchrdev = NUMCDEV;
4712954Sjulian
4846635Sphkint	bmaj2cmaj[NUMCDEV];
4946635Sphkint	nblkdev = NUMCDEV;
5046635Sphk
5111126Sjulian/*
5212954Sjulian * Routine to convert from character to block device number.
5312954Sjulian *
5412954Sjulian * A minimal stub routine can always return NODEV.
5512954Sjulian */
5612954Sjuliandev_t
5712954Sjulianchrtoblk(dev_t dev)
5812954Sjulian{
5912954Sjulian	struct cdevsw *cd;
6012954Sjulian
6146676Sphk	if((cd = devsw(dev)) != NULL) {
6237389Sjulian          if (cd->d_bmaj != -1)
6337389Sjulian	    return(makedev(cd->d_bmaj,minor(dev)));
6412954Sjulian	}
6512954Sjulian	return(NODEV);
6612954Sjulian}
6712954Sjulian
6837389Sjulianint
6937389Sjuliancdevsw_add(dev_t *descrip,
7037389Sjulian		struct cdevsw *newentry,
7137389Sjulian		struct cdevsw **oldentry)
7217264Sphk{
7337389Sjulian	int i ;
7417264Sphk
7537389Sjulian	if ( (int)*descrip == NODEV) {	/* auto (0 is valid) */
7637389Sjulian		/*
7737389Sjulian		 * Search the table looking for a slot...
7837389Sjulian		 */
7937389Sjulian		for (i = cdevsw_ALLOCSTART; i < nchrdev; i++)
8037389Sjulian			if (cdevsw[i] == NULL)
8137389Sjulian				break;		/* found one! */
8237389Sjulian		/* out of allocable slots? */
8337389Sjulian		if (i >= nchrdev) {
8437389Sjulian			return ENFILE;
8537389Sjulian		}
8637389Sjulian	} else {				/* assign */
8737389Sjulian		i = major(*descrip);
8837389Sjulian		if (i < 0 || i >= nchrdev) {
8937389Sjulian			return EINVAL;
9037389Sjulian		}
9137389Sjulian	}
9217264Sphk
9337389Sjulian	/* maybe save old */
9437389Sjulian        if (oldentry) {
9537389Sjulian		*oldentry = cdevsw[i];
9637389Sjulian	}
9737389Sjulian	if (newentry) {
9837389Sjulian		newentry->d_bmaj = -1;
9937389Sjulian		newentry->d_maj = i;
10037389Sjulian	}
10137389Sjulian	/* replace with new */
10237389Sjulian	cdevsw[i] = newentry;
10337389Sjulian
10437389Sjulian	/* done!  let them know where we put it */
10537389Sjulian	*descrip = makedev(i,0);
10637389Sjulian	return 0;
10737389Sjulian}
10837389Sjulian
10937389Sjulian/*
11037389Sjulian * note must call cdevsw_add before bdevsw_add due to d_bmaj hack.
11137389Sjulian */
11217264Sphkvoid
11346635Sphkcdevsw_add_generic(int bmaj, int cmaj, struct cdevsw *cdevsw)
11417264Sphk{
11517264Sphk	dev_t dev;
11637172Sphk
11746635Sphk	dev = makedev(cmaj, 0);
11837389Sjulian	cdevsw_add(&dev, cdevsw, NULL);
11946635Sphk	bmaj2cmaj[bmaj] = cmaj;
12017264Sphk}
12136735Sdfr
12236735Sdfrint
12346635Sphkdevsw_module_handler(module_t mod, int what, void* arg)
12436735Sdfr{
12546635Sphk	struct devsw_module_data* data = (struct devsw_module_data*) arg;
12636735Sdfr	int error;
12736735Sdfr
12836735Sdfr	switch (what) {
12936735Sdfr	case MOD_LOAD:
13046635Sphk		error = cdevsw_add(&data->cdev, data->cdevsw, NULL);
13146635Sphk		if (!error && data->cdevsw->d_strategy != nostrategy) {
13246635Sphk			if (data->bdev == NODEV)
13346635Sphk				data->bdev = data->cdev;
13446635Sphk			bmaj2cmaj[major(data->bdev)] = major(data->cdev);
13544975Sdfr		}
13644975Sdfr		if (!error && data->chainevh)
13744975Sdfr			error = data->chainevh(mod, what, data->chainarg);
13844975Sdfr		return error;
13936735Sdfr
14036735Sdfr	case MOD_UNLOAD:
14144975Sdfr		if (data->chainevh) {
14244975Sdfr			error = data->chainevh(mod, what, data->chainarg);
14344975Sdfr			if (error)
14444975Sdfr				return error;
14544975Sdfr		}
14646635Sphk		if (data->cdevsw->d_strategy != nostrategy)
14746635Sphk			bmaj2cmaj[major(data->bdev)] = 0;
14846635Sphk		error = cdevsw_add(&data->cdev, NULL, NULL);
14944975Sdfr		return error;
15036735Sdfr	}
15136735Sdfr
15236735Sdfr	if (data->chainevh)
15336735Sdfr		return data->chainevh(mod, what, data->chainarg);
15436735Sdfr	else
15536735Sdfr		return 0;
15636735Sdfr}
157