root/dev/tc/asc_tc.c

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

DEFINITIONS

This source file includes following definitions.
  1. asc_tc_match
  2. asc_tc_attach
  3. asc_tc_reset
  4. asc_tc_intr
  5. asc_tc_setup
  6. asc_tc_go
  7. asc_tc_stop
  8. asc_dma_isintr
  9. asc_dma_isactive
  10. asc_clear_latched_intr

    1 /* $OpenBSD: asc_tc.c,v 1.7 2003/02/11 19:20:28 mickey Exp $ */
    2 /* $NetBSD: asc_tc.c,v 1.19 2001/11/15 09:48:19 lukem Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Tohru Nishimura.
   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 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/device.h>
   43 #include <sys/buf.h>
   44 
   45 #include <scsi/scsi_all.h>
   46 #include <scsi/scsiconf.h>
   47 #include <scsi/scsi_message.h>
   48 
   49 #include <machine/bus.h>
   50 
   51 #include <dev/ic/ncr53c9xreg.h>
   52 #include <dev/ic/ncr53c9xvar.h>
   53 #include <dev/tc/ascvar.h>
   54 
   55 #include <dev/tc/tcvar.h>
   56 
   57 struct asc_tc_softc {
   58         struct asc_softc asc;
   59 
   60         /* XXX XXX XXX */
   61         caddr_t sc_base, sc_bounce, sc_target;
   62 };
   63 
   64 int  asc_tc_match(struct device *, void *, void *);
   65 void asc_tc_attach(struct device *, struct device *, void *);
   66 
   67 struct cfattach asc_tc_ca = {
   68         sizeof(struct asc_tc_softc), asc_tc_match, asc_tc_attach
   69 };
   70 
   71 extern struct scsi_adapter asc_switch;
   72 extern struct scsi_device asc_dev;
   73 
   74 int     asc_dma_isintr(struct ncr53c9x_softc *);
   75 void    asc_tc_reset(struct ncr53c9x_softc *);
   76 int     asc_tc_intr(struct ncr53c9x_softc *);
   77 int     asc_tc_setup(struct ncr53c9x_softc *, caddr_t *,
   78                                                 size_t *, int, size_t *);
   79 void    asc_tc_go(struct ncr53c9x_softc *);
   80 void    asc_tc_stop(struct ncr53c9x_softc *);
   81 int     asc_dma_isactive(struct ncr53c9x_softc *);
   82 void    asc_clear_latched_intr(struct ncr53c9x_softc *);
   83 
   84 struct ncr53c9x_glue asc_tc_glue = {
   85         asc_read_reg,
   86         asc_write_reg,
   87         asc_dma_isintr,
   88         asc_tc_reset,
   89         asc_tc_intr,
   90         asc_tc_setup,
   91         asc_tc_go,
   92         asc_tc_stop,
   93         asc_dma_isactive,
   94         asc_clear_latched_intr,
   95 };
   96 
   97 /*
   98  * Parameters specific to PMAZ-A TC option card.
   99  */
  100 #define PMAZ_OFFSET_53C94       0x0             /* from module base */
  101 #define PMAZ_OFFSET_DMAR        0x40000         /* DMA Address Register */
  102 #define PMAZ_OFFSET_RAM         0x80000         /* 128KB SRAM buffer */
  103 #define PMAZ_OFFSET_ROM         0xc0000         /* diagnostic ROM */
  104 
  105 #define PMAZ_RAM_SIZE           0x20000         /* 128k (32k*32) */
  106 #define PER_TGT_DMA_SIZE        ((PMAZ_RAM_SIZE/7) & ~(sizeof(int)-1))
  107 
  108 #define PMAZ_DMAR_WRITE         0x80000000      /* DMA direction bit */
  109 #define PMAZ_DMAR_MASK          0x1ffff         /* 17 bits, 128k */
  110 #define PMAZ_DMA_ADDR(x)        ((unsigned long)(x) & PMAZ_DMAR_MASK)
  111 
  112 int
  113 asc_tc_match(parent, cfdata, aux)
  114         struct device *parent;
  115         void *cfdata, *aux;
  116 {
  117         struct tc_attach_args *d = aux;
  118         
  119         if (strncmp("PMAZ-AA ", d->ta_modname, TC_ROM_LLEN))
  120                 return (0);
  121 
  122         return (1);
  123 }
  124 
  125 void
  126 asc_tc_attach(parent, self, aux)
  127         struct device *parent, *self;
  128         void *aux;
  129 {
  130         struct tc_attach_args *ta = aux;
  131         struct asc_tc_softc *asc = (struct asc_tc_softc *)self; 
  132         struct ncr53c9x_softc *sc = &asc->asc.sc_ncr53c9x;
  133 
  134         /*
  135          * Set up glue for MI code early; we use some of it here.
  136          */
  137         sc->sc_glue = &asc_tc_glue;
  138         asc->asc.sc_bst = ta->ta_memt;
  139         asc->asc.sc_dmat = ta->ta_dmat;
  140         if (bus_space_map(asc->asc.sc_bst, ta->ta_addr,
  141                 PMAZ_OFFSET_RAM + PMAZ_RAM_SIZE, 0, &asc->asc.sc_bsh)) {
  142                 printf("%s: unable to map device\n", sc->sc_dev.dv_xname);
  143                 return;
  144         }
  145         asc->sc_base = (caddr_t)ta->ta_addr;    /* XXX XXX XXX */
  146 
  147         tc_intr_establish(parent, ta->ta_cookie, IPL_BIO, ncr53c9x_intr, sc);
  148         
  149         sc->sc_id = 7;
  150         sc->sc_freq = (ta->ta_busspeed) ? 25000000 : 12500000;
  151 
  152         /* gimme MHz */
  153         sc->sc_freq /= 1000000;
  154 
  155         /*
  156          * XXX More of this should be in ncr53c9x_attach(), but
  157          * XXX should we really poke around the chip that much in
  158          * XXX the MI code?  Think about this more...
  159          */
  160 
  161         /*
  162          * Set up static configuration info.
  163          */
  164         sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
  165         sc->sc_cfg2 = NCRCFG2_SCSI2;
  166         sc->sc_cfg3 = 0;
  167         sc->sc_rev = NCR_VARIANT_NCR53C94;
  168 
  169         /*
  170          * XXX minsync and maxxfer _should_ be set up in MI code,
  171          * XXX but it appears to have some dependency on what sort
  172          * XXX of DMA we're hooked up to, etc.
  173          */
  174 
  175         /*
  176          * This is the value used to start sync negotiations
  177          * Note that the NCR register "SYNCTP" is programmed
  178          * in "clocks per byte", and has a minimum value of 4.
  179          * The SCSI period used in negotiation is one-fourth
  180          * of the time (in nanoseconds) needed to transfer one byte.
  181          * Since the chip's clock is given in MHz, we have the following
  182          * formula: 4 * period = (1000 / freq) * 4
  183          */
  184         sc->sc_minsync = (1000 / sc->sc_freq) * 5 / 4;
  185 
  186         sc->sc_maxxfer = 64 * 1024;
  187 
  188         /* Do the common parts of attachment. */
  189         ncr53c9x_attach(sc, &asc_switch, &asc_dev);
  190 }
  191 
  192 void
  193 asc_tc_reset(sc)
  194         struct ncr53c9x_softc *sc;
  195 {
  196         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  197 
  198         asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
  199 }
  200 
  201 int
  202 asc_tc_intr(sc)
  203         struct ncr53c9x_softc *sc;
  204 {
  205         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  206         int trans, resid;
  207 
  208         resid = 0;
  209         if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0 &&
  210             (resid = (NCR_READ_REG(sc, NCR_FFLAG) & NCRFIFO_FF)) != 0) {
  211                 NCR_DMA(("asc_tc_intr: empty FIFO of %d ", resid));
  212                 DELAY(1);
  213         }
  214 
  215         resid += NCR_READ_REG(sc, NCR_TCL);
  216         resid += NCR_READ_REG(sc, NCR_TCM) << 8;
  217 
  218         trans = asc->asc.sc_dmasize - resid;
  219 
  220         if (asc->asc.sc_flags & ASC_ISPULLUP)
  221                 memcpy(asc->sc_target, asc->sc_bounce, trans);
  222         *asc->asc.sc_dmalen -= trans;
  223         *asc->asc.sc_dmaaddr += trans;
  224         asc->asc.sc_flags &= ~(ASC_DMAACTIVE|ASC_MAPLOADED);
  225 
  226         return (0);
  227 }
  228 
  229 int
  230 asc_tc_setup(sc, addr, len, datain, dmasize)
  231         struct ncr53c9x_softc *sc;
  232         caddr_t *addr;
  233         size_t *len;
  234         int datain;
  235         size_t *dmasize;
  236 {
  237         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  238         u_int32_t tc_dmar;
  239         size_t size;
  240 
  241         asc->asc.sc_dmaaddr = addr;
  242         asc->asc.sc_dmalen = len;
  243         asc->asc.sc_flags = (datain) ? ASC_ISPULLUP : 0;
  244 
  245         NCR_DMA(("asc_tc_setup: start %ld@%p, %s\n", (long)*asc->asc.sc_dmalen,
  246                 *asc->asc.sc_dmaaddr, datain ? "IN" : "OUT"));
  247 
  248         size = *dmasize;
  249         if (size > PER_TGT_DMA_SIZE)
  250                 size = PER_TGT_DMA_SIZE;
  251         *dmasize = asc->asc.sc_dmasize = size;
  252 
  253         NCR_DMA(("asc_tc_setup: dmasize = %ld\n", (long)asc->asc.sc_dmasize));
  254 
  255         asc->sc_bounce = asc->sc_base + PMAZ_OFFSET_RAM;
  256         asc->sc_bounce += PER_TGT_DMA_SIZE *
  257             sc->sc_nexus->xs->sc_link->target;
  258         asc->sc_target = *addr;
  259 
  260         if ((asc->asc.sc_flags & ASC_ISPULLUP) == 0)
  261                 memcpy(asc->sc_bounce, asc->sc_target, size);
  262 
  263 #if 1
  264         if (asc->asc.sc_flags & ASC_ISPULLUP)
  265                 tc_dmar = PMAZ_DMA_ADDR(asc->sc_bounce);
  266         else
  267                 tc_dmar = PMAZ_DMAR_WRITE | PMAZ_DMA_ADDR(asc->sc_bounce);
  268         bus_space_write_4(asc->asc.sc_bst, asc->asc.sc_bsh, PMAZ_OFFSET_DMAR,
  269             tc_dmar);
  270         asc->asc.sc_flags |= ASC_MAPLOADED|ASC_DMAACTIVE;
  271 #endif
  272         return (0);
  273 }
  274 
  275 void
  276 asc_tc_go(sc)
  277         struct ncr53c9x_softc *sc;
  278 {
  279 #if 0
  280         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  281         u_int32_t tc_dmar;
  282 
  283         if (asc->asc.sc_flags & ASC_ISPULLUP)
  284                 tc_dmar = PMAZ_DMA_ADDR(asc->sc_bounce);
  285         else
  286                 tc_dmar = PMAZ_DMAR_WRITE | PMAZ_DMA_ADDR(asc->sc_bounce);
  287         bus_space_write_4(asc->asc.sc_bst, asc->asc.sc_bsh, PMAZ_OFFSET_DMAR,
  288             tc_dmar);
  289         asc->asc.sc_flags |= ASC_DMAACTIVE;
  290 #endif
  291 }
  292 
  293 /* NEVER CALLED BY MI 53C9x ENGINE INDEED */
  294 void
  295 asc_tc_stop(sc)
  296         struct ncr53c9x_softc *sc;
  297 {
  298 #if 0
  299         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  300 
  301         if (asc->asc.sc_flags & ASC_ISPULLUP)
  302                 memcpy(asc->sc_target, asc->sc_bounce, asc->sc_dmasize);
  303         asc->asc.sc_flags &= ~ASC_DMAACTIVE;
  304 #endif
  305 }
  306 
  307 /*
  308  * Glue functions.
  309  */
  310 int
  311 asc_dma_isintr(sc)
  312         struct ncr53c9x_softc *sc;
  313 {
  314         return !!(NCR_READ_REG(sc, NCR_STAT) & NCRSTAT_INT);
  315 }
  316 
  317 int
  318 asc_dma_isactive(sc)
  319         struct ncr53c9x_softc *sc;
  320 {
  321         struct asc_tc_softc *asc = (struct asc_tc_softc *)sc;
  322 
  323         return !!(asc->asc.sc_flags & ASC_DMAACTIVE);
  324 }
  325 
  326 void
  327 asc_clear_latched_intr(sc)
  328         struct ncr53c9x_softc *sc;
  329 {
  330 }

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