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/sbus/esp_sbus.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: esp_sbus.c,v 1.29 2004/03/17 17:04:58 pk Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center; 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 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: esp_sbus.c,v 1.29 2004/03/17 17:04:58 pk Exp $");
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/device.h>
   46 #include <sys/buf.h>
   47 #include <sys/malloc.h>
   48 
   49 #include <dev/scsipi/scsi_all.h>
   50 #include <dev/scsipi/scsipi_all.h>
   51 #include <dev/scsipi/scsiconf.h>
   52 #include <dev/scsipi/scsi_message.h>
   53 
   54 #include <machine/bus.h>
   55 #include <machine/intr.h>
   56 #include <machine/autoconf.h>
   57 
   58 #include <dev/ic/lsi64854reg.h>
   59 #include <dev/ic/lsi64854var.h>
   60 
   61 #include <dev/ic/ncr53c9xreg.h>
   62 #include <dev/ic/ncr53c9xvar.h>
   63 
   64 #include <dev/sbus/sbusvar.h>
   65 
   66 /* #define ESP_SBUS_DEBUG */
   67 
   68 struct esp_softc {
   69         struct ncr53c9x_softc sc_ncr53c9x;      /* glue to MI code */
   70         struct sbusdev  sc_sd;                  /* sbus device */
   71 
   72         bus_space_tag_t sc_bustag;
   73         bus_dma_tag_t   sc_dmatag;
   74 
   75         bus_space_handle_t sc_reg;              /* the registers */
   76         struct lsi64854_softc *sc_dma;          /* pointer to my dma */
   77 
   78         int     sc_pri;                         /* SBUS priority */
   79 };
   80 
   81 void    espattach_sbus  __P((struct device *, struct device *, void *));
   82 void    espattach_dma   __P((struct device *, struct device *, void *));
   83 int     espmatch_sbus   __P((struct device *, struct cfdata *, void *));
   84 
   85 
   86 CFATTACH_DECL(esp_sbus, sizeof(struct esp_softc),
   87     espmatch_sbus, espattach_sbus, NULL, NULL);
   88 
   89 CFATTACH_DECL(esp_dma, sizeof(struct esp_softc),
   90     espmatch_sbus, espattach_dma, NULL, NULL);
   91 
   92 /*
   93  * Functions and the switch for the MI code.
   94  */
   95 static u_char   esp_read_reg __P((struct ncr53c9x_softc *, int));
   96 static void     esp_write_reg __P((struct ncr53c9x_softc *, int, u_char));
   97 static u_char   esp_rdreg1 __P((struct ncr53c9x_softc *, int));
   98 static void     esp_wrreg1 __P((struct ncr53c9x_softc *, int, u_char));
   99 static int      esp_dma_isintr __P((struct ncr53c9x_softc *));
  100 static void     esp_dma_reset __P((struct ncr53c9x_softc *));
  101 static int      esp_dma_intr __P((struct ncr53c9x_softc *));
  102 static int      esp_dma_setup __P((struct ncr53c9x_softc *, caddr_t *,
  103                                     size_t *, int, size_t *));
  104 static void     esp_dma_go __P((struct ncr53c9x_softc *));
  105 static void     esp_dma_stop __P((struct ncr53c9x_softc *));
  106 static int      esp_dma_isactive __P((struct ncr53c9x_softc *));
  107 
  108 static struct ncr53c9x_glue esp_sbus_glue = {
  109         esp_read_reg,
  110         esp_write_reg,
  111         esp_dma_isintr,
  112         esp_dma_reset,
  113         esp_dma_intr,
  114         esp_dma_setup,
  115         esp_dma_go,
  116         esp_dma_stop,
  117         esp_dma_isactive,
  118         NULL,                   /* gl_clear_latched_intr */
  119 };
  120 
  121 static struct ncr53c9x_glue esp_sbus_glue1 = {
  122         esp_rdreg1,
  123         esp_wrreg1,
  124         esp_dma_isintr,
  125         esp_dma_reset,
  126         esp_dma_intr,
  127         esp_dma_setup,
  128         esp_dma_go,
  129         esp_dma_stop,
  130         esp_dma_isactive,
  131         NULL,                   /* gl_clear_latched_intr */
  132 };
  133 
  134 static void     espattach __P((struct esp_softc *, struct ncr53c9x_glue *));
  135 
  136 int
  137 espmatch_sbus(parent, cf, aux)
  138         struct device *parent;
  139         struct cfdata *cf;
  140         void *aux;
  141 {
  142         int rv;
  143         struct sbus_attach_args *sa = aux;
  144 
  145         if (strcmp("SUNW,fas", sa->sa_name) == 0)
  146                 return 1;
  147 
  148         rv = (strcmp(cf->cf_name, sa->sa_name) == 0 ||
  149             strcmp("ptscII", sa->sa_name) == 0);
  150         return (rv);
  151 }
  152 
  153 void
  154 espattach_sbus(parent, self, aux)
  155         struct device *parent, *self;
  156         void *aux;
  157 {
  158         struct esp_softc *esc = (void *)self;
  159         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  160         struct sbus_attach_args *sa = aux;
  161         struct lsi64854_softc *lsc;
  162         int burst, sbusburst;
  163 
  164         esc->sc_bustag = sa->sa_bustag;
  165         esc->sc_dmatag = sa->sa_dmatag;
  166 
  167         sc->sc_id = prom_getpropint(sa->sa_node, "initiator-id", 7);
  168         sc->sc_freq = prom_getpropint(sa->sa_node, "clock-frequency", -1);
  169         if (sc->sc_freq < 0)
  170                 sc->sc_freq = ((struct sbus_softc *)
  171                     sc->sc_dev.dv_parent)->sc_clockfreq;
  172 
  173 #ifdef ESP_SBUS_DEBUG
  174         printf("%s: espattach_sbus: sc_id %d, freq %d\n",
  175                self->dv_xname, sc->sc_id, sc->sc_freq);
  176 #endif
  177 
  178         if (strcmp("SUNW,fas", sa->sa_name) == 0) {
  179 
  180                 /*
  181                  * fas has 2 register spaces: dma(lsi64854) and SCSI core (ncr53c9x)
  182                  */
  183                 if (sa->sa_nreg != 2) {
  184                         printf("%s: %d register spaces\n", self->dv_xname, sa->sa_nreg);
  185                         return;
  186                 }
  187 
  188                 /*
  189                  * allocate space for dma, in SUNW,fas there are no separate
  190                  * dma device
  191                  */
  192                 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF, M_NOWAIT);
  193 
  194                 if (lsc == NULL) {
  195                         printf("%s: out of memory (lsi64854_softc)\n",
  196                                self->dv_xname);
  197                         return;
  198                 }
  199                 esc->sc_dma = lsc;
  200 
  201                 lsc->sc_bustag = sa->sa_bustag;
  202                 lsc->sc_dmatag = sa->sa_dmatag;
  203 
  204                 bcopy(sc->sc_dev.dv_xname, lsc->sc_dev.dv_xname,
  205                       sizeof (lsc->sc_dev.dv_xname));
  206 
  207                 /* Map dma registers */
  208                 if (sa->sa_npromvaddrs) {
  209                         sbus_promaddr_to_handle(sa->sa_bustag,
  210                                 sa->sa_promvaddrs[0], &lsc->sc_regs);
  211                 } else {
  212                         if (sbus_bus_map(sa->sa_bustag,
  213                                 sa->sa_reg[0].oa_space,
  214                                 sa->sa_reg[0].oa_base,
  215                                 sa->sa_reg[0].oa_size,
  216                                 0, &lsc->sc_regs) != 0) {
  217                                 printf("%s: cannot map dma registers\n",
  218                                         self->dv_xname);
  219                                 return;
  220                         }
  221                 }
  222 
  223                 /*
  224                  * XXX is this common(from bpp.c), the same in dma_sbus...etc.
  225                  *
  226                  * Get transfer burst size from PROM and plug it into the
  227                  * controller registers. This is needed on the Sun4m; do
  228                  * others need it too?
  229                  */
  230                 sbusburst = ((struct sbus_softc *)parent)->sc_burst;
  231                 if (sbusburst == 0)
  232                         sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
  233 
  234                 burst = prom_getpropint(sa->sa_node, "burst-sizes", -1);
  235 
  236 #if ESP_SBUS_DEBUG
  237                 printf("espattach_sbus: burst 0x%x, sbus 0x%x\n",
  238                     burst, sbusburst);
  239 #endif
  240 
  241                 if (burst == -1)
  242                         /* take SBus burst sizes */
  243                         burst = sbusburst;
  244 
  245                 /* Clamp at parent's burst sizes */
  246                 burst &= sbusburst;
  247                 lsc->sc_burst = (burst & SBUS_BURST_32) ? 32 :
  248                     (burst & SBUS_BURST_16) ? 16 : 0;
  249 
  250                 lsc->sc_channel = L64854_CHANNEL_SCSI;
  251                 lsc->sc_client = sc;
  252 
  253                 lsi64854_attach(lsc);
  254 
  255                 /*
  256                  * map SCSI core registers
  257                  */
  258                 if (sa->sa_npromvaddrs > 1) {
  259                         sbus_promaddr_to_handle(sa->sa_bustag,
  260                                 sa->sa_promvaddrs[1], &esc->sc_reg);
  261                 } else {
  262                         if (sbus_bus_map(sa->sa_bustag,
  263                                 sa->sa_reg[1].oa_space,
  264                                 sa->sa_reg[1].oa_base,
  265                                 sa->sa_reg[1].oa_size,
  266                                 0, &esc->sc_reg) != 0) {
  267                                 printf("%s @ sbus: "
  268                                         "cannot map scsi core registers\n",
  269                                         self->dv_xname);
  270                                 return;
  271                         }
  272                 }
  273 
  274                 if (sa->sa_nintr == 0) {
  275                         printf("\n%s: no interrupt property\n", self->dv_xname);
  276                         return;
  277                 }
  278 
  279                 esc->sc_pri = sa->sa_pri;
  280 
  281                 /* add me to the sbus structures */
  282                 esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
  283                 sbus_establish(&esc->sc_sd, &sc->sc_dev);
  284 
  285                 espattach(esc, &esp_sbus_glue);
  286 
  287                 return;
  288         }
  289 
  290         /*
  291          * Find the DMA by poking around the dma device structures
  292          *
  293          * What happens here is that if the dma driver has not been
  294          * configured, then this returns a NULL pointer. Then when the
  295          * dma actually gets configured, it does the opposing test, and
  296          * if the sc->sc_esp field in it's softc is NULL, then tries to
  297          * find the matching esp driver.
  298          */
  299         esc->sc_dma = (struct lsi64854_softc *)
  300                                 getdevunit("dma", sc->sc_dev.dv_unit);
  301 
  302         /*
  303          * and a back pointer to us, for DMA
  304          */
  305         if (esc->sc_dma)
  306                 esc->sc_dma->sc_client = sc;
  307         else {
  308                 printf("\n");
  309                 panic("espattach: no dma found");
  310         }
  311 
  312         /*
  313          * The `ESC' DMA chip must be reset before we can access
  314          * the esp registers.
  315          */
  316         if (esc->sc_dma->sc_rev == DMAREV_ESC)
  317                 DMA_RESET(esc->sc_dma);
  318 
  319         /*
  320          * Map my registers in, if they aren't already in virtual
  321          * address space.
  322          */
  323         if (sa->sa_npromvaddrs) {
  324                 sbus_promaddr_to_handle(sa->sa_bustag,
  325                         sa->sa_promvaddrs[0], &esc->sc_reg);
  326         } else {
  327                 if (sbus_bus_map(sa->sa_bustag,
  328                         sa->sa_slot, sa->sa_offset, sa->sa_size,
  329                         0, &esc->sc_reg) != 0) {
  330                         printf("%s @ sbus: cannot map registers\n",
  331                                 self->dv_xname);
  332                         return;
  333                 }
  334         }
  335 
  336         if (sa->sa_nintr == 0) {
  337                 /*
  338                  * No interrupt properties: we quit; this might
  339                  * happen on e.g. a Sparc X terminal.
  340                  */
  341                 printf("\n%s: no interrupt property\n", self->dv_xname);
  342                 return;
  343         }
  344 
  345         esc->sc_pri = sa->sa_pri;
  346 
  347         /* add me to the sbus structures */
  348         esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
  349         sbus_establish(&esc->sc_sd, &sc->sc_dev);
  350 
  351         if (strcmp("ptscII", sa->sa_name) == 0) {
  352                 espattach(esc, &esp_sbus_glue1);
  353         } else {
  354                 espattach(esc, &esp_sbus_glue);
  355         }
  356 }
  357 
  358 void
  359 espattach_dma(parent, self, aux)
  360         struct device *parent, *self;
  361         void *aux;
  362 {
  363         struct esp_softc *esc = (void *)self;
  364         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  365         struct sbus_attach_args *sa = aux;
  366 
  367         if (strcmp("ptscII", sa->sa_name) == 0) {
  368                 return;
  369         }
  370 
  371         esc->sc_bustag = sa->sa_bustag;
  372         esc->sc_dmatag = sa->sa_dmatag;
  373 
  374         sc->sc_id = prom_getpropint(sa->sa_node, "initiator-id", 7);
  375         sc->sc_freq = prom_getpropint(sa->sa_node, "clock-frequency", -1);
  376 
  377         esc->sc_dma = (struct lsi64854_softc *)parent;
  378         esc->sc_dma->sc_client = sc;
  379 
  380         /*
  381          * Map my registers in, if they aren't already in virtual
  382          * address space.
  383          */
  384         if (sa->sa_npromvaddrs) {
  385                 sbus_promaddr_to_handle(sa->sa_bustag,
  386                         sa->sa_promvaddrs[0], &esc->sc_reg);
  387         } else {
  388                 if (sbus_bus_map(sa->sa_bustag,
  389                         sa->sa_slot, sa->sa_offset, sa->sa_size,
  390                         0, &esc->sc_reg) != 0) {
  391                         printf("%s @ dma: cannot map registers\n",
  392                                 self->dv_xname);
  393                         return;
  394                 }
  395         }
  396 
  397         if (sa->sa_nintr == 0) {
  398                 /*
  399                  * No interrupt properties: we quit; this might
  400                  * happen on e.g. a Sparc X terminal.
  401                  */
  402                 printf("\n%s: no interrupt property\n", self->dv_xname);
  403                 return;
  404         }
  405 
  406         esc->sc_pri = sa->sa_pri;
  407 
  408         /* Assume SBus is grandparent */
  409         esc->sc_sd.sd_reset = (void *) ncr53c9x_reset;
  410         sbus_establish(&esc->sc_sd, parent);
  411 
  412         espattach(esc, &esp_sbus_glue);
  413 }
  414 
  415 
  416 /*
  417  * Attach this instance, and then all the sub-devices
  418  */
  419 void
  420 espattach(esc, gluep)
  421         struct esp_softc *esc;
  422         struct ncr53c9x_glue *gluep;
  423 {
  424         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  425         void *icookie;
  426         unsigned int uid = 0;
  427 
  428         /*
  429          * Set up glue for MI code early; we use some of it here.
  430          */
  431         sc->sc_glue = gluep;
  432 
  433         /* gimme MHz */
  434         sc->sc_freq /= 1000000;
  435 
  436         /*
  437          * XXX More of this should be in ncr53c9x_attach(), but
  438          * XXX should we really poke around the chip that much in
  439          * XXX the MI code?  Think about this more...
  440          */
  441 
  442         /*
  443          * It is necessary to try to load the 2nd config register here,
  444          * to find out what rev the esp chip is, else the ncr53c9x_reset
  445          * will not set up the defaults correctly.
  446          */
  447         sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
  448         sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
  449         sc->sc_cfg3 = NCRCFG3_CDB;
  450         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  451 
  452         if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
  453             (NCRCFG2_SCSI2 | NCRCFG2_RPE)) {
  454                 sc->sc_rev = NCR_VARIANT_ESP100;
  455         } else {
  456                 sc->sc_cfg2 = NCRCFG2_SCSI2;
  457                 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  458                 sc->sc_cfg3 = 0;
  459                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  460                 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
  461                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  462                 if (NCR_READ_REG(sc, NCR_CFG3) !=
  463                     (NCRCFG3_CDB | NCRCFG3_FCLK)) {
  464                         sc->sc_rev = NCR_VARIANT_ESP100A;
  465                 } else {
  466                         /* NCRCFG2_FE enables > 64K transfers */
  467                         sc->sc_cfg2 |= NCRCFG2_FE;
  468                         sc->sc_cfg3 = 0;
  469                         NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  470                         sc->sc_rev = NCR_VARIANT_ESP200;
  471 
  472                         /* XXX spec says it's valid after power up or chip reset */
  473                         uid = NCR_READ_REG(sc, NCR_UID);
  474                         if (((uid & 0xf8) >> 3) == 0x0a) /* XXX */
  475                                 sc->sc_rev = NCR_VARIANT_FAS366;
  476                 }
  477         }
  478 
  479 #ifdef ESP_SBUS_DEBUG
  480         printf("espattach: revision %d, uid 0x%x\n", sc->sc_rev, uid);
  481 #endif
  482 
  483         /*
  484          * XXX minsync and maxxfer _should_ be set up in MI code,
  485          * XXX but it appears to have some dependency on what sort
  486          * XXX of DMA we're hooked up to, etc.
  487          */
  488 
  489         /*
  490          * This is the value used to start sync negotiations
  491          * Note that the NCR register "SYNCTP" is programmed
  492          * in "clocks per byte", and has a minimum value of 4.
  493          * The SCSI period used in negotiation is one-fourth
  494          * of the time (in nanoseconds) needed to transfer one byte.
  495          * Since the chip's clock is given in MHz, we have the following
  496          * formula: 4 * period = (1000 / freq) * 4
  497          */
  498         sc->sc_minsync = 1000 / sc->sc_freq;
  499 
  500         /*
  501          * Alas, we must now modify the value a bit, because it's
  502          * only valid when can switch on FASTCLK and FASTSCSI bits  
  503          * in config register 3... 
  504          */
  505         switch (sc->sc_rev) {
  506         case NCR_VARIANT_ESP100:
  507                 sc->sc_maxxfer = 64 * 1024;
  508                 sc->sc_minsync = 0;     /* No synch on old chip? */
  509                 break;
  510 
  511         case NCR_VARIANT_ESP100A:
  512                 sc->sc_maxxfer = 64 * 1024;
  513                 /* Min clocks/byte is 5 */
  514                 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
  515                 break;
  516 
  517         case NCR_VARIANT_ESP200:
  518         case NCR_VARIANT_FAS366:
  519                 sc->sc_maxxfer = 16 * 1024 * 1024;
  520                 /* XXX - do actually set FAST* bits */
  521                 break;
  522         }
  523 
  524         /* Establish interrupt channel */
  525         icookie = bus_intr_establish(esc->sc_bustag, esc->sc_pri, IPL_BIO,
  526                                      ncr53c9x_intr, sc);
  527 
  528         /* register interrupt stats */
  529         evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL,
  530             sc->sc_dev.dv_xname, "intr");
  531 
  532         /* Turn on target selection using the `dma' method */
  533         if (sc->sc_rev != NCR_VARIANT_FAS366)
  534                 sc->sc_features |= NCR_F_DMASELECT;
  535 
  536         /* Do the common parts of attachment. */
  537         sc->sc_adapter.adapt_minphys = minphys;
  538         sc->sc_adapter.adapt_request = ncr53c9x_scsipi_request;
  539         ncr53c9x_attach(sc);
  540 
  541 }
  542 
  543 /*
  544  * Glue functions.
  545  */
  546 
  547 #ifdef ESP_SBUS_DEBUG
  548 int esp_sbus_debug = 0;
  549 
  550 static struct {
  551         char *r_name;
  552         int   r_flag; 
  553 } esp__read_regnames [] = {
  554         { "TCL", 0},                    /* 0/00 */
  555         { "TCM", 0},                    /* 1/04 */
  556         { "FIFO", 0},                   /* 2/08 */
  557         { "CMD", 0},                    /* 3/0c */
  558         { "STAT", 0},                   /* 4/10 */
  559         { "INTR", 0},                   /* 5/14 */
  560         { "STEP", 0},                   /* 6/18 */
  561         { "FFLAGS", 1},                 /* 7/1c */
  562         { "CFG1", 1},                   /* 8/20 */
  563         { "STAT2", 0},                  /* 9/24 */
  564         { "CFG4", 1},                   /* a/28 */
  565         { "CFG2", 1},                   /* b/2c */
  566         { "CFG3", 1},                   /* c/30 */
  567         { "-none", 1},                  /* d/34 */
  568         { "TCH", 1},                    /* e/38 */
  569         { "TCX", 1},                    /* f/3c */
  570 };
  571 
  572 static struct {
  573         char *r_name;
  574         int   r_flag;
  575 } esp__write_regnames[] = {
  576         { "TCL", 1},                    /* 0/00 */
  577         { "TCM", 1},                    /* 1/04 */
  578         { "FIFO", 0},                   /* 2/08 */
  579         { "CMD", 0},                    /* 3/0c */
  580         { "SELID", 1},                  /* 4/10 */
  581         { "TIMEOUT", 1},                /* 5/14 */
  582         { "SYNCTP", 1},                 /* 6/18 */
  583         { "SYNCOFF", 1},                /* 7/1c */
  584         { "CFG1", 1},                   /* 8/20 */
  585         { "CCF", 1},                    /* 9/24 */
  586         { "TEST", 1},                   /* a/28 */
  587         { "CFG2", 1},                   /* b/2c */
  588         { "CFG3", 1},                   /* c/30 */
  589         { "-none", 1},                  /* d/34 */
  590         { "TCH", 1},                    /* e/38 */
  591         { "TCX", 1},                    /* f/3c */
  592 };
  593 #endif
  594 
  595 u_char
  596 esp_read_reg(sc, reg)
  597         struct ncr53c9x_softc *sc;
  598         int reg;
  599 {
  600         struct esp_softc *esc = (struct esp_softc *)sc;
  601         u_char v;
  602 
  603         v = bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg * 4);
  604 #ifdef ESP_SBUS_DEBUG
  605         if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
  606                 printf("RD:%x <%s> %x\n", reg * 4,
  607                     ((unsigned)reg < 0x10) ? esp__read_regnames[reg].r_name : "<***>", v);
  608 #endif
  609         return v;
  610 }
  611 
  612 void
  613 esp_write_reg(sc, reg, v)
  614         struct ncr53c9x_softc *sc;
  615         int reg;
  616         u_char v;
  617 {
  618         struct esp_softc *esc = (struct esp_softc *)sc;
  619 
  620 #ifdef ESP_SBUS_DEBUG
  621         if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
  622                 printf("WR:%x <%s> %x\n", reg * 4,
  623                     ((unsigned)reg < 0x10) ? esp__write_regnames[reg].r_name : "<***>", v);
  624 #endif
  625         bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg * 4, v);
  626 }
  627 
  628 u_char
  629 esp_rdreg1(sc, reg)
  630         struct ncr53c9x_softc *sc;
  631         int reg;
  632 {
  633         struct esp_softc *esc = (struct esp_softc *)sc;
  634 
  635         return (bus_space_read_1(esc->sc_bustag, esc->sc_reg, reg));
  636 }
  637 
  638 void
  639 esp_wrreg1(sc, reg, v)
  640         struct ncr53c9x_softc *sc;
  641         int reg;
  642         u_char v;
  643 {
  644         struct esp_softc *esc = (struct esp_softc *)sc;
  645 
  646         bus_space_write_1(esc->sc_bustag, esc->sc_reg, reg, v);
  647 }
  648 
  649 int
  650 esp_dma_isintr(sc)
  651         struct ncr53c9x_softc *sc;
  652 {
  653         struct esp_softc *esc = (struct esp_softc *)sc;
  654 
  655         return (DMA_ISINTR(esc->sc_dma));
  656 }
  657 
  658 void
  659 esp_dma_reset(sc)
  660         struct ncr53c9x_softc *sc;
  661 {
  662         struct esp_softc *esc = (struct esp_softc *)sc;
  663 
  664         DMA_RESET(esc->sc_dma);
  665 }
  666 
  667 int
  668 esp_dma_intr(sc)
  669         struct ncr53c9x_softc *sc;
  670 {
  671         struct esp_softc *esc = (struct esp_softc *)sc;
  672 
  673         return (DMA_INTR(esc->sc_dma));
  674 }
  675 
  676 int
  677 esp_dma_setup(sc, addr, len, datain, dmasize)
  678         struct ncr53c9x_softc *sc;
  679         caddr_t *addr;
  680         size_t *len;
  681         int datain;
  682         size_t *dmasize;
  683 {
  684         struct esp_softc *esc = (struct esp_softc *)sc;
  685 
  686         return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
  687 }
  688 
  689 void
  690 esp_dma_go(sc)
  691         struct ncr53c9x_softc *sc;
  692 {
  693         struct esp_softc *esc = (struct esp_softc *)sc;
  694 
  695         DMA_GO(esc->sc_dma);
  696 }
  697 
  698 void
  699 esp_dma_stop(sc)
  700         struct ncr53c9x_softc *sc;
  701 {
  702         struct esp_softc *esc = (struct esp_softc *)sc;
  703         u_int32_t csr;
  704 
  705         csr = L64854_GCSR(esc->sc_dma);
  706         csr &= ~D_EN_DMA;
  707         L64854_SCSR(esc->sc_dma, csr);
  708 }
  709 
  710 int
  711 esp_dma_isactive(sc)
  712         struct ncr53c9x_softc *sc;
  713 {
  714         struct esp_softc *esc = (struct esp_softc *)sc;
  715 
  716         return (DMA_ISACTIVE(esc->sc_dma));
  717 }
  718 
  719 #include "opt_ddb.h"
  720 #ifdef DDB
  721 #include <machine/db_machdep.h>
  722 #include <ddb/db_output.h>
  723 
  724 void db_esp __P((db_expr_t, int, db_expr_t, char*));
  725 
  726 void
  727 db_esp(addr, have_addr, count, modif)
  728         db_expr_t addr;
  729         int have_addr;
  730         db_expr_t count;
  731         char *modif;
  732 {
  733         struct ncr53c9x_softc *sc;
  734         struct ncr53c9x_ecb *ecb;
  735         struct ncr53c9x_linfo *li;
  736         int u, t, i;
  737 
  738         for (u=0; u<10; u++) {
  739                 sc = (struct ncr53c9x_softc *)
  740                         getdevunit("esp", u);
  741                 if (!sc) continue;
  742 
  743                 db_printf("esp%d: nexus %p phase %x prev %x dp %p dleft %lx ify %x\n",
  744                           u, sc->sc_nexus, sc->sc_phase, sc->sc_prevphase, 
  745                           sc->sc_dp, sc->sc_dleft, sc->sc_msgify);
  746                 db_printf("\tmsgout %x msgpriq %x msgin %x:%x:%x:%x:%x\n",
  747                           sc->sc_msgout, sc->sc_msgpriq, sc->sc_imess[0],
  748                           sc->sc_imess[1], sc->sc_imess[2], sc->sc_imess[3],
  749                           sc->sc_imess[0]);
  750                 db_printf("ready: ");
  751                 for (ecb = sc->ready_list.tqh_first; ecb; ecb = ecb->chain.tqe_next) {
  752                         db_printf("ecb %p ", ecb);
  753                         if (ecb == ecb->chain.tqe_next) {
  754                                 db_printf("\nWARNING: tailq loop on ecb %p", ecb);
  755                                 break;
  756                         }
  757                 }
  758                 db_printf("\n");
  759                 
  760                 for (t=0; t<sc->sc_ntarg; t++) {
  761                         LIST_FOREACH(li, &sc->sc_tinfo[t].luns, link) {
  762                                 db_printf("t%d lun %d untagged %p busy %d used %x\n",
  763                                           t, (int)li->lun, li->untagged, li->busy,
  764                                           li->used);
  765                                 for (i=0; i<256; i++)
  766                                         if ((ecb = li->queued[i])) {
  767                                                 db_printf("ecb %p tag %x\n", ecb, i);
  768                                         }
  769                         }
  770                 }
  771         }
  772 }
  773 #endif
  774 

Cache object: 0d53c6073f56ff6216b2f00d9450f766


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