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