The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_conf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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  * $FreeBSD$
   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 
   47 struct cdevsw   *bdevsw[NUMBDEV];
   48 int     nblkdev = NUMBDEV;
   49 struct cdevsw   *cdevsw[NUMCDEV];
   50 int     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  */
   57 dev_t
   58 chrtoblk(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  */
   73 static int
   74 bdevsw_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 
  113 int
  114 cdevsw_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  */
  157 void
  158 cdevsw_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 
  168 int
  169 cdevsw_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                 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:
  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 
  196 int
  197 bdevsw_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:
  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:
  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 }

Cache object: 3040bfc453efaa568175ff88bcb5d083


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.