root/dev/sbus/dma_sbus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dmaprint_sbus
  2. dmamatch_sbus
  3. dmaattach_sbus
  4. dmabus_intr_establish
  5. dma_alloc_bustag

    1 /*      $OpenBSD: dma_sbus.c,v 1.13 2006/06/02 20:00:56 miod Exp $      */
    2 /*      $NetBSD: dma_sbus.c,v 1.5 2000/07/09 20:57:42 pk Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Paul Kranenburg.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Copyright (c) 1994 Peter Galbavy.  All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  *
   52  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   53  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   54  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   55  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   56  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   57  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   58  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   59  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   60  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   61  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   62  */
   63 
   64 #include <sys/types.h>
   65 #include <sys/param.h>
   66 #include <sys/systm.h>
   67 #include <sys/kernel.h>
   68 #include <sys/errno.h>
   69 #include <sys/device.h>
   70 #include <sys/malloc.h>
   71 
   72 #include <machine/bus.h>
   73 #include <machine/intr.h>
   74 #include <machine/autoconf.h>
   75 
   76 #include <dev/sbus/sbusvar.h>
   77 
   78 #include <dev/ic/lsi64854reg.h>
   79 #include <dev/ic/lsi64854var.h>
   80 
   81 #include <scsi/scsi_all.h>
   82 #include <scsi/scsiconf.h>
   83 
   84 #include <dev/ic/ncr53c9xreg.h>
   85 #include <dev/ic/ncr53c9xvar.h>
   86 
   87 struct dma_softc {
   88         struct lsi64854_softc   sc_lsi64854;    /* base device */
   89 };
   90 
   91 int     dmamatch_sbus(struct device *, void *, void *);
   92 void    dmaattach_sbus(struct device *, struct device *, void *);
   93 
   94 int     dmaprint_sbus(void *, const char *);
   95 
   96 void    *dmabus_intr_establish(
   97                 bus_space_tag_t,
   98                 bus_space_tag_t,
   99                 int,                    /*bus interrupt priority*/
  100                 int,                    /*`device class' level*/
  101                 int,                    /*flags*/
  102                 int (*)(void *),        /*handler*/
  103                 void *,                 /*handler arg*/
  104                 const char *);          /*what*/
  105 
  106 static  bus_space_tag_t dma_alloc_bustag(struct dma_softc *sc);
  107 
  108 struct cfattach dma_sbus_ca = {
  109         sizeof(struct dma_softc), dmamatch_sbus, dmaattach_sbus
  110 };
  111 
  112 struct cfattach ledma_ca = {
  113         sizeof(struct dma_softc), dmamatch_sbus, dmaattach_sbus
  114 };
  115 
  116 struct cfdriver ledma_cd = {
  117         NULL, "ledma", DV_DULL
  118 };
  119 
  120 struct cfdriver dma_cd = {
  121         NULL, "dma", DV_DULL
  122 };
  123 
  124 int
  125 dmaprint_sbus(void *aux, const char *busname)
  126 {
  127         struct sbus_attach_args *sa = aux;
  128         bus_space_tag_t t = sa->sa_bustag;
  129         struct dma_softc *sc = t->cookie;
  130 
  131         sa->sa_bustag = sc->sc_lsi64854.sc_bustag;      /* XXX */
  132         sbus_print(aux, busname);       /* XXX */
  133         sa->sa_bustag = t;              /* XXX */
  134         return (UNCONF);
  135 }
  136 
  137 int
  138 dmamatch_sbus(struct device *parent, void *vcf, void *aux)
  139 {
  140         struct cfdata *cf = vcf;
  141         struct sbus_attach_args *sa = aux;
  142 
  143         return (strcmp(cf->cf_driver->cd_name, sa->sa_name) == 0 ||
  144                 strcmp("espdma", sa->sa_name) == 0);
  145 }
  146 
  147 void
  148 dmaattach_sbus(parent, self, aux)
  149         struct device *parent, *self;
  150         void *aux;
  151 {
  152         struct sbus_attach_args *sa = aux;
  153         struct dma_softc *dsc = (void *)self;
  154         struct lsi64854_softc *sc = &dsc->sc_lsi64854;
  155         bus_space_handle_t bh;
  156         bus_space_tag_t sbt;
  157         int sbusburst, burst;
  158         int node;
  159 
  160         node = sa->sa_node;
  161 
  162         sc->sc_bustag = sa->sa_bustag;
  163         sc->sc_dmatag = sa->sa_dmatag;
  164 
  165         /* Map registers */
  166         if (sa->sa_npromvaddrs != 0) {
  167                 if (sbus_bus_map(sa->sa_bustag, 0, 
  168                     sa->sa_promvaddrs[0],
  169                     sa->sa_size,                /* ???? */
  170                     BUS_SPACE_MAP_PROMADDRESS,
  171                     0, &bh) != 0) {
  172                         printf("%s: cannot map registers\n", self->dv_xname);
  173                         return;
  174                 }
  175         } else if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
  176             sa->sa_offset,
  177             sa->sa_size,
  178             0, 0, &bh) != 0) {
  179                 printf("%s: cannot map registers\n", self->dv_xname);
  180                 return;
  181         }
  182         sc->sc_regs = bh;
  183 
  184         /*
  185          * Get transfer burst size from PROM and plug it into the
  186          * controller registers. This is needed on the Sun4m; do
  187          * others need it too?
  188          */
  189         sbusburst = ((struct sbus_softc *)parent)->sc_burst;
  190         if (sbusburst == 0)
  191                 sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
  192 
  193         burst = getpropint(node,"burst-sizes", -1);
  194         if (burst == -1)
  195                 /* take SBus burst sizes */
  196                 burst = sbusburst;
  197 
  198         /* Clamp at parent's burst sizes */
  199         burst &= sbusburst;
  200         sc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
  201                        (burst & SBUS_BURST_16) ? 16 : 0;
  202 
  203         if (sc->sc_dev.dv_cfdata->cf_attach == &ledma_ca) {
  204                 char *cabletype;
  205                 u_int32_t csr;
  206                 /*
  207                  * Check to see which cable type is currently active and
  208                  * set the appropriate bit in the ledma csr so that it
  209                  * gets used. If we didn't netboot, the PROM won't have
  210                  * the "cable-selection" property; default to TP and then
  211                  * the user can change it via a "media" option to ifconfig.
  212                  */
  213                 cabletype = getpropstring(node, "cable-selection");
  214                 csr = L64854_GCSR(sc);
  215                 if (strcmp(cabletype, "tpe") == 0) {
  216                         csr |= E_TP_AUI;
  217                 } else if (strcmp(cabletype, "aui") == 0) {
  218                         csr &= ~E_TP_AUI;
  219                 } else {
  220                         /* assume TP if nothing there */
  221                         csr |= E_TP_AUI;
  222                 }
  223                 L64854_SCSR(sc, csr);
  224                 delay(20000);   /* manual says we need a 20ms delay */
  225                 sc->sc_channel = L64854_CHANNEL_ENET;
  226         } else {
  227                 sc->sc_channel = L64854_CHANNEL_SCSI;
  228         }
  229 
  230         sbt = dma_alloc_bustag(dsc);
  231         if (lsi64854_attach(sc) != 0)
  232                 return;
  233 
  234         /* Attach children */
  235         for (node = firstchild(sa->sa_node); node; node = nextsibling(node)) {
  236                 struct sbus_attach_args sa;
  237                 sbus_setup_attach_args((struct sbus_softc *)parent,
  238                                        sbt, sc->sc_dmatag, node, &sa);
  239                 (void) config_found(&sc->sc_dev, (void *)&sa, dmaprint_sbus);
  240                 sbus_destroy_attach_args(&sa);
  241         }
  242 }
  243 
  244 void *
  245 dmabus_intr_establish(
  246         bus_space_tag_t t,
  247         bus_space_tag_t t0,
  248         int pri,
  249         int level,
  250         int flags,
  251         int (*handler)(void *),
  252         void *arg,
  253         const char *what)
  254 {
  255         struct lsi64854_softc *sc = t->cookie;
  256 
  257         /* XXX - for now only le; do esp later */
  258         if (sc->sc_channel == L64854_CHANNEL_ENET) {
  259                 sc->sc_intrchain = handler;
  260                 sc->sc_intrchainarg = arg;
  261                 handler = lsi64854_enet_intr;
  262                 arg = sc;
  263         }
  264 
  265         for (t = t->parent; t; t = t->parent) {
  266                 if (t->sparc_intr_establish != NULL)
  267                         return ((*t->sparc_intr_establish)
  268                                 (t, t0, pri, level, flags, handler, arg, what));
  269 
  270         }
  271 
  272         panic("dmabus_intr_establish: no handler found");
  273 
  274         return (NULL);
  275 }
  276 
  277 bus_space_tag_t
  278 dma_alloc_bustag(struct dma_softc *sc)
  279 {
  280         struct sparc_bus_space_tag *sbt;
  281 
  282         sbt = malloc(sizeof(*sbt), M_DEVBUF, M_NOWAIT);
  283         if (sbt == NULL)
  284                 return (NULL);
  285 
  286         bzero(sbt, sizeof *sbt);
  287         sbt->cookie = sc;
  288         sbt->parent = sc->sc_lsi64854.sc_bustag;
  289         sbt->asi = sbt->parent->asi;
  290         sbt->sasi = sbt->parent->sasi;
  291         sbt->sparc_intr_establish = dmabus_intr_establish;
  292         return (sbt);
  293 }

/* [<][>][^][v][top][bottom][index][help] */