kern_conf.c revision 48864
181084Sjake/*- 281084Sjake * Parts Copyright (c) 1995 Terrence R. Lambert 381084Sjake * Copyright (c) 1995 Julian R. Elischer 481084Sjake * All rights reserved. 581084Sjake * 681084Sjake * Redistribution and use in source and binary forms, with or without 781084Sjake * modification, are permitted provided that the following conditions 881084Sjake * are met: 981084Sjake * 1. Redistributions of source code must retain the above copyright 10147272Smarius * notice, this list of conditions and the following disclaimer. 11147272Smarius * 2. Redistributions in binary form must reproduce the above copyright 12147272Smarius * notice, this list of conditions and the following disclaimer in the 13147272Smarius * documentation and/or other materials provided with the distribution. 14147272Smarius * 3. All advertising materials mentioning features or use of this software 15163890Smarius * must display the following acknowledgement: 16163890Smarius * This product includes software developed by Terrence R. Lambert. 17163890Smarius * 4. The name Terrence R. Lambert may not be used to endorse or promote 18163890Smarius * products derived from this software without specific prior written 19163890Smarius * permission. 20146419Smarius * 21146419Smarius * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY 22146419Smarius * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23146419Smarius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24146419Smarius * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE 25207154Smarius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26171167Sgnn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27147272Smarius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28147272Smarius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29147272Smarius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30147272Smarius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31147272Smarius * SUCH DAMAGE. 32147272Smarius * 33147272Smarius * $Id: kern_conf.c,v 1.48 1999/07/17 18:43:45 phk Exp $ 34152862Sru */ 35130294Sscottl 36119382Sjake#include <sys/param.h> 37119382Sjake#include <sys/systm.h> 38170840Smarius#include <sys/module.h> 39146483Smarius#include <sys/conf.h> 40147191Sjkoshy#include <sys/vnode.h> 41203679Sbrucec 42166144Smarius#define cdevsw_ALLOCSTART (NUMCDEVSW/2) 43155151Smarius 44166144Smariusstruct cdevsw *cdevsw[NUMCDEVSW]; 45133589Smarius 46152683Smariusint bmaj2cmaj[NUMCDEVSW]; 47207154Smarius 48207154Smarius/* 49186347Snwhitehorn * Routine to convert from character to block device number. 5086148Stmm * 51105399Stmm * A minimal stub routine can always return NODEV. 52116584Sjake */ 53152686Smariusdev_t 54151805Sjoergchrtoblk(dev_t dev) 55152862Sru{ 56152862Sru struct cdevsw *cd; 57119382Sjake 58186681Sed if((cd = devsw(dev)) != NULL) { 59119382Sjake if (cd->d_bmaj != -1) 60119816Smarcel return(makebdev(cd->d_bmaj,minor(dev))); 61122470Sjake } 62210601Smav return(NODEV); 6393122Stmm} 64124516Sdes 65124481Sdesstruct cdevsw * 66124481Sdesdevsw(dev_t dev) 67124481Sdes{ 68189170Sed return(cdevsw[major(dev)]); 69111072Sjake} 70100399Speter 71202006Smariusstruct cdevsw * 72182057Smariusbdevsw(dev_t dev) 73111072Sjake{ 7486235Stmm struct cdevsw *c; 75136944Syongari int i = major(dev); 76152862Sru 77128758Smarius if (bmaj2cmaj[i] == 256) 78202010Smarius return 0; 79129051Smarius 80129051Smarius c = cdevsw[bmaj2cmaj[major(dev)]]; 81129051Smarius if (!c) { 82220038Smarius printf("bogus bdev dev_t %p, no cdev\n", (void *)dev); 8386235Stmm Debugger("Bummer"); 84207154Smarius return 0; 85183423Smarius } 86146392Smarius /* CMAJ zero is the console, which has no strategy so this works */ 8790623Stmm if (c->d_strategy) 88146392Smarius return (c); 89208349Smarius return (0); 9081084Sjake} 9186235Stmm 9286235Stmm/* 93112399Sjake * Add a cdevsw entry 9481084Sjake */ 9590623Stmm 9690623Stmmint 9790623Stmmcdevsw_add(struct cdevsw *newentry) 9890623Stmm{ 9990623Stmm int i; 100105531Stmm static int setup; 10181084Sjake 102183202Smarius if (!setup) { 103183202Smarius for (i = 0; i < NUMCDEVSW; i++) 104152862Sru if (!bmaj2cmaj[i]) 105152862Sru bmaj2cmaj[i] = 256; 106131951Smarcel setup++; 10784202Sjake } 108220885Sbz 109183202Smarius if (newentry->d_maj < 0 || newentry->d_maj >= NUMCDEVSW) { 110183202Smarius printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 11181390Sjake newentry->d_name, newentry->d_maj); 11286235Stmm return EINVAL; 113182918Smarius } 114111684Sru 11581084Sjake if (cdevsw[newentry->d_maj]) { 116132956Smarkm printf("WARNING: \"%s\" is usurping \"%s\"'s cdevsw[]\n", 117183202Smarius newentry->d_name, cdevsw[newentry->d_maj]->d_name); 118183202Smarius } 119101070Sjake cdevsw[newentry->d_maj] = newentry; 12089053Sjake 12186235Stmm if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) { 12286235Stmm if (bmaj2cmaj[newentry->d_bmaj] != 256) { 12381084Sjake printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n", 124100844Sjake newentry->d_name, 125152862Sru cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name); 12682914Sjake } 127119382Sjake bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj; 128182918Smarius } 129112399Sjake 130203845Smarius return 0; 131174195Srwatson} 132183202Smarius 133183202Smarius/* 13481084Sjake * Remove a cdevsw entry 135101070Sjake */ 13681390Sjake 13796998Sjakeint 13881084Sjakecdevsw_remove(struct cdevsw *oldentry) 13981084Sjake{ 140127297Salc if (oldentry->d_maj < 0 || oldentry->d_maj >= NUMCDEVSW) { 141166060Smarius printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 14281084Sjake oldentry->d_name, oldentry->d_maj); 143207537Smarius return EINVAL; 144 } 145 146 cdevsw[oldentry->d_maj] = NULL; 147 148 if (oldentry->d_bmaj >= 0 && oldentry->d_bmaj < NUMCDEVSW) 149 bmaj2cmaj[oldentry->d_bmaj] = NULL; 150 151 return 0; 152} 153 154int 155devsw_module_handler(module_t mod, int what, void* arg) 156{ 157 struct devsw_module_data* data = (struct devsw_module_data*) arg; 158 int error = 0; 159 160 switch (what) { 161 case MOD_LOAD: 162 error = cdevsw_add(data->cdevsw); 163 if (!error && data->chainevh) 164 error = data->chainevh(mod, what, data->chainarg); 165 return error; 166 167 case MOD_UNLOAD: 168 if (data->chainevh) { 169 error = data->chainevh(mod, what, data->chainarg); 170 if (error) 171 return error; 172 } 173 cdevsw_remove(data->cdevsw); 174 return error; 175 } 176 177 if (data->chainevh) 178 return data->chainevh(mod, what, data->chainarg); 179 else 180 return 0; 181} 182 183/* 184 * dev_t and u_dev_t primitives 185 */ 186 187#define DEVT_FASCIST 1 188 189int 190major(dev_t x) 191{ 192 uintptr_t i = (uintptr_t)x; 193 194#ifdef DEVT_FASCIST 195 return(255 - ((i >> 8) & 0xff)); 196#else 197 return((i >> 8) & 0xff); 198#endif 199} 200 201int 202minor(dev_t x) 203{ 204 uintptr_t i = (uintptr_t)x; 205 206 return(i & 0xffff00ff); 207} 208 209dev_t 210makebdev(int x, int y) 211{ 212 return (makedev(x, y)); 213} 214 215dev_t 216makedev(int x, int y) 217{ 218#ifdef DEVT_FASCIST 219 return ((dev_t)(uintptr_t) (((255 - x) << 8) | y)); 220#else 221 return ((dev_t)(uintptr_t) ((x << 8) | y)); 222#endif 223} 224 225udev_t 226dev2udev(dev_t x) 227{ 228 return makeudev(major(x), minor(x)); 229} 230 231dev_t 232udev2dev(udev_t x, int b) 233{ 234 switch (b) { 235 case 0: 236 return makedev(umajor(x), uminor(x)); 237 case 1: 238 return makebdev(umajor(x), uminor(x)); 239 default: 240 Debugger("udev2dev(...,X)"); 241 return NODEV; 242 } 243} 244 245int 246uminor(udev_t dev) 247{ 248 return(dev & 0xffff00ff); 249} 250 251int 252umajor(udev_t dev) 253{ 254 return((dev & 0xff00) >> 8); 255} 256 257udev_t 258makeudev(int x, int y) 259{ 260 return ((x << 8) | y); 261} 262 263