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/isa/if_fmv_isa.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: if_fmv_isa.c,v 1.2 2002/10/05 17:52:32 tsutsui Exp $   */
    2 
    3 /*
    4  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
    5  *
    6  * This software may be used, modified, copied, distributed, and sold, in
    7  * both source and binary form provided that the above copyright, these
    8  * terms and the following disclaimer are retained.  The name of the author
    9  * and/or the contributor may not be used to endorse or promote products
   10  * derived from this software without specific prior written permission.
   11  *
   12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
   13  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   14  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   15  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
   16  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   17  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   18  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
   19  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   20  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   21  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   22  * SUCH DAMAGE.
   23  */
   24 
   25 /*
   26  * Portions copyright (C) 1993, David Greenman.  This software may be used,
   27  * modified, copied, distributed, and sold, in both source and binary form
   28  * provided that the above copyright and these terms are retained.  Under no
   29  * circumstances is the author responsible for the proper functioning of this
   30  * software, nor does the author assume any responsibility for damages
   31  * incurred with its use.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __KERNEL_RCSID(0, "$NetBSD: if_fmv_isa.c,v 1.2 2002/10/05 17:52:32 tsutsui Exp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/device.h>
   40 
   41 #include <net/if.h>
   42 #include <net/if_ether.h>
   43 #include <net/if_media.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/intr.h>
   47 
   48 #include <dev/ic/mb86960reg.h>
   49 #include <dev/ic/mb86960var.h>
   50 #include <dev/ic/fmvreg.h>
   51 #include <dev/ic/fmvvar.h>
   52 
   53 #include <dev/isa/isavar.h>
   54 
   55 int     fmv_isa_match __P((struct device *, struct cfdata *, void *));
   56 void    fmv_isa_attach __P((struct device *, struct device *, void *));
   57 
   58 struct fmv_isa_softc {
   59         struct  mb86960_softc sc_mb86960;       /* real "mb86960" softc */
   60 
   61         /* ISA-specific goo. */
   62         void    *sc_ih;                         /* interrupt cookie */
   63 };
   64 
   65 CFATTACH_DECL(fmv_isa, sizeof(struct fmv_isa_softc),
   66     fmv_isa_match, fmv_isa_attach, NULL, NULL);
   67 
   68 struct fe_simple_probe_struct {
   69         u_int8_t port;  /* Offset from the base I/O address. */
   70         u_int8_t mask;  /* Bits to be checked. */
   71         u_int8_t bits;  /* Values to be compared against. */
   72 };
   73 
   74 static __inline__ int fe_simple_probe __P((bus_space_tag_t, 
   75     bus_space_handle_t, struct fe_simple_probe_struct const *));
   76 static int fmv_find __P((bus_space_tag_t, bus_space_handle_t, int *, int *));
   77 
   78 static int const fmv_iomap[8] = {
   79         0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340
   80 };
   81 #define NFMV_IOMAP (sizeof (fmv_iomap) / sizeof (fmv_iomap[0]))
   82 #define FMV_NPORTS 0x20
   83 
   84 /*
   85  * Hardware probe routines.
   86  */
   87 
   88 /*
   89  * Determine if the device is present.
   90  */
   91 int
   92 fmv_isa_match(parent, match, aux)
   93         struct device *parent;
   94         struct cfdata *match;
   95         void *aux;
   96 {
   97         struct isa_attach_args *ia = aux;
   98         bus_space_tag_t iot = ia->ia_iot;
   99         bus_space_handle_t ioh;
  100         int i, iobase, irq, rv = 0;
  101         u_int8_t myea[ETHER_ADDR_LEN];
  102 
  103         if (ia->ia_nio < 1)
  104                 return (0);
  105         if (ia->ia_nirq < 1)
  106                 return (0);
  107 
  108         if (ISA_DIRECT_CONFIG(ia))
  109                 return (0);
  110 
  111         /* Disallow wildcarded values. */
  112         if (ia->ia_io[0].ir_addr == ISACF_PORT_DEFAULT)
  113                 return (0);
  114 
  115         /*
  116          * See if the sepcified address is valid for FMV-180 series.
  117          */
  118         for (i = 0; i < NFMV_IOMAP; i++)
  119                 if (fmv_iomap[i] == ia->ia_io[0].ir_addr)
  120                         break;
  121         if (i == NFMV_IOMAP) {
  122 #ifdef FMV_DEBUG
  123                 printf("fmv_match: unknown iobase 0x%x\n",
  124                     ia->ia_io[0].ir_addr);
  125 #endif
  126                 return (0);
  127         }
  128 
  129         /* Map i/o space. */
  130         if (bus_space_map(iot, ia->ia_io[0].ir_addr, FMV_NPORTS, 0, &ioh)) {
  131 #ifdef FMV_DEBUG
  132                 printf("fmv_match: couldn't map iospace 0x%x\n",
  133                     ia->ia_io[0].ir_addr);
  134 #endif
  135                 return (0);
  136         }
  137 
  138         if (fmv_find(iot, ioh, &iobase, &irq) == 0) {
  139 #ifdef FMV_DEBUG
  140                 printf("fmv_match: fmv_find failed\n");
  141 #endif
  142                 goto out;
  143         }
  144 
  145         if (iobase != ia->ia_io[0].ir_addr) {
  146 #ifdef FMV_DEBUG
  147                 printf("fmv_match: unexpected iobase in board: 0x%x\n",
  148                     iobase);
  149 #endif
  150                 goto out;
  151         }
  152 
  153         if (fmv_detect(iot, ioh, myea) == 0) { /* XXX necessary? */
  154 #ifdef FMV_DEBUG
  155                 printf("fmv_match: fmv_detect failed\n");
  156 #endif
  157                 goto out;
  158         }
  159 
  160         if (ia->ia_irq[0].ir_irq != ISACF_IRQ_DEFAULT) {
  161                 if (ia->ia_irq[0].ir_irq != irq) {
  162                         printf("fmv_match: irq mismatch; "
  163                             "kernel configured %d != board configured %d\n",
  164                             ia->ia_irq[0].ir_irq, irq);
  165                         goto out;
  166                 }
  167         } else
  168                 ia->ia_irq[0].ir_irq = irq;
  169 
  170         ia->ia_nio = 1;
  171         ia->ia_io[0].ir_size = FMV_NPORTS;
  172 
  173         ia->ia_nirq = 1;
  174 
  175         ia->ia_niomem = 0;
  176         ia->ia_ndrq = 0;
  177 
  178         rv = 1;
  179 
  180  out:
  181         bus_space_unmap(iot, ioh, FMV_NPORTS);
  182         return (rv);
  183 }
  184 
  185 /*
  186  * Check for specific bits in specific registers have specific values.
  187  */
  188 static __inline__ int
  189 fe_simple_probe (iot, ioh, sp)
  190         bus_space_tag_t iot;
  191         bus_space_handle_t ioh;
  192         struct fe_simple_probe_struct const *sp;
  193 {
  194         u_int8_t val;
  195         struct fe_simple_probe_struct const *p;
  196 
  197         for (p = sp; p->mask != 0; p++) {
  198                 val = bus_space_read_1(iot, ioh, p->port);
  199                 if ((val & p->mask) != p->bits) {
  200 #ifdef FMV_DEBUG
  201                         printf("fe_simple_probe: %x & %x != %x\n",
  202                             val, p->mask, p->bits);
  203 #endif
  204                         return (0);
  205                 }
  206         }
  207 
  208         return (1);
  209 }
  210 
  211 /*
  212  * Hardware (vendor) specific probe routines.
  213  */
  214 
  215 /*
  216  * Probe Fujitsu FMV-180 series boards and get iobase and irq from
  217  * board.
  218  */
  219 static int
  220 fmv_find(iot, ioh, iobase, irq)
  221         bus_space_tag_t iot;
  222         bus_space_handle_t ioh;
  223         int *iobase, *irq;
  224 {
  225         u_int8_t config;
  226         static int const fmv_irqmap[4] = { 3, 7, 10, 15 };
  227         static struct fe_simple_probe_struct const probe_table[] = {
  228                 { FE_DLCR2, 0x70, 0x00 },
  229                 { FE_DLCR4, 0x08, 0x00 },
  230             /*  { FE_DLCR5, 0x80, 0x00 },       Doesn't work. */
  231 
  232                 { FE_FMV0, FE_FMV0_MAGIC_MASK, FE_FMV0_MAGIC_VALUE },
  233                 { FE_FMV1, FE_FMV1_MAGIC_MASK, FE_FMV1_MAGIC_VALUE },
  234                 { FE_FMV3, FE_FMV3_EXTRA_MASK, FE_FMV3_EXTRA_VALUE },
  235 #if 1
  236         /*
  237          * Test *vendor* part of the station address for Fujitsu.
  238          * The test will gain reliability of probe process, but
  239          * it rejects FMV-180 clone boards manufactured by other vendors.
  240          * We have to turn the test off when such cards are made available.
  241          */
  242                 { FE_FMV4, 0xFF, 0x00 },
  243                 { FE_FMV5, 0xFF, 0x00 },
  244                 { FE_FMV6, 0xFF, 0x0E },
  245 #else
  246         /*
  247          * We can always verify the *first* 2 bits (in Ehternet
  248          * bit order) are "no multicast" and "no local" even for
  249          * unknown vendors.
  250          */
  251                 { FE_FMV4, 0x03, 0x00 },
  252 #endif
  253                 { 0 }
  254         };
  255 
  256         /* Simple probe. */
  257         if (!fe_simple_probe(iot, ioh, probe_table))
  258                 return (0);
  259 
  260         /* Check if our I/O address matches config info on EEPROM. */
  261         config = bus_space_read_1(iot, ioh, FE_FMV2);
  262         *iobase = fmv_iomap[(config & FE_FMV2_ADDR) >> FE_FMV2_ADDR_SHIFT];
  263 
  264         /*
  265          * Determine which IRQ to be used.
  266          *
  267          * In this version, we always get an IRQ assignment from the
  268          * FMV-180's configuration EEPROM, ignoring that specified in
  269          * config file.
  270          */
  271         *irq = fmv_irqmap[(config & FE_FMV2_IRQ) >> FE_FMV2_IRQ_SHIFT];
  272 
  273         return (1);
  274 }
  275 
  276 void
  277 fmv_isa_attach(parent, self, aux)
  278         struct device *parent, *self;
  279         void *aux;
  280 {
  281         struct fmv_isa_softc *isc = (struct fmv_isa_softc *)self;
  282         struct mb86960_softc *sc = &isc->sc_mb86960;
  283         struct isa_attach_args *ia = aux;
  284         bus_space_tag_t iot = ia->ia_iot;
  285         bus_space_handle_t ioh;
  286 
  287         /* Map i/o space. */
  288         if (bus_space_map(iot, ia->ia_io[0].ir_addr, FMV_NPORTS, 0, &ioh)) {
  289                 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
  290                 return;
  291         }
  292 
  293         sc->sc_bst = iot;
  294         sc->sc_bsh = ioh;
  295 
  296         fmv_attach(sc);
  297 
  298         /* Establish the interrupt handler. */
  299         isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
  300             IST_EDGE, IPL_NET, mb86960_intr, sc);
  301         if (isc->sc_ih == NULL)
  302                 printf("%s: couldn't establish interrupt handler\n",
  303                     sc->sc_dev.dv_xname);
  304 }

Cache object: af02ab7cd2d5eb1bd42ff2caf6e86642


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