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

Cache object: 5ca5d8bddcf3eb3abd747285b2ab33e5


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