kern_conf.c revision 48510
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 *
3348510Sphk * $Id: kern_conf.c,v 1.45 1999/06/26 11:39:27 dfr 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
4247640Sphk#define cdevsw_ALLOCSTART	(NUMCDEVSW/2)
4312954Sjulian
4447640Sphkstruct cdevsw 	*cdevsw[NUMCDEVSW];
4512954Sjulian
4647640Sphkint	bmaj2cmaj[NUMCDEVSW];
4746635Sphk
4811126Sjulian/*
4912954Sjulian * Routine to convert from character to block device number.
5012954Sjulian *
5112954Sjulian * A minimal stub routine can always return NODEV.
5212954Sjulian */
5312954Sjuliandev_t
5412954Sjulianchrtoblk(dev_t dev)
5512954Sjulian{
5612954Sjulian	struct cdevsw *cd;
5712954Sjulian
5846676Sphk	if((cd = devsw(dev)) != NULL) {
5937389Sjulian          if (cd->d_bmaj != -1)
6037389Sjulian	    return(makedev(cd->d_bmaj,minor(dev)));
6112954Sjulian	}
6212954Sjulian	return(NODEV);
6312954Sjulian}
6412954Sjulian
6547640Sphkstruct cdevsw *
6647640Sphkdevsw(dev_t dev)
6747640Sphk{
6847640Sphk        return(cdevsw[major(dev)]);
6947640Sphk}
7047640Sphk
7147640Sphkstruct cdevsw *
7247640Sphkbdevsw(dev_t dev)
7347640Sphk{
7447640Sphk        struct cdevsw *c;
7547640Sphk        int i = major(dev);
7647640Sphk
7747640Sphk        if (bmaj2cmaj[i] == 254)
7847640Sphk                return 0;
7947640Sphk
8047640Sphk        c = cdevsw[bmaj2cmaj[major(dev)]];
8147640Sphk        if (!c) {
8247640Sphk                printf("bogus bdev dev_t %p, no cdev\n", (void *)dev);
8347640Sphk                Debugger("Bummer");
8447640Sphk                return 0;
8547640Sphk        }
8647640Sphk        /* CMAJ zero is the console, which has no strategy so this works */
8747640Sphk        if (c->d_strategy)
8847640Sphk                return (c);
8947640Sphk        return (0);
9047640Sphk}
9147640Sphk
9247640Sphk/*
9347640Sphk *  Add a cdevsw entry
9447640Sphk */
9547640Sphk
9637389Sjulianint
9747640Sphkcdevsw_add(struct cdevsw *newentry)
9817264Sphk{
9947028Sphk	int i;
10047028Sphk	static int setup;
10117264Sphk
10247028Sphk	if (!setup) {
10347640Sphk		for (i = 0; i < NUMCDEVSW; i++)
10447028Sphk			if (!bmaj2cmaj[i])
10547028Sphk				bmaj2cmaj[i] = 254;
10647028Sphk		setup++;
10747028Sphk	}
10847028Sphk
10947640Sphk	if (newentry->d_maj < 0 || newentry->d_maj >= NUMCDEVSW) {
11047640Sphk		printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n",
11147640Sphk		    newentry->d_name, newentry->d_maj);
11247640Sphk		return EINVAL;
11337389Sjulian	}
11417264Sphk
11548510Sphk	if (cdevsw[newentry->d_maj]) {
11648510Sphk		printf("WARNING: \"%s\" is usurping \"%s\"'s cdevsw[]\n",
11748510Sphk		    newentry->d_name, cdevsw[newentry->d_maj]->d_name);
11848510Sphk	}
11947640Sphk	cdevsw[newentry->d_maj] = newentry;
12037389Sjulian
12148510Sphk	if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) {
12248510Sphk		if (bmaj2cmaj[newentry->d_bmaj] != 254) {
12348510Sphk			printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n",
12448510Sphk			    newentry->d_name,
12548510Sphk			    cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name);
12648510Sphk		}
12747640Sphk		bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj;
12848510Sphk	}
12947640Sphk
13037389Sjulian	return 0;
13137389Sjulian}
13237389Sjulian
13348211Sgrog/*
13448211Sgrog *  Remove a cdevsw entry
13548211Sgrog */
13648211Sgrog
13736735Sdfrint
13848211Sgrogcdevsw_remove(struct cdevsw *oldentry)
13948211Sgrog{
14048211Sgrog	if (oldentry->d_maj < 0 || oldentry->d_maj >= NUMCDEVSW) {
14148211Sgrog		printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n",
14248211Sgrog		    oldentry->d_name, oldentry->d_maj);
14348211Sgrog		return EINVAL;
14448211Sgrog	}
14548211Sgrog
14648211Sgrog	cdevsw[oldentry->d_maj] = NULL;
14748211Sgrog
14848211Sgrog	if (oldentry->d_bmaj >= 0 && oldentry->d_bmaj < NUMCDEVSW)
14948211Sgrog		bmaj2cmaj[oldentry->d_bmaj] = NULL;
15048211Sgrog
15148211Sgrog	return 0;
15248211Sgrog}
15348211Sgrog
15448211Sgrogint
15546635Sphkdevsw_module_handler(module_t mod, int what, void* arg)
15636735Sdfr{
15746635Sphk	struct devsw_module_data* data = (struct devsw_module_data*) arg;
15848240Sdfr	int error = 0;
15936735Sdfr
16046792Sphk	if (data->cmaj == NOMAJ)
16146792Sphk		data->cdev = NODEV;
16246792Sphk	else
16346792Sphk		data->cdev = makedev(data->cmaj, 0);
16436735Sdfr	switch (what) {
16536735Sdfr	case MOD_LOAD:
16647640Sphk		error = cdevsw_add(data->cdevsw);
16746635Sphk		if (!error && data->cdevsw->d_strategy != nostrategy) {
16846792Sphk			if (data->bmaj == NOMAJ) {
16946635Sphk				data->bdev = data->cdev;
17046792Sphk				data->bmaj = data->cmaj;
17146792Sphk			} else {
17246792Sphk				data->bdev = makedev(data->bmaj, 0);
17346792Sphk			}
17446792Sphk			data->cdevsw->d_maj = data->bmaj;
17546635Sphk			bmaj2cmaj[major(data->bdev)] = major(data->cdev);
17644975Sdfr		}
17744975Sdfr		if (!error && data->chainevh)
17844975Sdfr			error = data->chainevh(mod, what, data->chainarg);
17944975Sdfr		return error;
18036735Sdfr
18136735Sdfr	case MOD_UNLOAD:
18244975Sdfr		if (data->chainevh) {
18344975Sdfr			error = data->chainevh(mod, what, data->chainarg);
18444975Sdfr			if (error)
18544975Sdfr				return error;
18644975Sdfr		}
18748240Sdfr		cdevsw_remove(data->cdevsw);
18844975Sdfr		return error;
18936735Sdfr	}
19036735Sdfr
19136735Sdfr	if (data->chainevh)
19236735Sdfr		return data->chainevh(mod, what, data->chainarg);
19336735Sdfr	else
19436735Sdfr		return 0;
19536735Sdfr}
19647028Sphk
19747028Sphk/*
19847028Sphk * dev_t and u_dev_t primitives
19947028Sphk */
20047028Sphk
20147028Sphk#define DEVT_FASCIST 1
20247028Sphk
20347028Sphkint
20447028Sphkmajor(dev_t x)
20547028Sphk{
20647069Sphk	uintptr_t i = (uintptr_t)x;
20747066Sphk
20847028Sphk#ifdef DEVT_FASCIST
20947300Sluoqi	return(255 - ((i >> 8) & 0xff));
21047028Sphk#else
21147066Sphk	return((i >> 8) & 0xff);
21247028Sphk#endif
21347028Sphk}
21447028Sphk
21547028Sphkint
21647028Sphkminor(dev_t x)
21747028Sphk{
21847069Sphk	uintptr_t i = (uintptr_t)x;
21947066Sphk
22047066Sphk	return(i & 0xffff00ff);
22147028Sphk}
22247028Sphk
22347028Sphkdev_t
22447680Sphkmakebdev(int x, int y)
22547680Sphk{
22647680Sphk	return (makedev(x, y));
22747680Sphk}
22847680Sphk
22947680Sphkdev_t
23047028Sphkmakedev(int x, int y)
23147028Sphk{
23247028Sphk#ifdef DEVT_FASCIST
23348240Sdfr        return ((dev_t)(uintptr_t) (((255 - x) << 8) | y));
23447028Sphk#else
23548240Sdfr        return ((dev_t)(uintptr_t) ((x << 8) | y));
23647028Sphk#endif
23747028Sphk}
23847028Sphk
23947028Sphkudev_t
24047028Sphkdev2udev(dev_t x)
24147028Sphk{
24247028Sphk	return umakedev(major(x), minor(x));
24347028Sphk}
24447028Sphk
24547028Sphkdev_t
24647028Sphkudev2dev(udev_t x, int b)
24747028Sphk{
24847028Sphk	return makedev(umajor(x), uminor(x));
24947028Sphk}
25047028Sphk
25147028Sphkint
25247028Sphkuminor(udev_t dev)
25347028Sphk{
25447028Sphk	return(dev & 0xffff00ff);
25547028Sphk}
25647028Sphk
25747028Sphkint
25847028Sphkumajor(udev_t dev)
25947028Sphk{
26047028Sphk	return((dev & 0xff00) >> 8);
26147028Sphk}
26247028Sphk
26347028Sphkudev_t
26447028Sphkumakedev(int x, int y)
26547028Sphk{
26647028Sphk        return ((x << 8) | y);
26747028Sphk}
26847028Sphk
269