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/vme/vme.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: vme.c,v 1.10 2003/01/01 00:10:27 thorpej Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1999
    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  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  *
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __KERNEL_RCSID(0, "$NetBSD: vme.c,v 1.10 2003/01/01 00:10:27 thorpej Exp $");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/device.h>
   37 #include <sys/malloc.h>
   38 #include <sys/extent.h>
   39 #include <machine/bus.h>
   40 
   41 #include <dev/vme/vmereg.h>
   42 #include <dev/vme/vmevar.h>
   43 
   44 static void vme_extractlocators __P((int*, struct vme_attach_args*));
   45 static int vmeprint __P((struct vme_attach_args*, char*));
   46 static int vmesubmatch1 __P((struct device*, struct cfdata*, void*));
   47 static int vmesubmatch __P((struct device*, struct cfdata*, void*));
   48 int vmematch __P((struct device *, struct cfdata *, void *));
   49 void vmeattach __P((struct device*, struct device*,void*));
   50 static struct extent *vme_select_map __P((struct vmebus_softc*, vme_am_t));
   51 
   52 #ifdef notyet
   53 int vmedetach __P((struct device*));
   54 #endif
   55 
   56 #define VME_SLAVE_DUMMYDRV "vme_slv"
   57 
   58 #define VME_NUMCFRANGES 3 /* cf. "files.vme" */
   59 
   60 CFATTACH_DECL(vme, sizeof(struct vmebus_softc),
   61     vmematch, vmeattach, NULL, NULL);
   62 
   63 const struct cfattach vme_slv_ca = {
   64         0       /* never used */
   65 };
   66 
   67 static void
   68 vme_extractlocators(loc, aa)
   69         int *loc;
   70         struct vme_attach_args *aa;
   71 {
   72         int i = 0;
   73 
   74         /* XXX can't use constants in locators.h this way */
   75 
   76         while (i < VME_NUMCFRANGES && i < VME_MAXCFRANGES &&
   77                loc[i] != -1) {
   78                 aa->r[i].offset = (vme_addr_t)loc[i];
   79                 aa->r[i].size = (vme_size_t)loc[3 + i];
   80                 aa->r[i].am = (vme_am_t)loc[6 + i];
   81                 i++;
   82         }
   83         aa->numcfranges = i;
   84         aa->ilevel = loc[9];
   85         aa->ivector = loc[10];
   86 }
   87 
   88 static int
   89 vmeprint(v, dummy)
   90         struct vme_attach_args *v;
   91         char *dummy;
   92 {
   93         int i;
   94 
   95         for (i = 0; i < v->numcfranges; i++) {
   96                 aprint_normal(" addr %x", v->r[i].offset);
   97                 if (v->r[i].size != -1)
   98                         aprint_normal("-%x", v->r[i].offset + v->r[i].size - 1);
   99                 if (v->r[i].am != -1)
  100                         aprint_normal(" am %02x", v->r[i].am);
  101         }
  102         if (v->ilevel != -1) {
  103                 aprint_normal(" irq %d", v->ilevel);
  104                 if (v->ivector != -1)
  105                         aprint_normal(" vector %x", v->ivector);
  106         }
  107         return (UNCONF);
  108 }
  109 
  110 /*
  111  * This looks for a (dummy) vme device "VME_SLAVE_DUMMYDRV".
  112  * A callback provided by the bus's parent is called for every such
  113  * entry in the config database.
  114  * This is a special hack allowing to communicate the address settings
  115  * of the VME master's slave side to its driver via the normal
  116  * configuration mechanism.
  117  * Needed in following cases:
  118  *  -DMA windows are hardware settable but not readable by software
  119  *   (driver gets offsets for DMA address calculations this way)
  120  *  -DMA windows are software settable, but not persistent
  121  *   (hardware is set up from config file entry)
  122  *  -other adapter VME slave ranges which should be kept track of
  123  *   for address space accounting
  124  * In any case, the adapter driver must get the data before VME
  125  * devices are attached.
  126  */
  127 static int
  128 vmesubmatch1(bus, dev, aux)
  129         struct device *bus;
  130         struct cfdata *dev;
  131         void *aux;
  132 {
  133         struct vmebus_softc *sc = (struct vmebus_softc*)bus;
  134         struct vme_attach_args v;
  135 
  136         if (strcmp(dev->cf_name, VME_SLAVE_DUMMYDRV))
  137                 return (0);
  138 
  139         vme_extractlocators(dev->cf_loc, &v);
  140 
  141         v.va_vct = sc->sc_vct; /* for space allocation */
  142 
  143         (*sc->slaveconfig)(bus->dv_parent, &v);
  144         return (0);
  145 }
  146 
  147 static int
  148 vmesubmatch(bus, dev, aux)
  149         struct device *bus;
  150         struct cfdata *dev;
  151         void *aux;
  152 {
  153         struct vmebus_softc *sc = (struct vmebus_softc*)bus;
  154         struct vme_attach_args v;
  155 
  156         if (!strcmp(dev->cf_name, VME_SLAVE_DUMMYDRV))
  157                 return (0);
  158 
  159         vme_extractlocators(dev->cf_loc, &v);
  160 
  161         v.va_vct = sc->sc_vct;
  162         v.va_bdt = sc->sc_bdt;
  163 
  164         if (config_match(bus, dev, &v)) {
  165                 config_attach(bus, dev, &v, (cfprint_t)vmeprint);
  166                 return (1);
  167         }
  168         return (0);
  169 }
  170 
  171 int
  172 vmematch(parent, match, aux)
  173         struct device *parent;
  174         struct cfdata *match;
  175         void *aux;
  176 {
  177         return (1);
  178 }
  179 
  180 void
  181 vmeattach(parent, self, aux)
  182         struct device *parent, *self;
  183         void *aux;
  184 {
  185         struct vmebus_softc *sc = (struct vmebus_softc *)self;
  186 
  187         struct vmebus_attach_args *aa =
  188             (struct vmebus_attach_args*)aux;
  189 
  190         sc->sc_vct = aa->va_vct;
  191         sc->sc_bdt = aa->va_bdt;
  192 
  193         /* the "bus" are we ourselves */
  194         sc->sc_vct->bus = sc;
  195 
  196         sc->slaveconfig = aa->va_slaveconfig;
  197 
  198         printf("\n");
  199 
  200         /*
  201          * set up address space accounting - assume incomplete decoding
  202          */
  203         sc->vme32ext = extent_create("vme32", 0, 0xffffffff,
  204                                      M_DEVBUF, 0, 0, 0);
  205         if (!sc->vme32ext) {
  206                 printf("error creating A32 map\n");
  207                 return;
  208         }
  209 
  210         sc->vme24ext = extent_create("vme24", 0, 0x00ffffff,
  211                                      M_DEVBUF, 0, 0, 0);
  212         if (!sc->vme24ext) {
  213                 printf("error creating A24 map\n");
  214                 return;
  215         }
  216 
  217         sc->vme16ext = extent_create("vme16", 0, 0x0000ffff,
  218                                      M_DEVBUF, 0, 0, 0);
  219         if (!sc->vme16ext) {
  220                 printf("error creating A16 map\n");
  221                 return;
  222         }
  223 
  224         if (sc->slaveconfig) {
  225                 /* first get info about the bus master's slave side,
  226                  if present */
  227                 config_search((cfmatch_t)vmesubmatch1, self, 0);
  228         }
  229         config_search((cfmatch_t)vmesubmatch, self, 0);
  230 
  231 #ifdef VMEDEBUG
  232         if (sc->vme32ext)
  233                 extent_print(sc->vme32ext);
  234         if (sc->vme24ext)
  235                 extent_print(sc->vme24ext);
  236         if (sc->vme16ext)
  237                 extent_print(sc->vme16ext);
  238 #endif
  239 }
  240 
  241 #ifdef notyet
  242 int
  243 vmedetach(dev)
  244         struct device *dev;
  245 {
  246         struct vmebus_softc *sc = (struct vmebus_softc*)dev;
  247 
  248         if (sc->slaveconfig) {
  249                 /* allow bus master to free its bus ressources */
  250                 (*sc->slaveconfig)(dev->dv_parent, 0);
  251         }
  252 
  253         /* extent maps should be empty now */
  254 
  255         if (sc->vme32ext) {
  256 #ifdef VMEDEBUG
  257                 extent_print(sc->vme32ext);
  258 #endif
  259                 extent_destroy(sc->vme32ext);
  260         }
  261         if (sc->vme24ext) {
  262 #ifdef VMEDEBUG
  263                 extent_print(sc->vme24ext);
  264 #endif
  265                 extent_destroy(sc->vme24ext);
  266         }
  267         if (sc->vme16ext) {
  268 #ifdef VMEDEBUG
  269                 extent_print(sc->vme16ext);
  270 #endif
  271                 extent_destroy(sc->vme16ext);
  272         }
  273 
  274         return (0);
  275 }
  276 #endif
  277 
  278 static struct extent *
  279 vme_select_map(sc, ams)
  280         struct vmebus_softc *sc;
  281         vme_am_t ams;
  282 {
  283         if ((ams & VME_AM_ADRSIZEMASK) == VME_AM_A32)
  284                 return (sc->vme32ext);
  285         else if ((ams & VME_AM_ADRSIZEMASK) == VME_AM_A24)
  286                 return (sc->vme24ext);
  287         else if ((ams & VME_AM_ADRSIZEMASK) == VME_AM_A16)
  288                 return (sc->vme16ext);
  289         else
  290                 return (0);
  291 }
  292 
  293 int
  294 _vme_space_alloc(sc, addr, len, ams)
  295         struct vmebus_softc *sc;
  296         vme_addr_t addr;
  297         vme_size_t len;
  298         vme_am_t ams;
  299 {
  300         struct extent *ex;
  301 
  302         ex = vme_select_map(sc, ams);
  303         if (!ex)
  304                 return (EINVAL);
  305 
  306         return (extent_alloc_region(ex, addr, len, EX_NOWAIT));
  307 }
  308 
  309 void
  310 _vme_space_free(sc, addr, len, ams)
  311         struct vmebus_softc *sc;
  312         vme_addr_t addr;
  313         vme_size_t len;
  314         vme_am_t ams;
  315 {
  316         struct extent *ex;
  317 
  318         ex = vme_select_map(sc, ams);
  319         if (!ex) {
  320                 panic("vme_space_free: invalid am %x", ams);
  321                 return;
  322         }
  323 
  324         extent_free(ex, addr, len, EX_NOWAIT);
  325 }
  326 
  327 int
  328 _vme_space_get(sc, len, ams, align, addr)
  329         struct vmebus_softc *sc;
  330         vme_size_t len;
  331         vme_am_t ams;
  332         u_long align;
  333         vme_addr_t *addr;
  334 {
  335         struct extent *ex;
  336 
  337         ex = vme_select_map(sc, ams);
  338         if (!ex)
  339                 return (EINVAL);
  340 
  341         return (extent_alloc(ex, len, align, EX_NOBOUNDARY, EX_NOWAIT,
  342                              (u_long *)addr));
  343 }

Cache object: 86407a8d036ccec3aad5860683ca0519


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