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 withough 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$
   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 <net/if.h>
   39 #include <net/if_arp.h>
   40 
   41 #include <sys/module.h>
   42 #include <sys/bus.h>
   43 #include <machine/bus.h>
   44 #include <machine/resource.h>
   45 #include <sys/rman.h> 
   46 #include <dev/eisa/eisaconf.h>
   47 #include <dev/pdq/pdqvar.h>
   48 #include <dev/pdq/pdqreg.h>
   49 
   50 static void             pdq_eisa_subprobe       __P((pdq_bus_t, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *));
   51 static void             pdq_eisa_devinit        __P((pdq_softc_t *));
   52 static const char *     pdq_eisa_match          __P((eisa_id_t));
   53 static int              pdq_eisa_probe          __P((device_t));
   54 static int              pdq_eisa_attach         __P((device_t));
   55 void                    pdq_eisa_intr           __P((void *));
   56 static int              pdq_eisa_shutdown       __P((device_t));
   57 
   58 #define DEFEA_IRQS                      0x0000FBA9U
   59 
   60 #define DEFEA_INTRENABLE                0x8     /* level interrupt */
   61 #define DEFEA_DECODE_IRQ(n)             ((DEFEA_IRQS >> ((n) << 2)) & 0x0f)
   62 
   63 #define EISA_DEVICE_ID_DEC_DEC3001      0x10a33001
   64 #define EISA_DEVICE_ID_DEC_DEC3002      0x10a33002
   65 #define EISA_DEVICE_ID_DEC_DEC3003      0x10a33003
   66 #define EISA_DEVICE_ID_DEC_DEC3004      0x10a33004
   67 
   68 static void
   69 pdq_eisa_subprobe(bc, iobase, maddr, msize, irq)
   70         pdq_bus_t       bc;
   71         u_int32_t       iobase;
   72         u_int32_t       *maddr;
   73         u_int32_t       *msize;
   74         u_int32_t       *irq;
   75 {
   76         if (irq != NULL)
   77                 *irq = DEFEA_DECODE_IRQ(PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_IO_CONFIG_STAT_0) & 3);
   78         *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8)
   79                  | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16);
   80         *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
   81 
   82         return;
   83 }
   84 
   85 static void
   86 pdq_eisa_devinit (sc)
   87         pdq_softc_t     *sc;
   88 {
   89         pdq_uint8_t     data;
   90 
   91         /*
   92          * Do the standard initialization for the DEFEA registers.
   93          */
   94         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23);
   95         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1, (sc->sc_iobase >> 8) & 0xF0);
   96         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1, (sc->sc_iobase >> 8) & 0xF0);
   97         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01);
   98         data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF);
   99 #if defined(PDQ_IOMAPPED)
  100         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1);
  101 #else
  102         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1);
  103 #endif
  104         data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0);
  105         PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE);
  106 
  107         return;
  108 }
  109 
  110 static const char *
  111 pdq_eisa_match (type)
  112         eisa_id_t       type;
  113 {
  114         switch (type) {
  115                 case EISA_DEVICE_ID_DEC_DEC3001:
  116                 case EISA_DEVICE_ID_DEC_DEC3002:
  117                 case EISA_DEVICE_ID_DEC_DEC3003:
  118                 case EISA_DEVICE_ID_DEC_DEC3004:
  119                         return ("DEC FDDIcontroller/EISA Adapter");
  120                         break;
  121                  default:
  122                         break;
  123         }
  124         return (NULL);
  125 }
  126 
  127 static int
  128 pdq_eisa_probe (dev)
  129         device_t        dev;
  130 {
  131         const char      *desc;
  132         u_int32_t       iobase;
  133         u_int32_t       irq;
  134         u_int32_t       maddr;
  135         u_int32_t       msize;
  136 
  137         u_int32_t       eisa_id = eisa_get_id(dev);;
  138 
  139         desc = pdq_eisa_match(eisa_id);
  140         if (!desc) {
  141                 return (ENXIO);
  142         }
  143 
  144         device_set_desc(dev, desc);
  145 
  146         iobase = eisa_get_slot(dev) * EISA_SLOT_SIZE;
  147         pdq_eisa_subprobe(PDQ_BUS_EISA, iobase, &maddr, &msize, &irq);
  148 
  149         eisa_add_iospace(dev, iobase, 0x200, RESVADDR_NONE);
  150         eisa_add_mspace(dev, maddr, msize, RESVADDR_NONE);
  151         eisa_add_intr(dev, irq, EISA_TRIGGER_LEVEL);
  152         
  153         return (0);
  154 }
  155 
  156 void
  157 pdq_eisa_intr(xdev)
  158         void            *xdev;
  159 {
  160         device_t        dev = (device_t) xdev;
  161         pdq_softc_t     *sc = device_get_softc(dev);
  162         (void) pdq_interrupt(sc->sc_pdq);
  163 
  164         return;
  165 }
  166 
  167 static int
  168 pdq_eisa_attach (dev)
  169         device_t                dev;
  170 {
  171         pdq_softc_t             *sc = device_get_softc(dev);
  172         struct resource         *io = 0;
  173         struct resource         *irq = 0;
  174         struct resource         *mspace = 0;
  175         int                     rid;
  176         void                    *ih;
  177         u_int32_t               m_addr, m_size;
  178 
  179         rid = 0;
  180         io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
  181                                 0, ~0, 1, RF_ACTIVE);
  182 
  183         if (!io) {
  184                 device_printf(dev, "No I/O space?!\n");
  185                 goto bad;
  186         }
  187 
  188         rid = 0;
  189         mspace = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
  190                                     0, ~0, 1, RF_ACTIVE);
  191 
  192         if (!mspace) {
  193                 device_printf(dev, "No memory space?!\n");
  194                 goto bad;
  195         }
  196 
  197         rid = 0;
  198         irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
  199                                  0, ~0, 1, RF_ACTIVE);
  200 
  201         if (!irq) {
  202                 device_printf(dev, "No, irq?!\n");
  203                 goto bad;
  204         }
  205 
  206         m_addr = rman_get_start(mspace);
  207         m_size = (rman_get_end(mspace) - rman_get_start(mspace)) + 1;
  208 
  209         sc->sc_iobase = (pdq_bus_ioport_t) rman_get_start(io);
  210         sc->sc_membase = (pdq_bus_memaddr_t) pmap_mapdev(m_addr, m_size);
  211         sc->sc_if.if_name = "fea";
  212         sc->sc_if.if_unit = device_get_unit(dev);
  213 
  214         pdq_eisa_devinit(sc);
  215         sc->sc_pdq = pdq_initialize(PDQ_BUS_EISA, sc->sc_membase,
  216                                     sc->sc_if.if_name, sc->sc_if.if_unit,
  217                                     (void *) sc, PDQ_DEFEA);
  218         if (sc->sc_pdq == NULL) {
  219                 device_printf(dev, "initialization failed\n");
  220                 goto bad;
  221         }
  222 
  223         if (bus_setup_intr(dev, irq, INTR_TYPE_NET, pdq_eisa_intr, dev, &ih)) {
  224                 goto bad;
  225         }
  226 
  227         bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6);
  228         pdq_ifattach(sc, NULL);
  229 
  230         return (0);
  231 
  232 bad:
  233         if (io)
  234                 bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
  235         if (irq)
  236                 bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
  237         if (mspace)
  238                 bus_release_resource(dev, SYS_RES_MEMORY, 0, mspace);
  239 
  240         return (-1);
  241 }
  242 
  243 static int
  244 pdq_eisa_shutdown(dev)
  245         device_t        dev;
  246 {
  247         pdq_softc_t     *sc = device_get_softc(dev);
  248 
  249         pdq_hwreset(sc->sc_pdq);
  250 
  251         return (0);
  252 }
  253 
  254 static device_method_t pdq_eisa_methods[] = {
  255         DEVMETHOD(device_probe,         pdq_eisa_probe),
  256         DEVMETHOD(device_attach,        pdq_eisa_attach),
  257         DEVMETHOD(device_shutdown,      pdq_eisa_shutdown),
  258 
  259         { 0, 0 }
  260 };
  261 
  262 static driver_t pdq_eisa_driver = {
  263         "fea",
  264         pdq_eisa_methods,
  265         sizeof(pdq_softc_t),
  266 };
  267 
  268 static devclass_t pdq_devclass;
  269 
  270 DRIVER_MODULE(pdq, eisa, pdq_eisa_driver, pdq_devclass, 0, 0);

Cache object: 355b9c12e899db8e22a5ffc23b1a1f77


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