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/pdq/if_fea.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) 1995, 1996 Matt Thomas <matt@3am-software.com>
    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. The name of the author may not be used to endorse or promote products
   11  *    derived from this software without specific prior written permission
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   23  *
   24  * $FreeBSD: releng/5.4/sys/dev/pdq/if_fea.c 127135 2004-03-17 17:50:55Z njl $
   25  */
   26 
   27 /*
   28  * DEC PDQ FDDI Controller
   29  *
   30  *      This module support the DEFEA EISA FDDI Controller.
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/socket.h>
   37 
   38 #include <sys/module.h>
   39 #include <sys/bus.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/resource.h>
   43 #include <sys/rman.h> 
   44 
   45 #include <net/if.h>
   46 #include <net/if_arp.h>
   47 #include <net/if_media.h>
   48 #include <net/fddi.h>
   49 
   50 #include <dev/eisa/eisaconf.h>
   51 
   52 #include <dev/pdq/pdq_freebsd.h>
   53 #include <dev/pdq/pdqreg.h>
   54 
   55 static void             pdq_eisa_subprobe       (pdq_bus_t, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *);
   56 static void             pdq_eisa_devinit        (pdq_softc_t *);
   57 static const char *     pdq_eisa_match          (eisa_id_t);
   58 
   59 static int              pdq_eisa_probe          (device_t);
   60 static int              pdq_eisa_attach         (device_t);
   61 static int              pdq_eisa_detach         (device_t);
   62 static int              pdq_eisa_shutdown       (device_t);
   63 static void             pdq_eisa_ifintr         (void *);
   64 
   65 #define DEFEA_IRQS                      0x0000FBA9U
   66 
   67 #define DEFEA_INTRENABLE                0x8     /* level interrupt */
   68 #define DEFEA_DECODE_IRQ(n)             ((DEFEA_IRQS >> ((n) << 2)) & 0x0f)
   69 
   70 #define EISA_DEVICE_ID_DEC_DEC3001      0x10a33001
   71 #define EISA_DEVICE_ID_DEC_DEC3002      0x10a33002
   72 #define EISA_DEVICE_ID_DEC_DEC3003      0x10a33003
   73 #define EISA_DEVICE_ID_DEC_DEC3004      0x10a33004
   74 
   75 static void
   76 pdq_eisa_subprobe(bc, iobase, maddr, msize, irq)
   77         pdq_bus_t       bc;
   78         u_int32_t       iobase;
   79         u_int32_t       *maddr;
   80         u_int32_t       *msize;
   81         u_int32_t       *irq;
   82 {
   83         if (irq != NULL)
   84                 *irq = DEFEA_DECODE_IRQ(PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_IO_CONFIG_STAT_0) & 3);
   85         *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8)
   86                  | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16);
   87         *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
   88 
   89         return;
   90 }
   91 
   92 static void
   93 pdq_eisa_devinit (sc)
   94         pdq_softc_t     *sc;
   95 {
   96         pdq_uint8_t     data;
   97 
   98         /*
   99          * Do the standard initialization for the DEFEA registers.
  100          */
  101         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_FUNCTION_CTRL, 0x23);
  102         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_1_1, (sc->io_bsh >> 8) & 0xF0);
  103         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CMP_0_1, (sc->io_bsh >> 8) & 0xF0);
  104         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_SLOT_CTRL, 0x01);
  105         data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF);
  106 #if defined(PDQ_IOMAPPED)
  107         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data & ~1);
  108 #else
  109         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_BURST_HOLDOFF, data | 1);
  110 #endif
  111         data = PDQ_OS_IORD_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0);
  112         PDQ_OS_IOWR_8(sc->io_bst, sc->io_bsh, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE);
  113 
  114         return;
  115 }
  116 
  117 static const char *
  118 pdq_eisa_match (type)
  119         eisa_id_t       type;
  120 {
  121         switch (type) {
  122                 case EISA_DEVICE_ID_DEC_DEC3001:
  123                 case EISA_DEVICE_ID_DEC_DEC3002:
  124                 case EISA_DEVICE_ID_DEC_DEC3003:
  125                 case EISA_DEVICE_ID_DEC_DEC3004:
  126                         return ("DEC FDDIcontroller/EISA Adapter");
  127                         break;
  128                  default:
  129                         break;
  130         }
  131         return (NULL);
  132 }
  133 
  134 static int
  135 pdq_eisa_probe (dev)
  136         device_t        dev;
  137 {
  138         const char      *desc;
  139         u_int32_t       iobase;
  140         u_int32_t       irq;
  141         u_int32_t       maddr;
  142         u_int32_t       msize;
  143 
  144         u_int32_t       eisa_id = eisa_get_id(dev);;
  145 
  146         desc = pdq_eisa_match(eisa_id);
  147         if (!desc) {
  148                 return (ENXIO);
  149         }
  150 
  151         device_set_desc(dev, desc);
  152 
  153         iobase = eisa_get_slot(dev) * EISA_SLOT_SIZE;
  154         pdq_eisa_subprobe((pdq_bus_t)SYS_RES_IOPORT, iobase, &maddr, &msize, &irq);
  155 
  156         eisa_add_iospace(dev, iobase, 0x200, RESVADDR_NONE);
  157         eisa_add_mspace(dev, maddr, msize, RESVADDR_NONE);
  158         eisa_add_intr(dev, irq, EISA_TRIGGER_LEVEL);
  159         
  160         return (0);
  161 }
  162 
  163 static void
  164 pdq_eisa_ifintr(arg)
  165         void *          arg;
  166 {
  167         device_t        dev;
  168         pdq_softc_t *   sc;
  169 
  170         dev = (device_t)arg;
  171         sc = device_get_softc(dev);
  172 
  173         PDQ_LOCK(sc);
  174         (void) pdq_interrupt(sc->sc_pdq);
  175         PDQ_LOCK(sc);
  176 
  177         return;
  178 }
  179 
  180 static int
  181 pdq_eisa_attach (dev)
  182         device_t        dev;
  183 {
  184         pdq_softc_t *   sc;
  185         struct ifnet *  ifp;
  186         int             error;
  187 
  188         sc = device_get_softc(dev);
  189         ifp = &sc->arpcom.ac_if;
  190 
  191         sc->dev = dev;
  192 
  193         sc->io_rid = 0;
  194         sc->io_type = SYS_RES_IOPORT;
  195         sc->io = bus_alloc_resource_any(dev, sc->io_type, &sc->io_rid,
  196                                         RF_ACTIVE);
  197         if (!sc->io) {
  198                 device_printf(dev, "Unable to allocate I/O space resource.\n");
  199                 error = ENXIO;
  200                 goto bad;
  201         }
  202         sc->io_bsh = rman_get_bushandle(sc->io);
  203         sc->io_bst = rman_get_bustag(sc->io);
  204 
  205         sc->mem_rid = 0;
  206         sc->mem_type = SYS_RES_MEMORY;
  207         sc->mem = bus_alloc_resource_any(dev, sc->mem_type, &sc->mem_rid,
  208                                          RF_ACTIVE);
  209         if (!sc->mem) {
  210                 device_printf(dev, "Unable to allocate memory resource.\n");
  211                 error = ENXIO;
  212                 goto bad;
  213         }
  214         sc->mem_bsh = rman_get_bushandle(sc->mem);
  215         sc->mem_bst = rman_get_bustag(sc->mem);
  216 
  217         sc->irq_rid = 0;
  218         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  219                                          RF_SHAREABLE | RF_ACTIVE);
  220         if (!sc->irq) {
  221                 device_printf(dev, "Unable to allocate interrupt resource.\n");
  222                 error = ENXIO;
  223                 goto bad;
  224         }
  225 
  226         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  227 
  228         pdq_eisa_devinit(sc);
  229         sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh,
  230                                     ifp->if_xname, -1,
  231                                     (void *)sc, PDQ_DEFEA);
  232         if (sc->sc_pdq == NULL) {
  233                 device_printf(dev, "Initialization failed.\n");
  234                 error = ENXIO;
  235                 goto bad;
  236         }
  237 
  238         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
  239                                pdq_eisa_ifintr, dev, &sc->irq_ih);
  240         if (error) {
  241                 device_printf(dev, "Failed to setup interrupt handler.\n");
  242                 error = ENXIO;
  243                 goto bad;
  244         }
  245 
  246         bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
  247               (caddr_t) sc->arpcom.ac_enaddr, FDDI_ADDR_LEN);
  248         pdq_ifattach(sc);
  249 
  250         return (0);
  251 bad:
  252         pdq_free(dev);
  253         return (error);
  254 }
  255 
  256 static int
  257 pdq_eisa_detach (dev)
  258         device_t        dev;
  259 {
  260         pdq_softc_t *   sc;
  261 
  262         sc = device_get_softc(dev);
  263         pdq_ifdetach(sc);
  264 
  265         return (0);
  266 }
  267 
  268 static int
  269 pdq_eisa_shutdown(dev)
  270         device_t        dev;
  271 {
  272         pdq_softc_t *   sc;
  273 
  274         sc = device_get_softc(dev);
  275         pdq_hwreset(sc->sc_pdq);
  276 
  277         return (0);
  278 }
  279 
  280 static device_method_t pdq_eisa_methods[] = {
  281         DEVMETHOD(device_probe,         pdq_eisa_probe),
  282         DEVMETHOD(device_attach,        pdq_eisa_attach),
  283         DEVMETHOD(device_attach,        pdq_eisa_detach),
  284         DEVMETHOD(device_shutdown,      pdq_eisa_shutdown),
  285 
  286         { 0, 0 }
  287 };
  288 
  289 static driver_t pdq_eisa_driver = {
  290         "fea",
  291         pdq_eisa_methods,
  292         sizeof(pdq_softc_t),
  293 };
  294 
  295 DRIVER_MODULE(fea, eisa, pdq_eisa_driver, pdq_devclass, 0, 0);
  296 /* MODULE_DEPEND(fea, eisa, 1, 1, 1); */
  297 MODULE_DEPEND(fea, fddi, 1, 1, 1);

Cache object: 80f56020db9d67dc1dc746e1d21cf28c


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