kern_conf.c revision 37172
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.25 1998/06/25 11:27:34 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 NUMBDEV 128 43#define NUMCDEV 256 44#define bdevsw_ALLOCSTART (NUMBDEV/2) 45#define cdevsw_ALLOCSTART (NUMCDEV/2) 46 47struct bdevsw *bdevsw[NUMBDEV]; 48int nblkdev = NUMBDEV; 49struct cdevsw *cdevsw[NUMCDEV]; 50int nchrdev = NUMCDEV; 51 52static void cdevsw_make __P((struct bdevsw *from)); 53 54/* 55 * Routine to convert from character to block device number. 56 * 57 * A minimal stub routine can always return NODEV. 58 */ 59dev_t 60chrtoblk(dev_t dev) 61{ 62 struct bdevsw *bd; 63 struct cdevsw *cd; 64 65 if(cd = cdevsw[major(dev)]) { 66 if ( (bd = cd->d_bdev) ) 67 return(makedev(bd->d_maj,minor(dev))); 68 } 69 return(NODEV); 70} 71 72/* 73 * (re)place an entry in the bdevsw or cdevsw table 74 * return the slot used in major(*descrip) 75 */ 76#define ADDENTRY(TTYPE,NXXXDEV,ALLOCSTART) \ 77int TTYPE##_add(dev_t *descrip, \ 78 struct TTYPE *newentry, \ 79 struct TTYPE **oldentry) \ 80{ \ 81 int i ; \ 82 if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ \ 83 /* \ 84 * Search the table looking for a slot... \ 85 */ \ 86 for (i = ALLOCSTART; i < NXXXDEV; i++) \ 87 if (TTYPE[i] == NULL) \ 88 break; /* found one! */ \ 89 /* out of allocable slots? */ \ 90 if (i >= NXXXDEV) { \ 91 return ENFILE; \ 92 } \ 93 } else { /* assign */ \ 94 i = major(*descrip); \ 95 if (i < 0 || i >= NXXXDEV) { \ 96 return EINVAL; \ 97 } \ 98 } \ 99 \ 100 /* maybe save old */ \ 101 if (oldentry) { \ 102 *oldentry = TTYPE[i]; \ 103 } \ 104 if (newentry) \ 105 newentry->d_maj = i; \ 106 /* replace with new */ \ 107 TTYPE[i] = newentry; \ 108 \ 109 /* done! let them know where we put it */ \ 110 *descrip = makedev(i,0); \ 111 return 0; \ 112} \ 113 114static ADDENTRY(bdevsw, nblkdev,bdevsw_ALLOCSTART) 115ADDENTRY(cdevsw, nchrdev,cdevsw_ALLOCSTART) 116 117/* 118 * Since the bdevsw struct for a disk contains all the information 119 * needed to create a cdevsw entry, these two routines do that, rather 120 * than specifying it by hand. 121 */ 122 123static void 124cdevsw_make(struct bdevsw *from) 125{ 126 struct cdevsw *to = from->d_cdev; 127 128 if (!to) 129 panic("No target cdevsw in bdevsw"); 130 to->d_open = from->d_open; 131 to->d_close = from->d_close; 132 to->d_read = rawread; 133 to->d_write = rawwrite; 134 to->d_ioctl = from->d_ioctl; 135 to->d_stop = nostop; 136 to->d_reset = nullreset; 137 to->d_devtotty = nodevtotty; 138 to->d_poll = seltrue; 139 to->d_mmap = nommap; 140 to->d_strategy = from->d_strategy; 141 to->d_name = from->d_name; 142 to->d_bdev = from; 143 to->d_maj = -1; 144 to->d_bmaj = from->d_maj; 145 to->d_maxio = from->d_maxio; 146 to->d_dump = from->d_dump; 147 to->d_psize = from->d_psize; 148 to->d_flags = from->d_flags; 149} 150 151void 152bdevsw_add_generic(int bdev, int cdev, struct bdevsw *bdevsw) 153{ 154 dev_t dev; 155 156 cdevsw_make(bdevsw); 157 dev = makedev(cdev, 0); 158 cdevsw_add(&dev, bdevsw->d_cdev, NULL); 159 dev = makedev(bdev, 0); 160 bdevsw_add(&dev, bdevsw , NULL); 161} 162 163int 164cdevsw_module_handler(module_t mod, modeventtype_t what, void* arg) 165{ 166 struct cdevsw_module_data* data = (struct cdevsw_module_data*) arg; 167 int error; 168 169 switch (what) { 170 case MOD_LOAD: 171 if (error = cdevsw_add(&data->dev, data->cdevsw, NULL)) 172 return error; 173 break; 174 175 case MOD_UNLOAD: 176 if (error = cdevsw_add(&data->dev, NULL, NULL)) 177 return error; 178 break; 179 } 180 181 if (data->chainevh) 182 return data->chainevh(mod, what, data->chainarg); 183 else 184 return 0; 185} 186 187int 188bdevsw_module_handler(module_t mod, modeventtype_t what, void* arg) 189{ 190 struct bdevsw_module_data* data = (struct bdevsw_module_data*) arg; 191 int error; 192 193 switch (what) { 194 case MOD_LOAD: 195 cdevsw_make(data->bdevsw); 196 if (error = cdevsw_add(&data->cdev, data->bdevsw->d_cdev, NULL)) 197 return error; 198 if (error = bdevsw_add(&data->bdev, data->bdevsw, NULL)) 199 return error; 200 break; 201 202 case MOD_UNLOAD: 203 if (error = cdevsw_add(&data->cdev, NULL, NULL)) 204 return error; 205 if (error = bdevsw_add(&data->bdev, NULL, NULL)) 206 return error; 207 break; 208 } 209 210 if (data->chainevh) 211 return data->chainevh(mod, what, data->chainarg); 212 else 213 return 0; 214} 215