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/zs/zs_macio.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  * Copyright (c) 2003 Jake Burkholder, Benno Rice.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/6.4/sys/dev/zs/zs_macio.c 133589 2004-08-12 17:41:33Z marius $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/module.h>
   33 #include <sys/bus.h>
   34 #include <sys/interrupt.h>
   35 #include <sys/kernel.h>
   36 #include <machine/bus.h>
   37 #include <machine/resource.h>
   38 #include <sys/rman.h>
   39 
   40 #include <dev/ofw/ofw_bus.h>
   41 #include <dev/ofw/openfirm.h>
   42 
   43 #include <dev/zs/z8530reg.h>
   44 #include <dev/zs/z8530var.h>
   45 
   46 #define ZS_MACIO_CHAN_A 32
   47 #define ZS_MACIO_CHAN_B 0
   48 
   49 #define ZS_MACIO_CSR    0
   50 #define ZS_MACIO_DATA   16
   51 
   52 #define ZS_MACIO_DEF_SPEED      (57600)
   53 
   54 #define ZS_MACIO_CLOCK          (9600 * 384)
   55 #define ZS_MACIO_CLOCK_DIV      (16)
   56 
   57 struct zs_macio_softc {
   58         struct zs_softc         sc_zs;
   59         struct resource         *sc_irqres1, *sc_irqres2;
   60         int                     sc_irqrid1, sc_irqrid2;
   61         void                    *sc_ih1, *sc_ih2;
   62         struct resource         *sc_memres;
   63         int                     sc_memrid;
   64 };
   65 
   66 static int zs_macio_attach(device_t dev);
   67 static int zs_macio_detach(device_t dev);
   68 static int zs_macio_probe(device_t dev);
   69 
   70 static int zstty_macio_attach(device_t dev);
   71 static int zstty_macio_probe(device_t dev);
   72 
   73 static device_method_t zs_macio_methods[] = {
   74         DEVMETHOD(device_probe,         zs_macio_probe),
   75         DEVMETHOD(device_attach,        zs_macio_attach),
   76         DEVMETHOD(device_detach,        zs_macio_detach),
   77 
   78         DEVMETHOD(bus_print_child,      bus_generic_print_child),
   79 
   80         { 0, 0 }
   81 };
   82 
   83 static device_method_t zstty_macio_methods[] = {
   84         DEVMETHOD(device_probe,         zstty_macio_probe),
   85         DEVMETHOD(device_attach,        zstty_macio_attach),
   86         DEVMETHOD(device_detach,        bus_generic_detach),
   87 
   88         { 0, 0}
   89 };
   90 
   91 static driver_t zs_macio_driver = {
   92         "zs",
   93         zs_macio_methods,
   94         sizeof(struct zs_macio_softc),
   95 };
   96 
   97 static driver_t zstty_macio_driver = {
   98         "zstty",
   99         zstty_macio_methods,
  100         sizeof(struct zstty_softc),
  101 };
  102 
  103 static devclass_t zs_macio_devclass;
  104 static devclass_t zstty_macio_devclass;
  105 
  106 DRIVER_MODULE(zstty, zs, zstty_macio_driver, zstty_macio_devclass, 0, 0);
  107 DRIVER_MODULE(zs, macio, zs_macio_driver, zs_macio_devclass, 0, 0);
  108 
  109 static u_char zs_macio_init_reg[16] = {
  110         0,      /* 0: CMD (reset, etc.) */
  111         0,      /* 1: No interrupts yet. */
  112         0,      /* IVECT */
  113         ZSWR3_RX_8 | ZSWR3_RX_ENABLE,
  114         ZSWR4_CLK_X16 | ZSWR4_ONESB,
  115         ZSWR5_TX_8 | ZSWR5_TX_ENABLE,
  116         0,      /* 6: TXSYNC/SYNCLO */
  117         0,      /* 7: RXSYNC/SYNCHI */
  118         0,      /* 8: alias for data port */
  119         ZSWR9_MASTER_IE | ZSWR9_NO_VECTOR,
  120         0,      /*10: Misc. TX/RX control bits */
  121         ZSWR11_TXCLK_BAUD | ZSWR11_RXCLK_BAUD,
  122 #if 0
  123         ((ZS_MACIO_CLOCK/32)/ZS_MACIO_DEF_SPEED)-2,
  124 #endif
  125         BPS_TO_TCONST((ZS_MACIO_CLOCK / ZS_MACIO_CLOCK_DIV), ZS_MACIO_DEF_SPEED),
  126         0,
  127         ZSWR14_BAUD_ENA,
  128         ZSWR15_BREAK_IE,
  129 };
  130 
  131 static int
  132 zs_macio_probe(device_t dev)
  133 {
  134 
  135         if (strcmp(ofw_bus_get_name(dev), "escc") != 0 ||
  136             device_get_unit(dev) != 0)
  137                 return (ENXIO);
  138         return (zs_probe(dev));
  139 }
  140 
  141 static int
  142 zs_macio_attach(device_t dev)
  143 {
  144         struct  zs_macio_softc *sc;
  145 
  146         sc = device_get_softc(dev);
  147 
  148         sc->sc_memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  149             &sc->sc_memrid, RF_ACTIVE);
  150         if (sc->sc_memres == NULL) {
  151                 device_printf(dev, "could not allocate memory\n");
  152                 goto error;
  153         }
  154         sc->sc_irqrid1 = 0;
  155         sc->sc_irqres1 = bus_alloc_resource_any(dev, SYS_RES_IRQ,
  156             &sc->sc_irqrid1, RF_ACTIVE);
  157         if (sc->sc_irqres1 == NULL) {
  158                 device_printf(dev, "could not allocate interrupt 1\n");
  159                 goto error;
  160         }
  161         if (bus_setup_intr(dev, sc->sc_irqres1, INTR_TYPE_TTY | INTR_FAST,
  162             zs_intr, sc, &sc->sc_ih1) != 0) {
  163                 device_printf(dev, "could not setup interrupt 1\n");
  164                 goto error;
  165         }
  166         sc->sc_irqrid2 = 1;
  167         sc->sc_irqres2 = bus_alloc_resource_any(dev, SYS_RES_IRQ,
  168             &sc->sc_irqrid2, RF_ACTIVE);
  169         if (sc->sc_irqres2 == NULL) {
  170                 device_printf(dev, "could not allocate interrupt 2\n");
  171                 goto error;
  172         }
  173         if (bus_setup_intr(dev, sc->sc_irqres2, INTR_TYPE_TTY | INTR_FAST,
  174             zs_intr, sc, &sc->sc_ih2) != 0) {
  175                 device_printf(dev, "could not setup interrupt 2\n");
  176                 goto error;
  177         }
  178         sc->sc_zs.sc_bt = rman_get_bustag(sc->sc_memres);
  179         sc->sc_zs.sc_bh = rman_get_bushandle(sc->sc_memres);
  180         return (zs_attach(dev));
  181 
  182 error:
  183         zs_macio_detach(dev);
  184         return (ENXIO);
  185 }
  186 
  187 static int
  188 zs_macio_detach(device_t dev)
  189 {
  190         struct zs_macio_softc *sc;
  191 
  192         sc = device_get_softc(dev);
  193         if (sc->sc_irqres2 != NULL) {
  194                 if (sc->sc_ih2 != NULL)
  195                         bus_teardown_intr(dev, sc->sc_irqres2, sc->sc_ih2);
  196                 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid2,
  197                     sc->sc_irqres2);
  198         }
  199         if (sc->sc_irqres1 != NULL) {
  200                 if (sc->sc_ih1 != NULL)
  201                         bus_teardown_intr(dev, sc->sc_irqres1, sc->sc_ih1);
  202                 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irqrid1,
  203                     sc->sc_irqres1);
  204         }
  205         if (sc->sc_memres != NULL)
  206                 bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_memrid,
  207                     sc->sc_memres);
  208         return (0);
  209 }
  210 
  211 static int
  212 zstty_macio_probe(device_t dev)
  213 {
  214 
  215         if ((device_get_unit(dev) & 1) == 0)
  216                 device_set_desc(dev, "ttya");
  217         else
  218                 device_set_desc(dev, "ttyb");
  219 
  220         return (zstty_probe(dev));
  221 }
  222 
  223 static int
  224 zstty_macio_attach(device_t dev)
  225 {
  226         struct  zstty_softc *sc;
  227 
  228         sc = device_get_softc(dev);
  229         sc->sc_parent = device_get_softc(device_get_parent(dev));
  230         sc->sc_bt = sc->sc_parent->sc_bt;
  231         sc->sc_brg_clk = ZS_MACIO_CLOCK / ZS_MACIO_CLOCK_DIV;
  232 
  233         switch (device_get_unit(dev) & 1) {
  234         case 0:
  235                 bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
  236                     ZS_MACIO_CHAN_A + ZS_MACIO_CSR, 1, &sc->sc_csr);
  237                 bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
  238                     ZS_MACIO_CHAN_A + ZS_MACIO_DATA, 1, &sc->sc_data);
  239                 break;
  240 
  241         case 1:
  242                 bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
  243                     ZS_MACIO_CHAN_B + ZS_MACIO_CSR, 1, &sc->sc_csr);
  244                 bus_space_subregion(sc->sc_bt, sc->sc_parent->sc_bh,
  245                     ZS_MACIO_CHAN_B + ZS_MACIO_DATA, 1, &sc->sc_data);
  246                 break;
  247         }
  248 
  249         bcopy(zs_macio_init_reg, sc->sc_creg, 16);
  250         bcopy(zs_macio_init_reg, sc->sc_preg, 16);
  251 
  252         return (zstty_attach(dev));
  253 }
  254 
  255 void
  256 zstty_set_speed(struct zstty_softc *sc, int ospeed)
  257 {
  258 
  259         sc->sc_preg[12] = ospeed;
  260         sc->sc_preg[13] = ospeed >> 8;
  261 }
  262 
  263 int
  264 zstty_console(device_t dev, char *mode, int len)
  265 {
  266         phandle_t       chosen, options, parent;
  267         ihandle_t       stdin, stdout;
  268         phandle_t       stdinp, stdoutp;
  269         char            input[32], output[32];
  270         const char      *desc;
  271 
  272         chosen = OF_finddevice("/chosen");
  273         options = OF_finddevice("/options");
  274         parent = ofw_bus_get_node(device_get_parent(dev));
  275         if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1 ||
  276             OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1 ||
  277             OF_getprop(options, "input-device", input, sizeof(input)) == -1 ||
  278             OF_getprop(options, "output-device", output,
  279             sizeof(output)) == -1) {
  280                 return (0);
  281         }
  282         stdinp = OF_parent(OF_instance_to_package(stdin));
  283         stdoutp = OF_parent(OF_instance_to_package(stdout));
  284         desc = device_get_desc(dev);
  285         if (parent == stdinp && parent == stdoutp &&
  286             input[3] == desc[3] && output[3] == desc[3]) {
  287                 if (mode != NULL)
  288                         strlcpy(mode, "57600,8,n,1,-", len);
  289 
  290                 return (1);
  291         }
  292 
  293         return (0);
  294 }

Cache object: 2f983030bca0509a06e0d0826c2ffaa9


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