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/esp/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 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD AND BSD-2-Clause-NetBSD
    3  *
    4  * Copyright (c) 2004 Scott Long
    5  * Copyright (c) 2005 Marius Strobl <marius@FreeBSD.org>
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  */
   30 
   31 /*      $NetBSD: esp_sbus.c,v 1.51 2009/09/17 16:28:12 tsutsui Exp $    */
   32 
   33 /*-
   34  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   35  * All rights reserved.
   36  *
   37  * This code is derived from software contributed to The NetBSD Foundation
   38  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
   39  * Simulation Facility, NASA Ames Research Center; Paul Kranenburg.
   40  *
   41  * Redistribution and use in source and binary forms, with or without
   42  * modification, are permitted provided that the following conditions
   43  * are met:
   44  * 1. Redistributions of source code must retain the above copyright
   45  *    notice, this list of conditions and the following disclaimer.
   46  * 2. Redistributions in binary form must reproduce the above copyright
   47  *    notice, this list of conditions and the following disclaimer in the
   48  *    documentation and/or other materials provided with the distribution.
   49  *
   50  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   51  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   52  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   53  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   54  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   55  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   58  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   60  * POSSIBILITY OF SUCH DAMAGE.
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __FBSDID("$FreeBSD$");
   65 
   66 #include <sys/param.h>
   67 #include <sys/systm.h>
   68 #include <sys/bus.h>
   69 #include <sys/kernel.h>
   70 #include <sys/lock.h>
   71 #include <sys/module.h>
   72 #include <sys/mutex.h>
   73 #include <sys/rman.h>
   74 
   75 #include <dev/ofw/ofw_bus.h>
   76 #include <dev/ofw/openfirm.h>
   77 #include <machine/bus.h>
   78 #include <machine/ofw_machdep.h>
   79 #include <machine/resource.h>
   80 
   81 #include <cam/cam.h>
   82 #include <cam/cam_ccb.h>
   83 #include <cam/scsi/scsi_all.h>
   84 #include <cam/scsi/scsi_message.h>
   85 
   86 #include <sparc64/sbus/lsi64854reg.h>
   87 #include <sparc64/sbus/lsi64854var.h>
   88 #include <sparc64/sbus/sbusvar.h>
   89 
   90 #include <dev/esp/ncr53c9xreg.h>
   91 #include <dev/esp/ncr53c9xvar.h>
   92 
   93 /* #define ESP_SBUS_DEBUG */
   94 
   95 struct esp_softc {
   96         struct ncr53c9x_softc   sc_ncr53c9x;    /* glue to MI code */
   97         device_t                sc_dev;
   98 
   99         struct resource         *sc_res;
  100 
  101         struct resource         *sc_irqres;
  102         void                    *sc_irq;
  103 
  104         struct lsi64854_softc   *sc_dma;        /* pointer to my DMA */
  105 };
  106 
  107 static int      esp_probe(device_t);
  108 static int      esp_dma_attach(device_t);
  109 static int      esp_dma_detach(device_t);
  110 static int      esp_sbus_attach(device_t);
  111 static int      esp_sbus_detach(device_t);
  112 static int      esp_suspend(device_t);
  113 static int      esp_resume(device_t);
  114 
  115 static device_method_t esp_dma_methods[] = {
  116         DEVMETHOD(device_probe,         esp_probe),
  117         DEVMETHOD(device_attach,        esp_dma_attach),
  118         DEVMETHOD(device_detach,        esp_dma_detach),
  119         DEVMETHOD(device_suspend,       esp_suspend),
  120         DEVMETHOD(device_resume,        esp_resume),
  121 
  122         DEVMETHOD_END
  123 };
  124 
  125 static driver_t esp_dma_driver = {
  126         "esp",
  127         esp_dma_methods,
  128         sizeof(struct esp_softc)
  129 };
  130 
  131 DRIVER_MODULE(esp, dma, esp_dma_driver, esp_devclass, 0, 0);
  132 MODULE_DEPEND(esp, dma, 1, 1, 1);
  133 
  134 static device_method_t esp_sbus_methods[] = {
  135         DEVMETHOD(device_probe,         esp_probe),
  136         DEVMETHOD(device_attach,        esp_sbus_attach),
  137         DEVMETHOD(device_detach,        esp_sbus_detach),
  138         DEVMETHOD(device_suspend,       esp_suspend),
  139         DEVMETHOD(device_resume,        esp_resume),
  140 
  141         DEVMETHOD_END
  142 };
  143 
  144 static driver_t esp_sbus_driver = {
  145         "esp",
  146         esp_sbus_methods,
  147         sizeof(struct esp_softc)
  148 };
  149 
  150 DRIVER_MODULE(esp, sbus, esp_sbus_driver, esp_devclass, 0, 0);
  151 MODULE_DEPEND(esp, sbus, 1, 1, 1);
  152 
  153 /*
  154  * Functions and the switch for the MI code
  155  */
  156 static uint8_t  esp_read_reg(struct ncr53c9x_softc *sc, int reg);
  157 static void     esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v);
  158 static int      esp_dma_isintr(struct ncr53c9x_softc *sc);
  159 static void     esp_dma_reset(struct ncr53c9x_softc *sc);
  160 static int      esp_dma_intr(struct ncr53c9x_softc *sc);
  161 static int      esp_dma_setup(struct ncr53c9x_softc *sc, void **addr,
  162                     size_t *len, int datain, size_t *dmasize);
  163 static void     esp_dma_go(struct ncr53c9x_softc *sc);
  164 static void     esp_dma_stop(struct ncr53c9x_softc *sc);
  165 static int      esp_dma_isactive(struct ncr53c9x_softc *sc);
  166 static int      espattach(struct esp_softc *esc,
  167                     const struct ncr53c9x_glue *gluep);
  168 static int      espdetach(struct esp_softc *esc);
  169 
  170 static const struct ncr53c9x_glue esp_sbus_glue = {
  171         esp_read_reg,
  172         esp_write_reg,
  173         esp_dma_isintr,
  174         esp_dma_reset,
  175         esp_dma_intr,
  176         esp_dma_setup,
  177         esp_dma_go,
  178         esp_dma_stop,
  179         esp_dma_isactive,
  180 };
  181 
  182 static int
  183 esp_probe(device_t dev)
  184 {
  185         const char *name;
  186 
  187         name = ofw_bus_get_name(dev);
  188         if (strcmp("SUNW,fas", name) == 0) {
  189                 device_set_desc(dev, "Sun FAS366 Fast-Wide SCSI");
  190                 return (BUS_PROBE_DEFAULT);
  191         } else if (strcmp("esp", name) == 0) {
  192                 device_set_desc(dev, "Sun ESP SCSI/Sun FAS Fast-SCSI");
  193                 return (BUS_PROBE_DEFAULT);
  194         }
  195 
  196         return (ENXIO);
  197 }
  198 
  199 static int
  200 esp_sbus_attach(device_t dev)
  201 {
  202         struct esp_softc *esc;
  203         struct ncr53c9x_softc *sc;
  204         struct lsi64854_softc *lsc;
  205         device_t *children;
  206         int error, i, nchildren;
  207 
  208         esc = device_get_softc(dev);
  209         sc = &esc->sc_ncr53c9x;
  210 
  211         lsc = NULL;
  212         esc->sc_dev = dev;
  213         sc->sc_freq = sbus_get_clockfreq(dev);
  214 
  215         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") == 0) {
  216                 /*
  217                  * Allocate space for DMA, in SUNW,fas there are no
  218                  * separate DMA devices.
  219                  */
  220                 lsc = malloc(sizeof (struct lsi64854_softc), M_DEVBUF,
  221                     M_NOWAIT | M_ZERO);
  222                 if (lsc == NULL) {
  223                         device_printf(dev, "out of memory (lsi64854_softc)\n");
  224                         return (ENOMEM);
  225                 }
  226                 esc->sc_dma = lsc;
  227 
  228                 /*
  229                  * SUNW,fas have 2 register spaces: DMA (lsi64854) and
  230                  * SCSI core (ncr53c9x).
  231                  */
  232 
  233                 /* Allocate DMA registers. */
  234                 i = 0;
  235                 if ((lsc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  236                     &i, RF_ACTIVE)) == NULL) {
  237                         device_printf(dev, "cannot allocate DMA registers\n");
  238                         error = ENXIO;
  239                         goto fail_sbus_lsc;
  240                 }
  241 
  242                 /* Create a parent DMA tag based on this bus. */
  243                 error = bus_dma_tag_create(
  244                     bus_get_dma_tag(dev),       /* parent */
  245                     1, 0,                       /* alignment, boundary */
  246                     BUS_SPACE_MAXADDR,          /* lowaddr */
  247                     BUS_SPACE_MAXADDR,          /* highaddr */
  248                     NULL, NULL,                 /* filter, filterarg */
  249                     BUS_SPACE_MAXSIZE,          /* maxsize */
  250                     BUS_SPACE_UNRESTRICTED,     /* nsegments */
  251                     BUS_SPACE_MAXSIZE,          /* maxsegsize */
  252                     0,                          /* flags */
  253                     NULL, NULL,                 /* no locking */
  254                     &lsc->sc_parent_dmat);
  255                 if (error != 0) {
  256                         device_printf(dev, "cannot allocate parent DMA tag\n");
  257                         goto fail_sbus_lres;
  258                 }
  259 
  260                 i = sbus_get_burstsz(dev);
  261 
  262 #ifdef ESP_SBUS_DEBUG
  263                 printf("%s: burst 0x%x\n", __func__, i);
  264 #endif
  265 
  266                 lsc->sc_burst = (i & SBUS_BURST_32) ? 32 :
  267                     (i & SBUS_BURST_16) ? 16 : 0;
  268 
  269                 lsc->sc_channel = L64854_CHANNEL_SCSI;
  270                 lsc->sc_client = sc;
  271                 lsc->sc_dev = dev;
  272 
  273                 /*
  274                  * Allocate SCSI core registers.
  275                  */
  276                 i = 1;
  277                 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  278                     &i, RF_ACTIVE)) == NULL) {
  279                         device_printf(dev,
  280                             "cannot allocate SCSI core registers\n");
  281                         error = ENXIO;
  282                         goto fail_sbus_lpdma;
  283                 }
  284         } else {
  285                 /*
  286                  * Search accompanying DMA engine.  It should have been
  287                  * already attached otherwise there isn't much we can do.
  288                  */
  289                 if (device_get_children(device_get_parent(dev), &children,
  290                     &nchildren) != 0) {
  291                         device_printf(dev, "cannot determine siblings\n");
  292                         return (ENXIO);
  293                 }
  294                 for (i = 0; i < nchildren; i++) {
  295                         if (device_is_attached(children[i]) &&
  296                             sbus_get_slot(children[i]) ==
  297                             sbus_get_slot(dev) &&
  298                             strcmp(ofw_bus_get_name(children[i]),
  299                             "dma") == 0) {
  300                                 /* XXX hackery */
  301                                 esc->sc_dma = (struct lsi64854_softc *)
  302                                     device_get_softc(children[i]);
  303                                 break;
  304                         }
  305                 }
  306                 free(children, M_TEMP);
  307                 if (esc->sc_dma == NULL) {
  308                         device_printf(dev, "cannot find DMA engine\n");
  309                         return (ENXIO);
  310                 }
  311                 esc->sc_dma->sc_client = sc;
  312 
  313                 /*
  314                  * Allocate SCSI core registers.
  315                  */
  316                 i = 0;
  317                 if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  318                     &i, RF_ACTIVE)) == NULL) {
  319                         device_printf(dev,
  320                             "cannot allocate SCSI core registers\n");
  321                         return (ENXIO);
  322                 }
  323         }
  324 
  325         error = espattach(esc, &esp_sbus_glue);
  326         if (error != 0) {
  327                 device_printf(dev, "espattach failed\n");
  328                 goto fail_sbus_eres;
  329         }
  330 
  331         return (0);
  332 
  333  fail_sbus_eres:
  334         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
  335             esc->sc_res);
  336         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
  337                 return (error);
  338  fail_sbus_lpdma:
  339         bus_dma_tag_destroy(lsc->sc_parent_dmat);
  340  fail_sbus_lres:
  341         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
  342             lsc->sc_res);
  343  fail_sbus_lsc:
  344         free(lsc, M_DEVBUF);
  345         return (error);
  346 }
  347 
  348 static int
  349 esp_sbus_detach(device_t dev)
  350 {
  351         struct esp_softc *esc;
  352         struct lsi64854_softc *lsc;
  353         int error;
  354 
  355         esc = device_get_softc(dev);
  356         lsc = esc->sc_dma;
  357 
  358         error = espdetach(esc);
  359         if (error != 0)
  360                 return (error);
  361         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
  362                 esc->sc_res);
  363         if (strcmp(ofw_bus_get_name(dev), "SUNW,fas") != 0)
  364                 return (0);
  365         bus_dma_tag_destroy(lsc->sc_parent_dmat);
  366         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(lsc->sc_res),
  367             lsc->sc_res);
  368         free(lsc, M_DEVBUF);
  369 
  370         return (0);
  371 }
  372 
  373 static int
  374 esp_dma_attach(device_t dev)
  375 {
  376         struct esp_softc *esc;
  377         struct ncr53c9x_softc *sc;
  378         int error, i;
  379 
  380         esc = device_get_softc(dev);
  381         sc = &esc->sc_ncr53c9x;
  382 
  383         esc->sc_dev = dev;
  384         if (OF_getprop(ofw_bus_get_node(dev), "clock-frequency",
  385             &sc->sc_freq, sizeof(sc->sc_freq)) == -1) {
  386                 printf("failed to query OFW for clock-frequency\n");
  387                 return (ENXIO);
  388         }
  389 
  390         /* XXX hackery */
  391         esc->sc_dma = (struct lsi64854_softc *)
  392             device_get_softc(device_get_parent(dev));
  393         esc->sc_dma->sc_client = sc;
  394 
  395         /*
  396          * Allocate SCSI core registers.
  397          */
  398         i = 0;
  399         if ((esc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  400             &i, RF_ACTIVE)) == NULL) {
  401                 device_printf(dev, "cannot allocate SCSI core registers\n");
  402                 return (ENXIO);
  403         }
  404 
  405         error = espattach(esc, &esp_sbus_glue);
  406         if (error != 0) {
  407                 device_printf(dev, "espattach failed\n");
  408                 goto fail_dma_eres;
  409         }
  410 
  411         return (0);
  412 
  413  fail_dma_eres:
  414         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
  415             esc->sc_res);
  416         return (error);
  417 }
  418 
  419 static int
  420 esp_dma_detach(device_t dev)
  421 {
  422         struct esp_softc *esc;
  423         int error;
  424 
  425         esc = device_get_softc(dev);
  426 
  427         error = espdetach(esc);
  428         if (error != 0)
  429                 return (error);
  430         bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(esc->sc_res),
  431             esc->sc_res);
  432 
  433         return (0);
  434 }
  435 
  436 static int
  437 esp_suspend(device_t dev)
  438 {
  439 
  440         return (ENXIO);
  441 }
  442 
  443 static int
  444 esp_resume(device_t dev)
  445 {
  446 
  447         return (ENXIO);
  448 }
  449 
  450 static int
  451 espattach(struct esp_softc *esc, const struct ncr53c9x_glue *gluep)
  452 {
  453         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  454         unsigned int uid = 0;
  455         int error, i;
  456 
  457         NCR_LOCK_INIT(sc);
  458 
  459         sc->sc_id = OF_getscsinitid(esc->sc_dev);
  460 
  461 #ifdef ESP_SBUS_DEBUG
  462         device_printf(esc->sc_dev, "%s: sc_id %d, freq %d\n",
  463             __func__, sc->sc_id, sc->sc_freq);
  464 #endif
  465 
  466         /*
  467          * The `ESC' DMA chip must be reset before we can access
  468          * the ESP registers.
  469          */
  470         if (esc->sc_dma->sc_rev == DMAREV_ESC)
  471                 DMA_RESET(esc->sc_dma);
  472 
  473         /*
  474          * Set up glue for MI code early; we use some of it here.
  475          */
  476         sc->sc_glue = gluep;
  477 
  478         /* gimme MHz */
  479         sc->sc_freq /= 1000000;
  480 
  481         /*
  482          * XXX More of this should be in ncr53c9x_attach(), but
  483          * XXX should we really poke around the chip that much in
  484          * XXX the MI code?  Think about this more...
  485          */
  486 
  487         /*
  488          * Read the part-unique ID code of the SCSI chip.  The contained
  489          * value is only valid if all of the following conditions are met:
  490          * - After power-up or chip reset.
  491          * - Before any value is written to this register.
  492          * - The NCRCFG2_FE bit is set.
  493          * - A (NCRCMD_NOP | NCRCMD_DMA) command has been issued.
  494          */
  495         NCRCMD(sc, NCRCMD_RSTCHIP);
  496         NCRCMD(sc, NCRCMD_NOP);
  497         sc->sc_cfg2 = NCRCFG2_FE;
  498         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  499         NCRCMD(sc, NCRCMD_NOP | NCRCMD_DMA);
  500         uid = NCR_READ_REG(sc, NCR_UID);
  501 
  502         /*
  503          * It is necessary to try to load the 2nd config register here,
  504          * to find out what rev the esp chip is, else the ncr53c9x_reset
  505          * will not set up the defaults correctly.
  506          */
  507         sc->sc_cfg1 = sc->sc_id | NCRCFG1_PARENB;
  508         NCR_WRITE_REG(sc, NCR_CFG1, sc->sc_cfg1);
  509         sc->sc_cfg2 = 0;
  510         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  511         sc->sc_cfg2 = NCRCFG2_SCSI2 | NCRCFG2_RPE;
  512         NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  513 
  514         if ((NCR_READ_REG(sc, NCR_CFG2) & ~NCRCFG2_RSVD) !=
  515             (NCRCFG2_SCSI2 | NCRCFG2_RPE))
  516                 sc->sc_rev = NCR_VARIANT_ESP100;
  517         else {
  518                 sc->sc_cfg2 = NCRCFG2_SCSI2;
  519                 NCR_WRITE_REG(sc, NCR_CFG2, sc->sc_cfg2);
  520                 sc->sc_cfg3 = 0;
  521                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  522                 sc->sc_cfg3 = (NCRCFG3_CDB | NCRCFG3_FCLK);
  523                 NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  524                 if (NCR_READ_REG(sc, NCR_CFG3) !=
  525                     (NCRCFG3_CDB | NCRCFG3_FCLK))
  526                         sc->sc_rev = NCR_VARIANT_ESP100A;
  527                 else {
  528                         /* NCRCFG2_FE enables > 64K transfers. */
  529                         sc->sc_cfg2 |= NCRCFG2_FE;
  530                         sc->sc_cfg3 = 0;
  531                         NCR_WRITE_REG(sc, NCR_CFG3, sc->sc_cfg3);
  532                         if (sc->sc_freq <= 25)
  533                                 sc->sc_rev = NCR_VARIANT_ESP200;
  534                         else {
  535                                 switch ((uid & 0xf8) >> 3) {
  536                                 case 0x00:
  537                                         sc->sc_rev = NCR_VARIANT_FAS100A;
  538                                         break;
  539 
  540                                 case 0x02:
  541                                         if ((uid & 0x07) == 0x02)
  542                                                 sc->sc_rev =
  543                                                     NCR_VARIANT_FAS216;
  544                                         else
  545                                                 sc->sc_rev =
  546                                                     NCR_VARIANT_FAS236;
  547                                         break;
  548 
  549                                 case 0x0a:
  550                                         sc->sc_rev = NCR_VARIANT_FAS366;
  551                                         break;
  552 
  553                                 default:
  554                                         /*
  555                                          * We could just treat unknown chips
  556                                          * as ESP200 but then we would most
  557                                          * likely drive them out of specs.
  558                                          */
  559                                         device_printf(esc->sc_dev,
  560                                             "Unknown chip\n");
  561                                         error = ENXIO;
  562                                         goto fail_lock;
  563                                 }
  564                         }
  565                 }
  566         }
  567 
  568 #ifdef ESP_SBUS_DEBUG
  569         printf("%s: revision %d, uid 0x%x\n", __func__, sc->sc_rev, uid);
  570 #endif
  571 
  572         /*
  573          * This is the value used to start sync negotiations
  574          * Note that the NCR register "SYNCTP" is programmed
  575          * in "clocks per byte", and has a minimum value of 4.
  576          * The SCSI period used in negotiation is one-fourth
  577          * of the time (in nanoseconds) needed to transfer one byte.
  578          * Since the chip's clock is given in MHz, we have the following
  579          * formula: 4 * period = (1000 / freq) * 4
  580          */
  581         sc->sc_minsync = 1000 / sc->sc_freq;
  582 
  583         /*
  584          * Except for some variants the maximum transfer size is 64k.
  585          */
  586         sc->sc_maxxfer = 64 * 1024;
  587         sc->sc_maxoffset = 15;
  588         sc->sc_extended_geom = 1;
  589 
  590         /*
  591          * Alas, we must now modify the value a bit, because it's
  592          * only valid when we can switch on FASTCLK and FASTSCSI bits
  593          * in the config register 3...
  594          */
  595         switch (sc->sc_rev) {
  596         case NCR_VARIANT_ESP100:
  597                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
  598                 sc->sc_minsync = 0;     /* No synch on old chip? */
  599                 break;
  600 
  601         case NCR_VARIANT_ESP100A:
  602         case NCR_VARIANT_ESP200:
  603                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
  604                 /* Min clocks/byte is 5 */
  605                 sc->sc_minsync = ncr53c9x_cpb2stp(sc, 5);
  606                 break;
  607 
  608         case NCR_VARIANT_FAS100A:
  609         case NCR_VARIANT_FAS216:
  610         case NCR_VARIANT_FAS236:
  611                 /*
  612                  * The onboard SCSI chips in Sun Ultra 1 are actually
  613                  * documented to be NCR53C9X which use NCRCFG3_FCLK and
  614                  * NCRCFG3_FSCSI.  BSD/OS however probes these chips as
  615                  * FAS100A and uses NCRF9XCFG3_FCLK and NCRF9XCFG3_FSCSI
  616                  * instead which seems to be correct as otherwise sync
  617                  * negotiation just doesn't work.  Using NCRF9XCFG3_FCLK
  618                  * and NCRF9XCFG3_FSCSI with these chips in fact also
  619                  * yields Fast-SCSI speed.
  620                  */
  621                 sc->sc_features = NCR_F_FASTSCSI;
  622                 sc->sc_cfg3 = NCRF9XCFG3_FCLK;
  623                 sc->sc_cfg3_fscsi = NCRF9XCFG3_FSCSI;
  624                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_8_BIT;
  625                 sc->sc_maxxfer = 16 * 1024 * 1024;
  626                 break;
  627 
  628         case NCR_VARIANT_FAS366:
  629                 sc->sc_maxwidth = MSG_EXT_WDTR_BUS_16_BIT;
  630                 sc->sc_maxxfer = 16 * 1024 * 1024;
  631                 break;
  632         }
  633 
  634         /*
  635          * Given that we allocate resources based on sc->sc_maxxfer it doesn't
  636          * make sense to supply a value higher than the maximum actually used.
  637          */
  638         sc->sc_maxxfer = min(sc->sc_maxxfer, MAXPHYS);
  639 
  640         /* Attach the DMA engine. */
  641         error = lsi64854_attach(esc->sc_dma);
  642         if (error != 0) {
  643                 device_printf(esc->sc_dev, "lsi64854_attach failed\n");
  644                 goto fail_lock;
  645         }
  646 
  647         /* Establish interrupt channel. */
  648         i = 0;
  649         if ((esc->sc_irqres = bus_alloc_resource_any(esc->sc_dev, SYS_RES_IRQ,
  650             &i, RF_SHAREABLE|RF_ACTIVE)) == NULL) {
  651                 device_printf(esc->sc_dev, "cannot allocate interrupt\n");
  652                 goto fail_lsi;
  653         }
  654         if (bus_setup_intr(esc->sc_dev, esc->sc_irqres,
  655             INTR_MPSAFE | INTR_TYPE_CAM, NULL, ncr53c9x_intr, sc,
  656             &esc->sc_irq)) {
  657                 device_printf(esc->sc_dev, "cannot set up interrupt\n");
  658                 error = ENXIO;
  659                 goto fail_ires;
  660         }
  661 
  662         /* Turn on target selection using the `DMA' method. */
  663         if (sc->sc_rev != NCR_VARIANT_FAS366)
  664                 sc->sc_features |= NCR_F_DMASELECT;
  665 
  666         /* Do the common parts of attachment. */
  667         sc->sc_dev = esc->sc_dev;
  668         error = ncr53c9x_attach(sc);
  669         if (error != 0) {
  670                 device_printf(esc->sc_dev, "ncr53c9x_attach failed\n");
  671                 goto fail_intr;
  672         }
  673 
  674         return (0);
  675 
  676  fail_intr:
  677         bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
  678  fail_ires:
  679         bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
  680             rman_get_rid(esc->sc_irqres), esc->sc_irqres);
  681  fail_lsi:
  682         lsi64854_detach(esc->sc_dma);
  683  fail_lock:
  684         NCR_LOCK_DESTROY(sc);
  685         return (error);
  686 }
  687 
  688 static int
  689 espdetach(struct esp_softc *esc)
  690 {
  691         struct ncr53c9x_softc *sc = &esc->sc_ncr53c9x;
  692         int error;
  693 
  694         bus_teardown_intr(esc->sc_dev, esc->sc_irqres, esc->sc_irq);
  695         error = ncr53c9x_detach(sc);
  696         if (error != 0)
  697                 return (error);
  698         error = lsi64854_detach(esc->sc_dma);
  699         if (error != 0)
  700                 return (error);
  701         NCR_LOCK_DESTROY(sc);
  702         bus_release_resource(esc->sc_dev, SYS_RES_IRQ,
  703             rman_get_rid(esc->sc_irqres), esc->sc_irqres);
  704 
  705         return (0);
  706 }
  707 
  708 /*
  709  * Glue functions
  710  */
  711 
  712 #ifdef ESP_SBUS_DEBUG
  713 static int esp_sbus_debug = 0;
  714 
  715 static const struct {
  716         const char *r_name;
  717         int r_flag;
  718 } const esp__read_regnames [] = {
  719         { "TCL", 0},                    /* 0/00 */
  720         { "TCM", 0},                    /* 1/04 */
  721         { "FIFO", 0},                   /* 2/08 */
  722         { "CMD", 0},                    /* 3/0c */
  723         { "STAT", 0},                   /* 4/10 */
  724         { "INTR", 0},                   /* 5/14 */
  725         { "STEP", 0},                   /* 6/18 */
  726         { "FFLAGS", 1},                 /* 7/1c */
  727         { "CFG1", 1},                   /* 8/20 */
  728         { "STAT2", 0},                  /* 9/24 */
  729         { "CFG4", 1},                   /* a/28 */
  730         { "CFG2", 1},                   /* b/2c */
  731         { "CFG3", 1},                   /* c/30 */
  732         { "-none", 1},                  /* d/34 */
  733         { "TCH", 1},                    /* e/38 */
  734         { "TCX", 1},                    /* f/3c */
  735 };
  736 
  737 static const const struct {
  738         const char *r_name;
  739         int r_flag;
  740 } const esp__write_regnames[] = {
  741         { "TCL", 1},                    /* 0/00 */
  742         { "TCM", 1},                    /* 1/04 */
  743         { "FIFO", 0},                   /* 2/08 */
  744         { "CMD", 0},                    /* 3/0c */
  745         { "SELID", 1},                  /* 4/10 */
  746         { "TIMEOUT", 1},                /* 5/14 */
  747         { "SYNCTP", 1},                 /* 6/18 */
  748         { "SYNCOFF", 1},                /* 7/1c */
  749         { "CFG1", 1},                   /* 8/20 */
  750         { "CCF", 1},                    /* 9/24 */
  751         { "TEST", 1},                   /* a/28 */
  752         { "CFG2", 1},                   /* b/2c */
  753         { "CFG3", 1},                   /* c/30 */
  754         { "-none", 1},                  /* d/34 */
  755         { "TCH", 1},                    /* e/38 */
  756         { "TCX", 1},                    /* f/3c */
  757 };
  758 #endif
  759 
  760 static uint8_t
  761 esp_read_reg(struct ncr53c9x_softc *sc, int reg)
  762 {
  763         struct esp_softc *esc = (struct esp_softc *)sc;
  764         uint8_t v;
  765 
  766         v = bus_read_1(esc->sc_res, reg * 4);
  767 
  768 #ifdef ESP_SBUS_DEBUG
  769         if (esp_sbus_debug && (reg < 0x10) && esp__read_regnames[reg].r_flag)
  770                 printf("RD:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
  771                     esp__read_regnames[reg].r_name : "<***>", v);
  772 #endif
  773 
  774         return (v);
  775 }
  776 
  777 static void
  778 esp_write_reg(struct ncr53c9x_softc *sc, int reg, uint8_t v)
  779 {
  780         struct esp_softc *esc = (struct esp_softc *)sc;
  781 
  782 #ifdef ESP_SBUS_DEBUG
  783         if (esp_sbus_debug && (reg < 0x10) && esp__write_regnames[reg].r_flag)
  784                 printf("WR:%x <%s> %x\n", reg * 4, ((unsigned)reg < 0x10) ?
  785                     esp__write_regnames[reg].r_name : "<***>", v);
  786 #endif
  787 
  788         bus_write_1(esc->sc_res, reg * 4, v);
  789 }
  790 
  791 static int
  792 esp_dma_isintr(struct ncr53c9x_softc *sc)
  793 {
  794         struct esp_softc *esc = (struct esp_softc *)sc;
  795 
  796         return (DMA_ISINTR(esc->sc_dma));
  797 }
  798 
  799 static void
  800 esp_dma_reset(struct ncr53c9x_softc *sc)
  801 {
  802         struct esp_softc *esc = (struct esp_softc *)sc;
  803 
  804         DMA_RESET(esc->sc_dma);
  805 }
  806 
  807 static int
  808 esp_dma_intr(struct ncr53c9x_softc *sc)
  809 {
  810         struct esp_softc *esc = (struct esp_softc *)sc;
  811 
  812         return (DMA_INTR(esc->sc_dma));
  813 }
  814 
  815 static int
  816 esp_dma_setup(struct ncr53c9x_softc *sc, void **addr, size_t *len,
  817     int datain, size_t *dmasize)
  818 {
  819         struct esp_softc *esc = (struct esp_softc *)sc;
  820 
  821         return (DMA_SETUP(esc->sc_dma, addr, len, datain, dmasize));
  822 }
  823 
  824 static void
  825 esp_dma_go(struct ncr53c9x_softc *sc)
  826 {
  827         struct esp_softc *esc = (struct esp_softc *)sc;
  828 
  829         DMA_GO(esc->sc_dma);
  830 }
  831 
  832 static void
  833 esp_dma_stop(struct ncr53c9x_softc *sc)
  834 {
  835         struct esp_softc *esc = (struct esp_softc *)sc;
  836 
  837         L64854_SCSR(esc->sc_dma, L64854_GCSR(esc->sc_dma) & ~D_EN_DMA);
  838 }
  839 
  840 static int
  841 esp_dma_isactive(struct ncr53c9x_softc *sc)
  842 {
  843         struct esp_softc *esc = (struct esp_softc *)sc;
  844 
  845         return (DMA_ISACTIVE(esc->sc_dma));
  846 }

Cache object: 884ad728c14f6a10b7597478e0603b6c


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