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.29 1998/11/14 21:58:51 wollman Exp $
|
33 * $Id: kern_conf.c,v 1.30 1999/01/27 21:49:55 dillon 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 NUMBDEV 128 43#define NUMCDEV 256 44#define bdevsw_ALLOCSTART (NUMBDEV/2) 45#define cdevsw_ALLOCSTART (NUMCDEV/2) 46 47struct cdevsw *bdevsw[NUMBDEV]; 48int nblkdev = NUMBDEV; 49struct cdevsw *cdevsw[NUMCDEV]; 50int nchrdev = NUMCDEV; 51 52/* 53 * Routine to convert from character to block device number. 54 * 55 * A minimal stub routine can always return NODEV. 56 */ 57dev_t 58chrtoblk(dev_t dev) 59{ 60 struct cdevsw *cd; 61 62 if((cd = cdevsw[major(dev)]) != NULL) { 63 if (cd->d_bmaj != -1) 64 return(makedev(cd->d_bmaj,minor(dev))); 65 } 66 return(NODEV); 67} 68 69/* 70 * (re)place an entry in the bdevsw or cdevsw table 71 * return the slot used in major(*descrip) 72 */ 73static int 74bdevsw_add(dev_t *descrip, 75 struct cdevsw *newentry, 76 struct cdevsw **oldentry) 77{ 78 int i ; 79 80 if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ 81 /* 82 * Search the table looking for a slot... 83 */ 84 for (i = bdevsw_ALLOCSTART; i < nblkdev; i++) 85 if (bdevsw[i] == NULL) 86 break; /* found one! */ 87 /* out of allocable slots? */ 88 if (i >= nblkdev) { 89 return ENFILE; 90 } 91 } else { /* assign */ 92 i = major(*descrip); 93 if (i < 0 || i >= nblkdev) { 94 return EINVAL; 95 } 96 } 97 98 /* maybe save old */ 99 if (oldentry) { 100 *oldentry = bdevsw[i]; 101 } 102 if (newentry) { 103 newentry->d_bmaj = i; 104 } 105 /* replace with new */ 106 bdevsw[i] = newentry; 107 108 /* done! let them know where we put it */ 109 *descrip = makedev(i,0); 110 return 0; 111} 112 113int 114cdevsw_add(dev_t *descrip, 115 struct cdevsw *newentry, 116 struct cdevsw **oldentry) 117{ 118 int i ; 119 120 if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ 121 /* 122 * Search the table looking for a slot... 123 */ 124 for (i = cdevsw_ALLOCSTART; i < nchrdev; i++) 125 if (cdevsw[i] == NULL) 126 break; /* found one! */ 127 /* out of allocable slots? */ 128 if (i >= nchrdev) { 129 return ENFILE; 130 } 131 } else { /* assign */ 132 i = major(*descrip); 133 if (i < 0 || i >= nchrdev) { 134 return EINVAL; 135 } 136 } 137 138 /* maybe save old */ 139 if (oldentry) { 140 *oldentry = cdevsw[i]; 141 } 142 if (newentry) { 143 newentry->d_bmaj = -1; 144 newentry->d_maj = i; 145 } 146 /* replace with new */ 147 cdevsw[i] = newentry; 148 149 /* done! let them know where we put it */ 150 *descrip = makedev(i,0); 151 return 0; 152} 153 154/* 155 * note must call cdevsw_add before bdevsw_add due to d_bmaj hack. 156 */ 157void 158cdevsw_add_generic(int bdev, int cdev, struct cdevsw *cdevsw) 159{ 160 dev_t dev; 161 162 dev = makedev(cdev, 0); 163 cdevsw_add(&dev, cdevsw, NULL); 164 dev = makedev(bdev, 0); 165 bdevsw_add(&dev, cdevsw, NULL); 166} 167 168int 169cdevsw_module_handler(module_t mod, int what, void *arg) 170{ 171 struct cdevsw_module_data* data = (struct cdevsw_module_data*) arg; 172 int error; 173 174 switch (what) { 175 case MOD_LOAD:
|
176 if ((error = cdevsw_add(&data->dev, data->cdevsw, NULL)) != 0)
177 return error;
178 break;
|
176 error = cdevsw_add(&data->dev, data->cdevsw, NULL); 177 if (!error && data->chainevh) 178 error = data->chainevh(mod, what, data->chainarg); 179 return error; |
180 181 case MOD_UNLOAD:
|
181 if ((error = cdevsw_add(&data->dev, NULL, NULL)) != 0)
182 return error;
183 break;
|
182 if (data->chainevh) { 183 error = data->chainevh(mod, what, data->chainarg); 184 if (error) 185 return error; 186 } 187 return cdevsw_add(&data->dev, NULL, NULL); |
188 } 189 190 if (data->chainevh) 191 return data->chainevh(mod, what, data->chainarg); 192 else 193 return 0; 194} 195 196int 197bdevsw_module_handler(module_t mod, int what, void* arg) 198{ 199 struct bdevsw_module_data* data = (struct bdevsw_module_data*) arg; 200 int error; 201 202 switch (what) { 203 case MOD_LOAD:
|
200 if ((error = cdevsw_add(&data->cdev, data->cdevsw, NULL)) != 0)
201 return error;
202 if ((error = bdevsw_add(&data->bdev, data->cdevsw, NULL)) != 0) {
203 cdevsw_add(&data->bdev, NULL, NULL);
204 return error;
205 }
206 break;
|
204 error = cdevsw_add(&data->cdev, data->cdevsw, NULL); 205 if (!error) 206 error = bdevsw_add(&data->bdev, data->cdevsw, NULL); 207 if (!error && data->chainevh) 208 error = data->chainevh(mod, what, data->chainarg); 209 return error; |
210 211 case MOD_UNLOAD:
|
209 if ((error = bdevsw_add(&data->bdev, NULL, NULL)) != 0)
210 return error;
211 if ((error = cdevsw_add(&data->cdev, NULL, NULL)) != 0)
212 return error;
213 break;
|
212 if (data->chainevh) { 213 error = data->chainevh(mod, what, data->chainarg); 214 if (error) 215 return error; 216 } 217 error = bdevsw_add(&data->bdev, NULL, NULL); 218 if (!error) 219 error = cdevsw_add(&data->cdev, NULL, NULL); 220 return error; |
221 } 222 223 if (data->chainevh) 224 return data->chainevh(mod, what, data->chainarg); 225 else 226 return 0; 227}
|