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/arch/amiga/dev/atzsc.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: atzsc.c,v 1.45 2021/08/07 16:18:41 thorpej Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1982, 1990 The Regents of the University of California.
    5  * 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. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)dma.c
   32  */
   33 
   34 /*
   35  * Copyright (c) 1994 Christian E. Hopps
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. All advertising materials mentioning features or use of this software
   46  *    must display the following acknowledgement:
   47  *      This product includes software developed by the University of
   48  *      California, Berkeley and its contributors.
   49  * 4. Neither the name of the University nor the names of its contributors
   50  *    may be used to endorse or promote products derived from this software
   51  *    without specific prior written permission.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   63  * SUCH DAMAGE.
   64  *
   65  *      @(#)dma.c
   66  */
   67 
   68 #include <sys/cdefs.h>
   69 __KERNEL_RCSID(0, "$NetBSD: atzsc.c,v 1.45 2021/08/07 16:18:41 thorpej Exp $");
   70 
   71 #include <sys/param.h>
   72 #include <sys/systm.h>
   73 #include <sys/kernel.h>
   74 #include <sys/device.h>
   75 #include <sys/intr.h>
   76 #include <machine/cpu.h>
   77 #include <dev/scsipi/scsi_all.h>
   78 #include <dev/scsipi/scsipi_all.h>
   79 #include <dev/scsipi/scsiconf.h>
   80 #include <amiga/amiga/custom.h>
   81 #include <amiga/amiga/cc.h>
   82 #include <amiga/amiga/device.h>
   83 #include <amiga/amiga/isr.h>
   84 #include <amiga/dev/dmavar.h>
   85 #include <amiga/dev/sbicreg.h>
   86 #include <amiga/dev/sbicvar.h>
   87 #include <amiga/dev/atzscreg.h>
   88 #include <amiga/dev/zbusvar.h>
   89 
   90 void atzscattach(device_t, device_t, void *);
   91 int atzscmatch(device_t, cfdata_t, void *);
   92 
   93 void atzsc_enintr(struct sbic_softc *);
   94 void atzsc_dmastop(struct sbic_softc *);
   95 int atzsc_dmanext(struct sbic_softc *);
   96 int atzsc_dmaintr(void *);
   97 int atzsc_dmago(struct sbic_softc *, char *, int, int);
   98 
   99 #ifdef DEBUG
  100 void atzsc_dump(void);
  101 #endif
  102 
  103 #ifdef DEBUG
  104 int     atzsc_dmadebug = 0;
  105 #endif
  106 
  107 CFATTACH_DECL_NEW(atzsc, sizeof(struct sbic_softc),
  108     atzscmatch, atzscattach, NULL, NULL);
  109 
  110 /*
  111  * if we are a A2091 SCSI
  112  */
  113 int
  114 atzscmatch(device_t parent, cfdata_t cf, void *aux)
  115 {
  116         struct zbus_args *zap;
  117 
  118         zap = aux;
  119 
  120         /*
  121          * Check manufacturer and product id.
  122          * I was informed that older boards can be 2 also.
  123          */
  124         if (zap->manid == 514 && (zap->prodid == 3 || zap->prodid == 2))
  125                 return(1);
  126         else
  127                 return(0);
  128 }
  129 
  130 void
  131 atzscattach(device_t parent, device_t self, void *aux)
  132 {
  133         volatile struct sdmac *rp;
  134         struct sbic_softc *sc = device_private(self);
  135         struct zbus_args *zap;
  136         struct scsipi_adapter *adapt = &sc->sc_adapter;
  137         struct scsipi_channel *chan = &sc->sc_channel;
  138 
  139         zap = aux;
  140 
  141         sc->sc_dev = self;
  142         sc->sc_cregs = rp = zap->va;
  143         /*
  144          * disable ints and reset bank register
  145          */
  146         rp->CNTR = CNTR_PDMD;
  147         amiga_membarrier();
  148         rp->DAWR = DAWR_ATZSC;
  149         amiga_membarrier();
  150         sc->sc_enintr = atzsc_enintr;
  151         sc->sc_dmago = atzsc_dmago;
  152         sc->sc_dmanext = atzsc_dmanext;
  153         sc->sc_dmastop = atzsc_dmastop;
  154         sc->sc_dmacmd = 0;
  155 
  156         /*
  157          * only 24 bit mem.
  158          */
  159         sc->sc_flags |= SBICF_BADDMA;
  160         sc->sc_dmamask = ~0x00ffffff;
  161 #if 0
  162         /*
  163          * If the users kva space is not ztwo try and allocate a bounce buffer.
  164          * XXX this needs to change if we move to multiple memory segments.
  165          */
  166         if (kvtop(sc) & sc->sc_dmamask) {
  167                 sc->sc_dmabuffer = (char *)alloc_z2mem(MAXPHYS * 8); /* XXX */
  168                 if (isztwomem(sc->sc_dmabuffer))
  169                         printf(" bounce pa 0x%x", kvtop(sc->sc_dmabuffer));
  170                 else if (sc->sc_dmabuffer)
  171                         printf(" bounce pa 0x%x",
  172                             PREP_DMA_MEM(sc->sc_dmabuffer));
  173         }
  174 #endif
  175         sc->sc_sbic.sbic_asr_p = (volatile unsigned char *)rp + 0x91;
  176         sc->sc_sbic.sbic_value_p = (volatile unsigned char *)rp + 0x93;
  177 
  178         sc->sc_clkfreq = sbic_clock_override ? sbic_clock_override : 77;
  179 
  180         printf(": dmamask 0x%lx\n", ~sc->sc_dmamask);
  181 
  182         /*
  183          * Fill in the scsipi_adapter.
  184          */
  185         memset(adapt, 0, sizeof(*adapt));
  186         adapt->adapt_dev = self;
  187         adapt->adapt_nchannels = 1;
  188         adapt->adapt_openings = 7;
  189         adapt->adapt_max_periph = 1;
  190         adapt->adapt_request = sbic_scsipi_request;
  191         adapt->adapt_minphys = sbic_minphys;
  192 
  193         /*
  194          * Fill in the scsipi_channel.
  195          */
  196         memset(chan, 0, sizeof(*chan));
  197         chan->chan_adapter = adapt;
  198         chan->chan_bustype = &scsi_bustype;
  199         chan->chan_channel = 0;
  200         chan->chan_ntargets = 8;
  201         chan->chan_nluns = 8;
  202         chan->chan_id = 7;
  203 
  204         sbicinit(sc);
  205 
  206         sc->sc_isr.isr_intr = atzsc_dmaintr;
  207         sc->sc_isr.isr_arg = sc;
  208         sc->sc_isr.isr_ipl = 2;
  209         add_isr (&sc->sc_isr);
  210 
  211         /*
  212          * attach all scsi units on us
  213          */
  214         config_found(self, chan, scsiprint, CFARGS_NONE);
  215 }
  216 
  217 void
  218 atzsc_enintr(struct sbic_softc *dev)
  219 {
  220         volatile struct sdmac *sdp;
  221 
  222         sdp = dev->sc_cregs;
  223 
  224         dev->sc_flags |= SBICF_INTR;
  225         sdp->CNTR = CNTR_PDMD | CNTR_INTEN;
  226         amiga_membarrier();
  227 }
  228 
  229 int
  230 atzsc_dmago(struct sbic_softc *dev, char *addr, int count, int flags)
  231 {
  232         volatile struct sdmac *sdp;
  233 
  234         sdp = dev->sc_cregs;
  235         /*
  236          * Set up the command word based on flags
  237          */
  238         dev->sc_dmacmd = CNTR_PDMD | CNTR_INTEN;
  239         if ((flags & DMAGO_READ) == 0)
  240                 dev->sc_dmacmd |= CNTR_DDIR;
  241 #ifdef DEBUG
  242         if (atzsc_dmadebug & DDB_IO)
  243                 printf("atzsc_dmago: cmd %x\n", dev->sc_dmacmd);
  244 #endif
  245 
  246         dev->sc_flags |= SBICF_INTR;
  247         sdp->CNTR = dev->sc_dmacmd;
  248         amiga_membarrier();
  249         sdp->ACR = (u_int) dev->sc_cur->dc_addr;
  250         amiga_membarrier();
  251         sdp->ST_DMA = 1;
  252         amiga_membarrier();
  253 
  254         return(dev->sc_tcnt);
  255 }
  256 
  257 void
  258 atzsc_dmastop(struct sbic_softc *dev)
  259 {
  260         volatile struct sdmac *sdp;
  261         int s;
  262         vu_short istr;
  263 
  264         sdp = dev->sc_cregs;
  265 
  266 #ifdef DEBUG
  267         if (atzsc_dmadebug & DDB_FOLLOW)
  268                 printf("atzsc_dmastop()\n");
  269 #endif
  270         if (dev->sc_dmacmd) {
  271                 s = splbio();
  272                 if ((dev->sc_dmacmd & (CNTR_TCEN | CNTR_DDIR)) == 0) {
  273                         /*
  274                          * only FLUSH if terminal count not enabled,
  275                          * and reading from peripheral
  276                          */
  277                         sdp->FLUSH = 1;
  278                         amiga_membarrier();
  279                         do {
  280                                 istr = sdp->ISTR;
  281                                 amiga_membarrier();
  282                         } while ((istr & ISTR_FE_FLG) == 0);
  283                 }
  284                 /*
  285                  * clear possible interrupt and stop DMA
  286                  */
  287                 sdp->CINT = 1;
  288                 amiga_membarrier();
  289                 sdp->SP_DMA = 1;
  290                 amiga_membarrier();
  291                 dev->sc_dmacmd = 0;
  292                 splx(s);
  293         }
  294 }
  295 
  296 int
  297 atzsc_dmaintr(void *arg)
  298 {
  299         struct sbic_softc *dev = arg;
  300         volatile struct sdmac *sdp;
  301         int stat, found;
  302 
  303         sdp = dev->sc_cregs;
  304         stat = sdp->ISTR;
  305 
  306         if ((stat & (ISTR_INT_F|ISTR_INT_P)) == 0)
  307                 return (0);
  308 
  309 #ifdef DEBUG
  310         if (atzsc_dmadebug & DDB_FOLLOW)
  311                 printf("%s: dmaintr 0x%x\n", device_xname(dev->sc_dev), stat);
  312 #endif
  313 
  314         /*
  315          * both, SCSI and DMA interrupts arrive here. I chose
  316          * arbitrarily that DMA interrupts should have higher
  317          * precedence than SCSI interrupts.
  318          */
  319         found = 0;
  320         if (stat & ISTR_E_INT) {
  321                 found++;
  322 
  323                 sdp->CINT = 1;  /* clear possible interrupt */
  324                 amiga_membarrier();
  325 
  326                 /*
  327                  * check for SCSI ints in the same go and
  328                  * eventually save an interrupt
  329                  */
  330         }
  331 
  332         if (dev->sc_flags & SBICF_INTR && stat & ISTR_INTS)
  333                 found += sbicintr(dev);
  334         return(found);
  335 }
  336 
  337 
  338 int
  339 atzsc_dmanext(struct sbic_softc *dev)
  340 {
  341         volatile struct sdmac *sdp;
  342         vu_short istr;
  343 
  344         sdp = dev->sc_cregs;
  345 
  346         if (dev->sc_cur > dev->sc_last) {
  347                 /* shouldn't happen !! */
  348                 printf("atzsc_dmanext at end !!!\n");
  349                 atzsc_dmastop(dev);
  350                 return(0);
  351         }
  352         if ((dev->sc_dmacmd & (CNTR_TCEN | CNTR_DDIR)) == 0) {
  353                   /*
  354                    * only FLUSH if terminal count not enabled,
  355                    * and reading from peripheral
  356                    */
  357                 sdp->FLUSH = 1;
  358                 amiga_membarrier();
  359                 do {
  360                         istr = sdp->ISTR;
  361                         amiga_membarrier();
  362                 } while ((istr & ISTR_FE_FLG) == 0);
  363         }
  364         /*
  365          * clear possible interrupt and stop DMA
  366          */
  367         sdp->CINT = 1;  /* clear possible interrupt */
  368         amiga_membarrier();
  369         sdp->SP_DMA = 1;        /* stop DMA */
  370         amiga_membarrier();
  371         sdp->CNTR = dev->sc_dmacmd;
  372         amiga_membarrier();
  373         sdp->ACR = (u_int)dev->sc_cur->dc_addr;
  374         amiga_membarrier();
  375         sdp->ST_DMA = 1;
  376         amiga_membarrier();
  377 
  378         dev->sc_tcnt = dev->sc_cur->dc_count << 1;
  379         return(dev->sc_tcnt);
  380 }
  381 
  382 #ifdef DEBUG
  383 void
  384 atzsc_dump(void)
  385 {
  386         extern struct cfdriver atzsc_cd;
  387         struct sbic_softc *sc;
  388         int i;
  389 
  390         for (i = 0; i < atzsc_cd.cd_ndevs; ++i) {
  391                 sc = device_lookup_private(&atzsc_cd, i);
  392                 if (sc != NULL)
  393                         sbic_dump(sc);
  394         }
  395 }
  396 #endif

Cache object: 1569c7228cd00c01b45dc2a4f748b234


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