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/dev/bio.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 /*      $NetBSD: bio.c,v 1.1.4.3 2008/08/29 21:24:19 bouyer Exp $ */
    2 /*      $OpenBSD: bio.c,v 1.9 2007/03/20 02:35:55 marco Exp $   */
    3 
    4 /*
    5  * Copyright (c) 2002 Niklas Hallqvist.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 /* A device controller ioctl tunnelling device.  */
   29 
   30 #include <sys/cdefs.h>
   31 __KERNEL_RCSID(0, "$NetBSD: bio.c,v 1.1.4.3 2008/08/29 21:24:19 bouyer Exp $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/conf.h>
   35 #include <sys/device.h>
   36 #include <sys/event.h>
   37 #include <sys/ioctl.h>
   38 #include <sys/malloc.h>
   39 #include <sys/queue.h>
   40 #include <sys/systm.h>
   41 #include <sys/proc.h>
   42 #include <sys/kauth.h>
   43 
   44 #include <dev/biovar.h>
   45 
   46 struct bio_mapping {
   47         LIST_ENTRY(bio_mapping) bm_link;
   48         struct device *bm_dev;
   49         int (*bm_ioctl)(struct device *, u_long, caddr_t);
   50 };
   51 
   52 static LIST_HEAD(, bio_mapping) bios = LIST_HEAD_INITIALIZER(bios);
   53 
   54 void    bioattach(int);
   55 static int      bioclose(dev_t, int, int, struct lwp *);
   56 static int      bioioctl(dev_t, u_long, caddr_t, int, struct lwp *);
   57 static int      bioopen(dev_t, int, int, struct lwp *);
   58 
   59 static int      bio_delegate_ioctl(void *, u_long, void *);
   60 static struct   bio_mapping *bio_lookup(char *);
   61 static int      bio_validate(void *);
   62 
   63 const struct cdevsw bio_cdevsw = {
   64         bioopen, bioclose, noread, nowrite, bioioctl,
   65         nostop, notty, nopoll, nommap, nokqfilter, 0
   66 };
   67 
   68 
   69 void
   70 bioattach(int nunits)
   71 {
   72 }
   73 
   74 static int
   75 bioopen(dev_t dev, int flags, int mode, struct lwp *l)
   76 {
   77         return 0;
   78 }
   79 
   80 static int
   81 bioclose(dev_t dev, int flags, int mode, struct lwp *l)
   82 {
   83         return 0;
   84 }
   85 
   86 static int
   87 bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct  lwp *l)
   88 {
   89         struct bio_locate *locate;
   90         struct bio_common *common;
   91         char name[16];
   92         int error, s;
   93 
   94         switch(cmd) {
   95         case BIOCLOCATE:
   96         case BIOCINQ:
   97         case BIOCDISK:
   98         case BIOCDISK_NOVOL:
   99         case BIOCVOL:
  100 #ifdef COMPAT_30
  101         case OBIOCDISK:
  102         case OBIOCVOL:
  103 #endif
  104                 error = kauth_authorize_device_passthru(l->l_cred, dev,
  105                     KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF, addr);
  106                 if (error)
  107                         return error;
  108                 break;
  109         case BIOCBLINK:
  110         case BIOCSETSTATE:
  111         case BIOCVOLOPS:
  112                 error = kauth_authorize_device_passthru(l->l_cred, dev,
  113                     KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITECONF, addr);
  114                 if (error)
  115                         return error;
  116                 break;
  117         case BIOCALARM: {
  118                 struct bioc_alarm *alarm = (struct bioc_alarm *)addr;
  119                 switch (alarm->ba_opcode) {
  120                 case BIOC_SADISABLE:
  121                 case BIOC_SAENABLE:
  122                 case BIOC_SASILENCE:
  123                 case BIOC_SATEST:
  124                         error = kauth_authorize_device_passthru(l->l_cred, dev,
  125                             KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_WRITECONF, addr);
  126                         if (error)
  127                                 return error;
  128                         break;
  129                 case BIOC_GASTATUS:
  130                         error = kauth_authorize_device_passthru(l->l_cred, dev,
  131                             KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_READCONF, addr);
  132                         if (error)
  133                                 return error;
  134                         break;
  135                 default:
  136                         return EINVAL;
  137                 }
  138                 break;
  139         }
  140         default:
  141                 return ENOTTY;
  142         }
  143 
  144         switch (cmd) {
  145         case BIOCLOCATE:
  146                 locate = (struct bio_locate *)addr;
  147                 error = copyinstr(locate->bl_name, name, sizeof(name), NULL);
  148                 if (error != 0)
  149                         return error;
  150                 locate->bl_cookie = bio_lookup(name);
  151                 if (locate->bl_cookie == NULL)
  152                         return ENOENT;
  153                 break;
  154 
  155         default:
  156                 common = (struct bio_common *)addr;
  157                 s = splbio();
  158                 if (!bio_validate(common->bc_cookie)) {
  159                         splx(s);
  160                         return ENOENT;
  161                 }
  162                 splx(s);
  163 #ifdef COMPAT_30
  164                 switch (cmd) {
  165                 case OBIOCDISK: {
  166                         struct bioc_disk *bd =
  167                             malloc(sizeof(*bd), M_DEVBUF, M_WAITOK|M_ZERO);
  168 
  169                         (void)memcpy(bd, addr, sizeof(struct obioc_disk));
  170                         error = bio_delegate_ioctl(common->bc_cookie,
  171                             BIOCDISK, bd);
  172                         if (error) {
  173                                 free(bd, M_DEVBUF);
  174                                 return error;
  175                         }
  176                         (void)memcpy(addr, bd, sizeof(struct obioc_disk));
  177                         free(bd, M_DEVBUF);
  178                         return 0;
  179                 }
  180                 case OBIOCVOL: {
  181                         struct bioc_vol *bv =
  182                             malloc(sizeof(*bv), M_DEVBUF, M_WAITOK|M_ZERO);
  183 
  184                         (void)memcpy(bv, addr, sizeof(struct obioc_vol));
  185                         error = bio_delegate_ioctl(common->bc_cookie,
  186                             BIOCVOL, bv);
  187                         if (error) {
  188                                 free(bv, M_DEVBUF);
  189                                 return error;
  190                         }
  191                         (void)memcpy(addr, bv, sizeof(struct obioc_vol));
  192                         free(bv, M_DEVBUF);
  193                         return 0;
  194                 }
  195                 }
  196 #endif
  197                 error = bio_delegate_ioctl(common->bc_cookie, cmd, addr);
  198                 return error;
  199         }
  200         return 0;
  201 }
  202 
  203 int
  204 bio_register(struct device *dev, int (*ioctl)(struct device *, u_long, caddr_t))
  205 {
  206         struct bio_mapping *bm;
  207         int s;
  208 
  209         bm = malloc(sizeof (*bm), M_DEVBUF, M_NOWAIT|M_ZERO);
  210         if (bm == NULL)
  211                 return ENOMEM;
  212         bm->bm_dev = dev;
  213         bm->bm_ioctl = ioctl;
  214         s = splbio();
  215         LIST_INSERT_HEAD(&bios, bm, bm_link);
  216         splx(s);
  217         return 0;
  218 }
  219 
  220 void
  221 bio_unregister(struct device *dev)
  222 {
  223         struct bio_mapping *bm, *next;
  224         int s;
  225 
  226         s = splbio();
  227         for (bm = LIST_FIRST(&bios); bm != NULL; bm = next) {
  228                 next = LIST_NEXT(bm, bm_link);
  229 
  230                 if (dev == bm->bm_dev) {
  231                         LIST_REMOVE(bm, bm_link);
  232                         free(bm, M_DEVBUF);
  233                 }
  234         }
  235         splx(s);
  236 }
  237 
  238 static struct bio_mapping *
  239 bio_lookup(char *name)
  240 {
  241         struct bio_mapping *bm;
  242         int s;
  243 
  244         s = splbio();
  245         LIST_FOREACH(bm, &bios, bm_link) {
  246                 if (strcmp(name, bm->bm_dev->dv_xname) == 0) {
  247                         splx(s);
  248                         return bm;
  249                 }
  250         }
  251         splx(s);
  252         return NULL;
  253 }
  254 
  255 static int
  256 bio_validate(void *cookie)
  257 {
  258         struct bio_mapping *bm;
  259 
  260         LIST_FOREACH(bm, &bios, bm_link)
  261                 if (bm == cookie)
  262                         return 1;
  263 
  264         return 0;
  265 }
  266 
  267 static int
  268 bio_delegate_ioctl(void * cookie, u_long cmd, void *addr)
  269 {
  270         struct bio_mapping *bm = cookie;
  271         
  272         return bm->bm_ioctl(bm->bm_dev, cmd, addr);
  273 }

Cache object: 1f793ad7c43c1787e2fb2d708acf9604


[ 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.