kern_conf.c revision 48859
1/*- 2 * Parts Copyright (c) 1995 Terrence R. Lambert 3 * Copyright (c) 1995 Julian R. Elischer 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Terrence R. Lambert. 17 * 4. The name Terrence R. Lambert may not be used to endorse or promote 18 * products derived from this software without specific prior written 19 * permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $Id: kern_conf.c,v 1.47 1999/07/04 14:58:38 phk Exp $ 34 */ 35 36#include <sys/param.h> 37#include <sys/systm.h> 38#include <sys/module.h> 39#include <sys/conf.h> 40#include <sys/vnode.h> 41 42#define cdevsw_ALLOCSTART (NUMCDEVSW/2) 43 44struct cdevsw *cdevsw[NUMCDEVSW]; 45 46int bmaj2cmaj[NUMCDEVSW]; 47 48/* 49 * Routine to convert from character to block device number. 50 * 51 * A minimal stub routine can always return NODEV. 52 */ 53dev_t 54chrtoblk(dev_t dev) 55{ 56 struct cdevsw *cd; 57 58 if((cd = devsw(dev)) != NULL) { 59 if (cd->d_bmaj != -1) 60 return(makedev(cd->d_bmaj,minor(dev))); 61 } 62 return(NODEV); 63} 64 65struct cdevsw * 66devsw(dev_t dev) 67{ 68 return(cdevsw[major(dev)]); 69} 70 71struct cdevsw * 72bdevsw(dev_t dev) 73{ 74 struct cdevsw *c; 75 int i = major(dev); 76 77 if (bmaj2cmaj[i] == 254) 78 return 0; 79 80 c = cdevsw[bmaj2cmaj[major(dev)]]; 81 if (!c) { 82 printf("bogus bdev dev_t %p, no cdev\n", (void *)dev); 83 Debugger("Bummer"); 84 return 0; 85 } 86 /* CMAJ zero is the console, which has no strategy so this works */ 87 if (c->d_strategy) 88 return (c); 89 return (0); 90} 91 92/* 93 * Add a cdevsw entry 94 */ 95 96int 97cdevsw_add(struct cdevsw *newentry) 98{ 99 int i; 100 static int setup; 101 102 if (!setup) { 103 for (i = 0; i < NUMCDEVSW; i++) 104 if (!bmaj2cmaj[i]) 105 bmaj2cmaj[i] = 254; 106 setup++; 107 } 108 109 if (newentry->d_maj < 0 || newentry->d_maj >= NUMCDEVSW) { 110 printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 111 newentry->d_name, newentry->d_maj); 112 return EINVAL; 113 } 114 115 if (cdevsw[newentry->d_maj]) { 116 printf("WARNING: \"%s\" is usurping \"%s\"'s cdevsw[]\n", 117 newentry->d_name, cdevsw[newentry->d_maj]->d_name); 118 } 119 cdevsw[newentry->d_maj] = newentry; 120 121 if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) { 122 if (bmaj2cmaj[newentry->d_bmaj] != 254) { 123 printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n", 124 newentry->d_name, 125 cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name); 126 } 127 bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj; 128 } 129 130 return 0; 131} 132 133/* 134 * Remove a cdevsw entry 135 */ 136 137int 138cdevsw_remove(struct cdevsw *oldentry) 139{ 140 if (oldentry->d_maj < 0 || oldentry->d_maj >= NUMCDEVSW) { 141 printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 142 oldentry->d_name, oldentry->d_maj); 143 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 return makedev(umajor(x), uminor(x)); 235} 236 237int 238uminor(udev_t dev) 239{ 240 return(dev & 0xffff00ff); 241} 242 243int 244umajor(udev_t dev) 245{ 246 return((dev & 0xff00) >> 8); 247} 248 249udev_t 250makeudev(int x, int y) 251{ 252 return ((x << 8) | y); 253} 254 255