kern_conf.c revision 46676
139213Sgibbs/*- 239213Sgibbs * Parts Copyright (c) 1995 Terrence R. Lambert 339213Sgibbs * Copyright (c) 1995 Julian R. Elischer 439213Sgibbs * All rights reserved. 539213Sgibbs * 639213Sgibbs * Redistribution and use in source and binary forms, with or without 739213Sgibbs * modification, are permitted provided that the following conditions 839213Sgibbs * are met: 939213Sgibbs * 1. Redistributions of source code must retain the above copyright 1039213Sgibbs * notice, this list of conditions and the following disclaimer. 1139213Sgibbs * 2. Redistributions in binary form must reproduce the above copyright 1239213Sgibbs * notice, this list of conditions and the following disclaimer in the 1339213Sgibbs * documentation and/or other materials provided with the distribution. 1439213Sgibbs * 3. All advertising materials mentioning features or use of this software 1539213Sgibbs * must display the following acknowledgement: 1639213Sgibbs * This product includes software developed by Terrence R. Lambert. 1739213Sgibbs * 4. The name Terrence R. Lambert may not be used to endorse or promote 1839213Sgibbs * products derived from this software without specific prior written 1939213Sgibbs * permission. 2039213Sgibbs * 2139213Sgibbs * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY 2239213Sgibbs * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2339213Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2439213Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE 2539213Sgibbs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2639213Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2739213Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2850477Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2939213Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3039213Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3139213Sgibbs * SUCH DAMAGE. 3239213Sgibbs * 3339213Sgibbs * $Id: kern_conf.c,v 1.32 1999/05/07 10:10:50 phk Exp $ 3439213Sgibbs */ 3539213Sgibbs 3660041Sphk#include <sys/param.h> 3739213Sgibbs#include <sys/systm.h> 3839213Sgibbs#include <sys/module.h> 3939213Sgibbs#include <sys/conf.h> 4050073Sken#include <sys/vnode.h> 4139213Sgibbs 4239213Sgibbs#define NUMCDEV 256 4339213Sgibbs#define cdevsw_ALLOCSTART (NUMCDEV/2) 4439213Sgibbs 4539213Sgibbsstruct cdevsw *cdevsw[NUMCDEV]; 4639213Sgibbsint nchrdev = NUMCDEV; 4739213Sgibbs 4839213Sgibbsint bmaj2cmaj[NUMCDEV]; 4939213Sgibbsint nblkdev = NUMCDEV; 5039213Sgibbs 5139213Sgibbs/* 5250073Sken * Routine to convert from character to block device number. 5350073Sken * 5439213Sgibbs * A minimal stub routine can always return NODEV. 5539213Sgibbs */ 5639213Sgibbsdev_t 5739213Sgibbschrtoblk(dev_t dev) 5839213Sgibbs{ 5939213Sgibbs struct cdevsw *cd; 6039213Sgibbs 6139213Sgibbs if((cd = devsw(dev)) != NULL) { 6239213Sgibbs if (cd->d_bmaj != -1) 6339213Sgibbs return(makedev(cd->d_bmaj,minor(dev))); 6439213Sgibbs } 6539213Sgibbs return(NODEV); 6639213Sgibbs} 6739213Sgibbs 6839213Sgibbsint 6939213Sgibbscdevsw_add(dev_t *descrip, 7039213Sgibbs struct cdevsw *newentry, 7139213Sgibbs struct cdevsw **oldentry) 7239213Sgibbs{ 7339213Sgibbs int i ; 7439213Sgibbs 7539213Sgibbs if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ 7639213Sgibbs /* 7739213Sgibbs * Search the table looking for a slot... 7859249Sphk */ 79112006Sphk for (i = cdevsw_ALLOCSTART; i < nchrdev; i++) 8060938Sjake if (cdevsw[i] == NULL) 8139213Sgibbs break; /* found one! */ 8239213Sgibbs /* out of allocable slots? */ 8339213Sgibbs if (i >= nchrdev) { 8450073Sken return ENFILE; 8553257Sken } 8639213Sgibbs } else { /* assign */ 8739213Sgibbs i = major(*descrip); 8839213Sgibbs if (i < 0 || i >= nchrdev) { 8939213Sgibbs return EINVAL; 9039213Sgibbs } 9139213Sgibbs } 9239213Sgibbs 9339213Sgibbs /* maybe save old */ 9439213Sgibbs if (oldentry) { 9540603Sken *oldentry = cdevsw[i]; 9639213Sgibbs } 9739213Sgibbs if (newentry) { 9839213Sgibbs newentry->d_bmaj = -1; 9939213Sgibbs newentry->d_maj = i; 10050073Sken } 10139213Sgibbs /* replace with new */ 10239213Sgibbs cdevsw[i] = newentry; 10339213Sgibbs 10439213Sgibbs /* done! let them know where we put it */ 10539213Sgibbs *descrip = makedev(i,0); 10639213Sgibbs return 0; 10739213Sgibbs} 10839213Sgibbs 10939213Sgibbs/* 11039213Sgibbs * note must call cdevsw_add before bdevsw_add due to d_bmaj hack. 11139213Sgibbs */ 11239213Sgibbsvoid 11339213Sgibbscdevsw_add_generic(int bmaj, int cmaj, struct cdevsw *cdevsw) 11439213Sgibbs{ 11539213Sgibbs dev_t dev; 11672119Speter 11739213Sgibbs dev = makedev(cmaj, 0); 11839213Sgibbs cdevsw_add(&dev, cdevsw, NULL); 11939213Sgibbs bmaj2cmaj[bmaj] = cmaj; 12047625Sphk} 121111815Sphk 122111815Sphkint 123111815Sphkdevsw_module_handler(module_t mod, int what, void* arg) 124111815Sphk{ 125111815Sphk struct devsw_module_data* data = (struct devsw_module_data*) arg; 126111815Sphk int error; 127111815Sphk 128111815Sphk switch (what) { 12939213Sgibbs case MOD_LOAD: 13039213Sgibbs error = cdevsw_add(&data->cdev, data->cdevsw, NULL); 13150073Sken if (!error && data->cdevsw->d_strategy != nostrategy) { 13250073Sken if (data->bdev == NODEV) 13350073Sken data->bdev = data->cdev; 13450073Sken bmaj2cmaj[major(data->bdev)] = major(data->cdev); 13539213Sgibbs } 13683366Sjulian if (!error && data->chainevh) 13739213Sgibbs error = data->chainevh(mod, what, data->chainarg); 13839213Sgibbs return error; 13939213Sgibbs 14039213Sgibbs case MOD_UNLOAD: 14139213Sgibbs if (data->chainevh) { 14240603Sken error = data->chainevh(mod, what, data->chainarg); 14339213Sgibbs if (error) 14439213Sgibbs return error; 145101940Snjl } 14639213Sgibbs if (data->cdevsw->d_strategy != nostrategy) 14739213Sgibbs bmaj2cmaj[major(data->bdev)] = 0; 14839213Sgibbs error = cdevsw_add(&data->cdev, NULL, NULL); 14939213Sgibbs return error; 15039213Sgibbs } 15140603Sken 15240603Sken if (data->chainevh) 15340603Sken return data->chainevh(mod, what, data->chainarg); 15440603Sken else 15540603Sken return 0; 15640603Sken} 15739213Sgibbs