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/ofisa/if_cs_ofisa.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_cs_ofisa.c,v 1.11 2003/05/03 18:11:32 wiz Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
    9  * NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: if_cs_ofisa.c,v 1.11 2003/05/03 18:11:32 wiz Exp $");
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/socket.h>
   46 #include <sys/device.h>
   47 #include <sys/malloc.h>
   48 
   49 #include "rnd.h"
   50 #if NRND > 0
   51 #include <sys/rnd.h>
   52 #endif
   53 
   54 #include <net/if.h>
   55 #include <net/if_ether.h>
   56 #include <net/if_media.h>
   57 #ifdef INET
   58 #include <netinet/in.h>
   59 #include <netinet/if_inarp.h>
   60 #endif
   61 
   62 #include <machine/bus.h>
   63 #include <machine/intr.h>
   64 
   65 #include <dev/ofw/openfirm.h>
   66 #include <dev/isa/isavar.h>
   67 #include <dev/ofisa/ofisavar.h>
   68 
   69 #include <dev/ic/cs89x0reg.h>
   70 #include <dev/ic/cs89x0var.h>
   71 #include <dev/isa/cs89x0isavar.h>
   72 
   73 int     cs_ofisa_match __P((struct device *, struct cfdata *, void *));
   74 void    cs_ofisa_attach __P((struct device *, struct device *, void *));
   75 
   76 CFATTACH_DECL(cs_ofisa, sizeof(struct cs_softc_isa),
   77     cs_ofisa_match, cs_ofisa_attach, NULL, NULL);
   78 
   79 int
   80 cs_ofisa_match(parent, cf, aux)
   81         struct device *parent;
   82         struct cfdata *cf;
   83         void *aux;
   84 {
   85         struct ofisa_attach_args *aa = aux;
   86         static const char *const compatible_strings[] = {
   87                 "CRUS,CS8900",
   88                 /* XXX CS8920, CS8920M? */
   89                 /* XXX PNP names? */
   90                 NULL,
   91         };
   92         int rv = 0;
   93 
   94         if (of_compatible(aa->oba.oba_phandle, compatible_strings) != -1)
   95                 rv = 5;
   96 #ifdef _CS_OFISA_MD_MATCH
   97         if (rv == 0)
   98                 rv = cs_ofisa_md_match(parent, cf, aux);
   99 #endif
  100         return (rv);
  101 }
  102 
  103 void
  104 cs_ofisa_attach(parent, self, aux)
  105         struct device *parent, *self;
  106         void *aux;
  107 {
  108         struct cs_softc *sc = (struct cs_softc *) self;
  109         struct cs_softc_isa *isc = (void *)sc;
  110         struct ofisa_attach_args *aa = aux;
  111         struct ofisa_reg_desc reg[2];
  112         struct ofisa_intr_desc intr;
  113         struct ofisa_dma_desc dma;
  114         int i, n, *media, nmedia, defmedia;
  115         bus_addr_t io_addr, mem_addr;
  116         char *model = NULL;
  117         const char *message = NULL;
  118         u_int8_t enaddr[6];
  119 
  120         isc->sc_ic = aa->ic;
  121         sc->sc_iot = aa->iot;
  122         sc->sc_memt = aa->memt;
  123 
  124         /*
  125          * We're living on an OFW.  We have to ask the OFW what our
  126          * registers and interrupts properties look like.
  127          *
  128          * We expect:
  129          *
  130          *      1 i/o register region
  131          *      0 or 1 memory region
  132          *      1 interrupt
  133          *      0 or 1 DMA channel
  134          */
  135 
  136         io_addr = mem_addr = -1;
  137 
  138         n = ofisa_reg_get(aa->oba.oba_phandle, reg, 2);
  139 #ifdef _CS_OFISA_MD_REG_FIXUP
  140         n = cs_ofisa_md_reg_fixup(parent, self, aux, reg, 2, n);
  141 #endif
  142         if (n < 1 || n > 2) {
  143                 printf(": error getting register data\n");
  144                 return;
  145         }
  146 
  147         for (i = 0; i < n; i++) {
  148                 if (reg[i].type == OFISA_REG_TYPE_IO) {
  149                         if (io_addr != (bus_addr_t) -1) {
  150                                 printf(": multiple I/O regions\n");
  151                                 return;
  152                         }
  153                         if (reg[i].len != CS8900_IOSIZE) {
  154                                 printf(": weird register size (%lu, expected %d)\n",
  155                                     (unsigned long)reg[i].len, CS8900_IOSIZE);
  156                                 return;
  157                         }
  158                         io_addr = reg[i].addr;
  159                 } else {
  160                         if (mem_addr != (bus_addr_t) -1) {
  161                                 printf(": multiple memory regions\n");
  162                                 return;
  163                         }
  164                         if (reg[i].len != CS8900_MEMSIZE) {
  165                                 printf(": weird register size (%lu, expected %d)\n",
  166                                     (unsigned long)reg[i].len, CS8900_MEMSIZE);
  167                                 return;
  168                         }
  169                         mem_addr = reg[i].addr;
  170                 }
  171         }
  172 
  173         n = ofisa_intr_get(aa->oba.oba_phandle, &intr, 1);
  174 #ifdef _CS_OFISA_MD_INTR_FIXUP
  175         n = cs_ofisa_md_intr_fixup(parent, self, aux, &intr, 1, n);
  176 #endif
  177         if (n != 1) {
  178                 printf(": error getting interrupt data\n");
  179                 return;
  180         }
  181         sc->sc_irq = intr.irq;
  182 
  183         if (CS8900_IRQ_ISVALID(sc->sc_irq) == 0) {
  184                 printf(": invalid IRQ %d\n", sc->sc_irq);
  185                 return;
  186         }
  187 
  188         isc->sc_drq = ISACF_DRQ_DEFAULT;
  189         n = ofisa_dma_get(aa->oba.oba_phandle, &dma, 1);
  190 #ifdef _CS_OFISA_MD_DMA_FIXUP
  191         n = cs_ofisa_md_dma_fixup(parent, self, aux, &dma, 1, n);
  192 #endif
  193         if (n == 1)
  194                 isc->sc_drq = dma.drq;
  195 
  196         if (io_addr == (bus_addr_t) -1) {
  197                 printf(": no I/O space\n");
  198                 return;
  199         }
  200         if (bus_space_map(sc->sc_iot, io_addr, CS8900_IOSIZE, 0,
  201             &sc->sc_ioh)) {
  202                 printf(": unable to map register space\n");
  203                 return;
  204         }
  205 
  206         if (mem_addr != (bus_addr_t) -1) {
  207                 if (bus_space_map(sc->sc_memt, mem_addr, CS8900_MEMSIZE, 0,
  208                     &sc->sc_memh)) {
  209                         message = "unable to map memory space";
  210                 } else {
  211                         sc->sc_cfgflags |= CFGFLG_MEM_MODE;
  212                         sc->sc_pktpgaddr = mem_addr;
  213                 }
  214         }
  215 
  216         /* Dig MAC address out of the firmware. */
  217         if (OF_getprop(aa->oba.oba_phandle, "mac-address", enaddr,
  218             sizeof(enaddr)) < 0) {
  219                 printf(": unable to get Ethernet address\n");
  220                 return;
  221         }
  222 
  223         /* Dig media out of the firmware. */
  224         media = of_network_decode_media(aa->oba.oba_phandle, &nmedia,
  225             &defmedia);
  226 #ifdef _CS_OFISA_MD_MEDIA_FIXUP
  227         media = cs_ofisa_md_media_fixup(parent, self, aux, media, &nmedia,
  228             &defmedia);
  229 #endif
  230         if (media == NULL) {
  231                 printf(": unable to get media information\n");
  232                 return;
  233         }
  234 
  235         n = OF_getproplen(aa->oba.oba_phandle, "model");
  236         if (n > 0) {
  237                 model = alloca(n);
  238                 if (OF_getprop(aa->oba.oba_phandle, "model", model, n) != n)
  239                         model = NULL;   /* Safe; alloca is on-stack */
  240         }
  241         if (model != NULL)
  242                 printf(": %s\n", model);
  243         else
  244                 printf("\n");
  245 
  246         if (message != NULL)
  247                 printf("%s: %s\n", sc->sc_dev.dv_xname, message);
  248 
  249         if (defmedia == -1) {
  250                 printf("%s: unable to get default media\n",
  251                     sc->sc_dev.dv_xname);
  252                 defmedia = media[0];    /* XXX What to do? */
  253         }
  254 
  255         sc->sc_ih = isa_intr_establish(isc->sc_ic, sc->sc_irq, intr.share,
  256             IPL_NET, cs_intr, sc);
  257         if (sc->sc_ih == NULL) {
  258                 printf("%s: unable to establish interrupt\n",
  259                     sc->sc_dev.dv_xname);
  260                 return;
  261         }
  262 
  263 #ifdef _CS_OFISA_MD_CFGFLAGS_FIXUP
  264         sc->sc_cfgflags |= cs_ofisa_md_cfgflags_fixup(parent, self, aux);
  265 #endif
  266 
  267         sc->sc_dma_chipinit = cs_isa_dma_chipinit;
  268         sc->sc_dma_attach = cs_isa_dma_attach;
  269         sc->sc_dma_process_rx = cs_process_rx_dma;
  270 
  271         cs_attach(sc, enaddr, media, nmedia, defmedia);
  272 
  273         /* This is malloc'd. */
  274         free(media, M_DEVBUF);
  275 }

Cache object: a1723073dd599fa0fd99b1e92ca01fa4


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