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_drvctl.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: kern_drvctl.c,v 1.1 2004/08/18 12:19:29 drochner Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2004
    5  *      Matthias Drochner.  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 AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __KERNEL_RCSID(0, "$NetBSD: kern_drvctl.c,v 1.1 2004/08/18 12:19:29 drochner Exp $");
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/kernel.h>
   35 #include <sys/conf.h>
   36 #include <sys/device.h>
   37 #include <sys/event.h>
   38 #include <sys/malloc.h>
   39 #include <sys/ioctl.h>
   40 #include <sys/drvctlio.h>
   41 
   42 dev_type_ioctl(drvctlioctl);
   43 
   44 const struct cdevsw drvctl_cdevsw = {
   45         nullopen, nullclose, nullread, nullwrite, drvctlioctl,
   46         nostop, notty, nopoll, nommap, nokqfilter,
   47 };
   48 
   49 void drvctlattach(int);
   50 
   51 #define MAXLOCATORS 100
   52 
   53 static int
   54 detachdevbyname(const char *devname)
   55 {
   56         struct device *d;
   57 
   58         TAILQ_FOREACH(d, &alldevs, dv_list) {
   59                 if (!strcmp(devname, d->dv_xname)) {
   60 #ifndef XXXFULLRISK
   61                         /*
   62                          * If the parent cannot be notified, it might keep
   63                          * pointers to the detached device.
   64                          * There might be a private notification mechanism,
   65                          * but better play save here.
   66                          */
   67                         if (d->dv_parent &&
   68                             !d->dv_parent->dv_cfattach->ca_childdetached)
   69                                 return (ENOTSUP);
   70 #endif
   71                         return (config_detach(d, 0));
   72                 }
   73         }
   74 
   75         return (ENXIO);
   76 }
   77 
   78 static int
   79 rescanbus(const char *busname, const char *ifattr,
   80           int numlocators, const int *locators)
   81 {
   82         int i;
   83         struct device *d;
   84         const char * const *ap;
   85 
   86         /* XXX there should be a way to get limits and defaults (per device)
   87            from config generated data */
   88         int locs[MAXLOCATORS];
   89         for (i = 0; i < MAXLOCATORS; i++)
   90                 locs[i] = -1;
   91 
   92         for (i = 0; i < numlocators;i++)
   93                 locs[i] = locators[i];
   94 
   95         TAILQ_FOREACH(d, &alldevs, dv_list) {
   96                 if (!strcmp(busname, d->dv_xname)) {
   97                         /*
   98                          * must support rescan, and must have something
   99                          * to attach to
  100                          */
  101                         if (!d->dv_cfattach->ca_rescan ||
  102                             !d->dv_cfdriver->cd_attrs)
  103                                 return (ENODEV);
  104 
  105                         /* allow to omit attribute if there is exactly one */
  106                         if (!ifattr) {
  107                                 if (d->dv_cfdriver->cd_attrs[1])
  108                                         return (EINVAL);
  109                                 ifattr = d->dv_cfdriver->cd_attrs[0];
  110                         } else {
  111                                 /* check for valid attribute passed */
  112                                 for (ap = d->dv_cfdriver->cd_attrs; *ap; ap++)
  113                                         if (!strcmp(*ap, ifattr))
  114                                                 break;
  115                                 if (!*ap)
  116                                         return (EINVAL);
  117                         }
  118 
  119                         return (*d->dv_cfattach->ca_rescan)(d, ifattr, locs);
  120                 }
  121         }
  122 
  123         return (ENXIO);
  124 }
  125 
  126 int
  127 drvctlioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  128 {
  129         int res;
  130         char *ifattr;
  131         int *locs;
  132 
  133         switch (cmd) {
  134         case DRVDETACHDEV:
  135 #define d ((struct devdetachargs *)data)
  136                 res = detachdevbyname(d->devname);
  137 #undef d
  138                 break;
  139         case DRVRESCANBUS:
  140 #define d ((struct devrescanargs *)data)
  141                 d->busname[sizeof(d->busname) - 1] = '\0';
  142 
  143                 /* XXX better copyin? */
  144                 if (d->ifattr[0]) {
  145                         d->ifattr[sizeof(d->ifattr) - 1] = '\0';
  146                         ifattr = d->ifattr;
  147                 } else
  148                         ifattr = 0;
  149 
  150                 if (d->numlocators) {
  151                         if (d->numlocators > MAXLOCATORS)
  152                                 return (EINVAL);
  153                         locs = malloc(d->numlocators * sizeof(int), M_DEVBUF,
  154                                       M_WAITOK);
  155                         res = copyin(d->locators, locs,
  156                                      d->numlocators * sizeof(int));
  157                         if (res)
  158                                 return (res);
  159                 } else
  160                         locs = 0;
  161                 res = rescanbus(d->busname, ifattr, d->numlocators, locs);
  162                 if (locs)
  163                         free(locs, M_DEVBUF);
  164 #undef d
  165                         break;
  166                 default:
  167                         return (EPASSTHROUGH);
  168         }
  169         return (res);
  170 }
  171 
  172 void
  173 drvctlattach(int arg)
  174 {
  175 }

Cache object: 828861f0429e86d9b34f7e7f22b0969a


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