kern_conf.c revision 46676
111126Sjulian/*- 211126Sjulian * Parts Copyright (c) 1995 Terrence R. Lambert 311126Sjulian * Copyright (c) 1995 Julian R. Elischer 411126Sjulian * All rights reserved. 511126Sjulian * 611126Sjulian * Redistribution and use in source and binary forms, with or without 711126Sjulian * modification, are permitted provided that the following conditions 811126Sjulian * are met: 911126Sjulian * 1. Redistributions of source code must retain the above copyright 1011126Sjulian * notice, this list of conditions and the following disclaimer. 1111126Sjulian * 2. Redistributions in binary form must reproduce the above copyright 1211126Sjulian * notice, this list of conditions and the following disclaimer in the 1311126Sjulian * documentation and/or other materials provided with the distribution. 1411126Sjulian * 3. All advertising materials mentioning features or use of this software 1511126Sjulian * must display the following acknowledgement: 1611126Sjulian * This product includes software developed by Terrence R. Lambert. 1711126Sjulian * 4. The name Terrence R. Lambert may not be used to endorse or promote 1811126Sjulian * products derived from this software without specific prior written 1911126Sjulian * permission. 2011126Sjulian * 2111126Sjulian * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY 2211126Sjulian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311126Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411126Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE 2511126Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2611126Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2711126Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2811126Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2911126Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3011126Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3111126Sjulian * SUCH DAMAGE. 3211126Sjulian * 3346676Sphk * $Id: kern_conf.c,v 1.32 1999/05/07 10:10:50 phk Exp $ 3411126Sjulian */ 3511126Sjulian 3611126Sjulian#include <sys/param.h> 3711127Sjulian#include <sys/systm.h> 3836735Sdfr#include <sys/module.h> 3911126Sjulian#include <sys/conf.h> 4012954Sjulian#include <sys/vnode.h> 4111126Sjulian 4217675Sjulian#define NUMCDEV 256 4317675Sjulian#define cdevsw_ALLOCSTART (NUMCDEV/2) 4412954Sjulian 4512954Sjulianstruct cdevsw *cdevsw[NUMCDEV]; 4612954Sjulianint nchrdev = NUMCDEV; 4712954Sjulian 4846635Sphkint bmaj2cmaj[NUMCDEV]; 4946635Sphkint nblkdev = NUMCDEV; 5046635Sphk 5111126Sjulian/* 5212954Sjulian * Routine to convert from character to block device number. 5312954Sjulian * 5412954Sjulian * A minimal stub routine can always return NODEV. 5512954Sjulian */ 5612954Sjuliandev_t 5712954Sjulianchrtoblk(dev_t dev) 5812954Sjulian{ 5912954Sjulian struct cdevsw *cd; 6012954Sjulian 6146676Sphk if((cd = devsw(dev)) != NULL) { 6237389Sjulian if (cd->d_bmaj != -1) 6337389Sjulian return(makedev(cd->d_bmaj,minor(dev))); 6412954Sjulian } 6512954Sjulian return(NODEV); 6612954Sjulian} 6712954Sjulian 6837389Sjulianint 6937389Sjuliancdevsw_add(dev_t *descrip, 7037389Sjulian struct cdevsw *newentry, 7137389Sjulian struct cdevsw **oldentry) 7217264Sphk{ 7337389Sjulian int i ; 7417264Sphk 7537389Sjulian if ( (int)*descrip == NODEV) { /* auto (0 is valid) */ 7637389Sjulian /* 7737389Sjulian * Search the table looking for a slot... 7837389Sjulian */ 7937389Sjulian for (i = cdevsw_ALLOCSTART; i < nchrdev; i++) 8037389Sjulian if (cdevsw[i] == NULL) 8137389Sjulian break; /* found one! */ 8237389Sjulian /* out of allocable slots? */ 8337389Sjulian if (i >= nchrdev) { 8437389Sjulian return ENFILE; 8537389Sjulian } 8637389Sjulian } else { /* assign */ 8737389Sjulian i = major(*descrip); 8837389Sjulian if (i < 0 || i >= nchrdev) { 8937389Sjulian return EINVAL; 9037389Sjulian } 9137389Sjulian } 9217264Sphk 9337389Sjulian /* maybe save old */ 9437389Sjulian if (oldentry) { 9537389Sjulian *oldentry = cdevsw[i]; 9637389Sjulian } 9737389Sjulian if (newentry) { 9837389Sjulian newentry->d_bmaj = -1; 9937389Sjulian newentry->d_maj = i; 10037389Sjulian } 10137389Sjulian /* replace with new */ 10237389Sjulian cdevsw[i] = newentry; 10337389Sjulian 10437389Sjulian /* done! let them know where we put it */ 10537389Sjulian *descrip = makedev(i,0); 10637389Sjulian return 0; 10737389Sjulian} 10837389Sjulian 10937389Sjulian/* 11037389Sjulian * note must call cdevsw_add before bdevsw_add due to d_bmaj hack. 11137389Sjulian */ 11217264Sphkvoid 11346635Sphkcdevsw_add_generic(int bmaj, int cmaj, struct cdevsw *cdevsw) 11417264Sphk{ 11517264Sphk dev_t dev; 11637172Sphk 11746635Sphk dev = makedev(cmaj, 0); 11837389Sjulian cdevsw_add(&dev, cdevsw, NULL); 11946635Sphk bmaj2cmaj[bmaj] = cmaj; 12017264Sphk} 12136735Sdfr 12236735Sdfrint 12346635Sphkdevsw_module_handler(module_t mod, int what, void* arg) 12436735Sdfr{ 12546635Sphk struct devsw_module_data* data = (struct devsw_module_data*) arg; 12636735Sdfr int error; 12736735Sdfr 12836735Sdfr switch (what) { 12936735Sdfr case MOD_LOAD: 13046635Sphk error = cdevsw_add(&data->cdev, data->cdevsw, NULL); 13146635Sphk if (!error && data->cdevsw->d_strategy != nostrategy) { 13246635Sphk if (data->bdev == NODEV) 13346635Sphk data->bdev = data->cdev; 13446635Sphk bmaj2cmaj[major(data->bdev)] = major(data->cdev); 13544975Sdfr } 13644975Sdfr if (!error && data->chainevh) 13744975Sdfr error = data->chainevh(mod, what, data->chainarg); 13844975Sdfr return error; 13936735Sdfr 14036735Sdfr case MOD_UNLOAD: 14144975Sdfr if (data->chainevh) { 14244975Sdfr error = data->chainevh(mod, what, data->chainarg); 14344975Sdfr if (error) 14444975Sdfr return error; 14544975Sdfr } 14646635Sphk if (data->cdevsw->d_strategy != nostrategy) 14746635Sphk bmaj2cmaj[major(data->bdev)] = 0; 14846635Sphk error = cdevsw_add(&data->cdev, NULL, NULL); 14944975Sdfr return error; 15036735Sdfr } 15136735Sdfr 15236735Sdfr if (data->chainevh) 15336735Sdfr return data->chainevh(mod, what, data->chainarg); 15436735Sdfr else 15536735Sdfr return 0; 15636735Sdfr} 157