kern_conf.c revision 47680
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.41 1999/05/31 11:27:28 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 cdevsw[newentry->d_maj] = newentry; 116 117 if (newentry->d_bmaj >= 0 || newentry->d_bmaj < NUMCDEVSW) 118 bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj; 119 120 return 0; 121} 122 123int 124devsw_module_handler(module_t mod, int what, void* arg) 125{ 126 struct devsw_module_data* data = (struct devsw_module_data*) arg; 127 int error; 128 129 if (data->cmaj == NOMAJ) 130 data->cdev = NODEV; 131 else 132 data->cdev = makedev(data->cmaj, 0); 133 switch (what) { 134 case MOD_LOAD: 135 error = cdevsw_add(data->cdevsw); 136 if (!error && data->cdevsw->d_strategy != nostrategy) { 137 if (data->bmaj == NOMAJ) { 138 data->bdev = data->cdev; 139 data->bmaj = data->cmaj; 140 } else { 141 data->bdev = makedev(data->bmaj, 0); 142 } 143 data->cdevsw->d_maj = data->bmaj; 144 bmaj2cmaj[major(data->bdev)] = major(data->cdev); 145 } 146 if (!error && data->chainevh) 147 error = data->chainevh(mod, what, data->chainarg); 148 return error; 149 150 case MOD_UNLOAD: 151 if (data->chainevh) { 152 error = data->chainevh(mod, what, data->chainarg); 153 if (error) 154 return error; 155 } 156 if (data->cdevsw->d_strategy != nostrategy) 157 bmaj2cmaj[major(data->bdev)] = 0; 158 return error; 159 } 160 161 if (data->chainevh) 162 return data->chainevh(mod, what, data->chainarg); 163 else 164 return 0; 165} 166 167/* 168 * dev_t and u_dev_t primitives 169 */ 170 171#define DEVT_FASCIST 1 172 173int 174major(dev_t x) 175{ 176 uintptr_t i = (uintptr_t)x; 177 178#ifdef DEVT_FASCIST 179 return(255 - ((i >> 8) & 0xff)); 180#else 181 return((i >> 8) & 0xff); 182#endif 183} 184 185int 186minor(dev_t x) 187{ 188 uintptr_t i = (uintptr_t)x; 189 190 return(i & 0xffff00ff); 191} 192 193dev_t 194makebdev(int x, int y) 195{ 196 return (makedev(x, y)); 197} 198 199dev_t 200makedev(int x, int y) 201{ 202#ifdef DEVT_FASCIST 203 return ((dev_t) (((255 - x) << 8) | y)); 204#else 205 return ((dev_t) ((x << 8) | y)); 206#endif 207} 208 209udev_t 210dev2udev(dev_t x) 211{ 212 return umakedev(major(x), minor(x)); 213} 214 215dev_t 216udev2dev(udev_t x, int b) 217{ 218 return makedev(umajor(x), uminor(x)); 219} 220 221int 222uminor(udev_t dev) 223{ 224 return(dev & 0xffff00ff); 225} 226 227int 228umajor(udev_t dev) 229{ 230 return((dev & 0xff00) >> 8); 231} 232 233udev_t 234umakedev(int x, int y) 235{ 236 return ((x << 8) | y); 237} 238 239