kern_conf.c revision 46676
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.32 1999/05/07 10:10:50 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 NUMCDEV 256 43#define cdevsw_ALLOCSTART (NUMCDEV/2) 44 45struct cdevsw *cdevsw[NUMCDEV]; 46int nchrdev = NUMCDEV; 47 48int bmaj2cmaj[NUMCDEV]; 49int nblkdev = NUMCDEV; 50 51/* 52 * Routine to convert from character to block device number. 53 * 54 * A minimal stub routine can always return NODEV. 55 */ 56dev_t 57chrtoblk(dev_t dev) 58{ 59 struct cdevsw *cd; 60 61 if((cd = devsw(dev)) != NULL) { 62 if (cd->d_bmaj != -1) 63 return(makedev(cd->d_bmaj,minor(dev))); 64 } 65 return(NODEV); 66} 67 68int 69cdevsw_add(dev_t *descrip, 70 struct cdevsw *newentry, 71 struct cdevsw **oldentry) 72{ 73 int i ; 74 75 if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ 76 /* 77 * Search the table looking for a slot... 78 */ 79 for (i = cdevsw_ALLOCSTART; i < nchrdev; i++) 80 if (cdevsw[i] == NULL) 81 break; /* found one! */ 82 /* out of allocable slots? */ 83 if (i >= nchrdev) { 84 return ENFILE; 85 } 86 } else { /* assign */ 87 i = major(*descrip); 88 if (i < 0 || i >= nchrdev) { 89 return EINVAL; 90 } 91 } 92 93 /* maybe save old */ 94 if (oldentry) { 95 *oldentry = cdevsw[i]; 96 } 97 if (newentry) { 98 newentry->d_bmaj = -1; 99 newentry->d_maj = i; 100 } 101 /* replace with new */ 102 cdevsw[i] = newentry; 103 104 /* done! let them know where we put it */ 105 *descrip = makedev(i,0); 106 return 0; 107} 108 109/* 110 * note must call cdevsw_add before bdevsw_add due to d_bmaj hack. 111 */ 112void 113cdevsw_add_generic(int bmaj, int cmaj, struct cdevsw *cdevsw) 114{ 115 dev_t dev; 116 117 dev = makedev(cmaj, 0); 118 cdevsw_add(&dev, cdevsw, NULL); 119 bmaj2cmaj[bmaj] = cmaj; 120} 121 122int 123devsw_module_handler(module_t mod, int what, void* arg) 124{ 125 struct devsw_module_data* data = (struct devsw_module_data*) arg; 126 int error; 127 128 switch (what) { 129 case MOD_LOAD: 130 error = cdevsw_add(&data->cdev, data->cdevsw, NULL); 131 if (!error && data->cdevsw->d_strategy != nostrategy) { 132 if (data->bdev == NODEV) 133 data->bdev = data->cdev; 134 bmaj2cmaj[major(data->bdev)] = major(data->cdev); 135 } 136 if (!error && data->chainevh) 137 error = data->chainevh(mod, what, data->chainarg); 138 return error; 139 140 case MOD_UNLOAD: 141 if (data->chainevh) { 142 error = data->chainevh(mod, what, data->chainarg); 143 if (error) 144 return error; 145 } 146 if (data->cdevsw->d_strategy != nostrategy) 147 bmaj2cmaj[major(data->bdev)] = 0; 148 error = cdevsw_add(&data->cdev, NULL, NULL); 149 return error; 150 } 151 152 if (data->chainevh) 153 return data->chainevh(mod, what, data->chainarg); 154 else 155 return 0; 156} 157