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/arl/if_arl_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 /*-
    2  * Copyright (c) 1999-2001, Ivan Sharov, Vitaly Belekhov.
    3  * Copyright (c) 2004 Stanislav Svirid.
    4  * All rights reserved.
    5  * 
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 
   15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  * 
   27  * $RISS: if_arl/dev/arl/if_arl_isa.c,v 1.7 2004/03/16 05:30:38 count Exp $
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include "opt_inet.h"
   34 
   35 #ifdef INET
   36 #define ARLCACHE
   37 #endif
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/socket.h>
   42 #include <sys/kernel.h>
   43 #include <sys/malloc.h>
   44 
   45 #include <sys/module.h>
   46 #include <sys/bus.h>
   47 #include <machine/bus.h>
   48 #include <machine/resource.h>
   49 #include <sys/rman.h>
   50 
   51 #include <net/ethernet.h>
   52 #include <net/if.h>
   53 #include <net/if_arp.h>
   54 #include <net/if_mib.h>
   55 #include <net/if_media.h>
   56 
   57 #include <isa/isavar.h>
   58 #include <isa/pnpvar.h>
   59 #include <isa/isa_common.h>
   60 
   61 #include <machine/clock.h>
   62 #include <machine/md_var.h>
   63 #include <vm/vm.h>
   64 #include <vm/pmap.h>
   65 #include <vm/vm_param.h>
   66 
   67 #include <dev/arl/if_arlreg.h>
   68 
   69 static void     arl_isa_identify(driver_t *, device_t);
   70 static int      arl_isa_probe   (device_t);
   71 static int      arl_isa_attach  (device_t);
   72 static int      arl_isa_detach  (device_t);
   73 static char*    arl_make_desc   (u_int8_t, u_int8_t);
   74 
   75 #define ARL_MAX_ATYPE_LEN       10
   76 static struct arl_type {
   77         u_int8_t        type;
   78         char*           desc;
   79 }
   80 arl_type_list[] = {
   81         { 0, "450" },
   82         { 1, "650" },
   83         { 0xb, "670" },
   84         { 0xc, "670E" },
   85         { 0xd, "650E" },
   86         { 0xe, "440LT" },
   87         { 0x2e, "655" },
   88         { 0x6b, "IC2200" },
   89         { 0, 0 }
   90 };
   91 
   92 #define ARL_MAX_RTYPE_LEN       10
   93 struct radio_type {
   94         u_int8_t        type;
   95         char*           desc;
   96 } radio_type_list []  = {
   97         { 1, "092/094"  },
   98         { 2, "020"      },
   99         { 3, "092A"     },
  100         { 4, "020B"     },
  101         { 5, "095"      },
  102         { 6, "024"      },
  103         { 7, "025B"     },
  104         { 8, "024B"     },
  105         { 9, "024C"     },
  106         {10, "025C"     },
  107         {11, "024-1A"   },
  108         {12, "025-1A"   },
  109 };
  110 
  111 
  112 static char*
  113 arl_make_desc(hw_type, radio_mod)
  114         u_int8_t hw_type;
  115         u_int8_t radio_mod;
  116 {
  117         static char desc[80];
  118         char atype[ARL_MAX_ATYPE_LEN], rtype[ARL_MAX_RTYPE_LEN];
  119         int i;
  120 
  121         *atype = *rtype = 0;
  122 
  123         /* arl type */
  124         for(i = 0; arl_type_list[i].desc; i++) {
  125                 if (arl_type_list[i].type == hw_type)
  126                         break;
  127         }
  128 
  129         if (arl_type_list[i].desc)
  130                 strncpy(atype, arl_type_list[i].desc, ARL_MAX_ATYPE_LEN);
  131         else
  132                 snprintf(atype, ARL_MAX_ATYPE_LEN, "(0x%x)", hw_type);
  133 
  134         /* radio type */
  135         for(i = 0; radio_type_list[i].desc; i++)
  136                 if (radio_type_list[i].type == radio_mod)
  137                         break;
  138 
  139         if (radio_type_list[i].desc)
  140                 strncpy(rtype, radio_type_list[i].desc, ARL_MAX_RTYPE_LEN);
  141         else
  142                 snprintf(rtype, ARL_MAX_RTYPE_LEN, "(0x%x)", radio_mod);
  143 
  144         snprintf(desc, 80, "ArLan type %s, radio module %s", atype, rtype);
  145 
  146         return desc;
  147 }
  148 
  149 #define ARL_ADDR2VEC(addr) (1 << ((addr - ARL_BASE_START) / ARL_BASE_STEP))
  150 
  151 static void
  152 arl_isa_identify (driver_t *driver, device_t parent)
  153 {
  154         device_t        child;
  155         struct  arl_softc       *sc;
  156         int             chunk, found, i;
  157         u_int16_t       free_mem = 0xFFFF;
  158 
  159         if (bootverbose)
  160                 printf("arl: in identify\n");
  161 
  162         /* Try avoid already added devices */
  163         for (i = 0; (child = device_find_child(parent, "arl", i)) != NULL; i++) {
  164                 chunk = bus_get_resource_start(child, SYS_RES_MEMORY, 0);
  165                 if (bootverbose)
  166                         device_printf(child, "found at iomem = 0x%0x\n", chunk);
  167                 if (chunk >= ARL_BASE_START && chunk <= ARL_BASE_END)
  168                         free_mem ^= ARL_ADDR2VEC(chunk);
  169         }
  170 
  171         if (bootverbose)
  172                 printf("arl: free mem vector = 0x%x\n", free_mem);
  173 
  174         for (chunk = ARL_BASE_START; chunk <= ARL_BASE_END; chunk += ARL_BASE_STEP) {
  175                 /* If device 'arl' with this chunk was found early - skip it */
  176                 if ( !(free_mem & ARL_ADDR2VEC(chunk)) )
  177                         continue;
  178 
  179                 found = 0;
  180                 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "arl", -1);
  181                 device_set_driver(child, driver);
  182                 sc = device_get_softc(child);
  183                 bzero(sc, sizeof(*sc));
  184 
  185                 bus_set_resource(child, SYS_RES_MEMORY, sc->mem_rid, chunk,
  186                         ARL_BASE_STEP);
  187 
  188                 if (arl_alloc_memory(child, sc->mem_rid, ARL_BASE_STEP) == 0) {
  189                         ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
  190                         if (!bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1))
  191                                 found++;
  192                 }
  193 
  194                 if (bootverbose)
  195                         device_printf(child, "%sfound at 0x%x\n",
  196                                         !found ? "not " : "", chunk);
  197 
  198                 arl_release_resources(child);
  199                 if (!found) {
  200                         bus_delete_resource(child, SYS_RES_MEMORY, sc->mem_rid);
  201                         device_delete_child(parent, child);
  202                 }
  203 
  204         }
  205 }
  206 
  207 static int
  208 arl_isa_probe (device_t dev)
  209 {
  210         struct arl_softc *sc = device_get_softc(dev);
  211         int error;
  212         u_char *ptr;
  213         u_int8_t irq;
  214 
  215         if (isa_get_vendorid(dev))
  216                 return (ENXIO);
  217 
  218         if (bootverbose)
  219                 device_printf(dev, "in probe\n");
  220 
  221         bzero(sc, sizeof(struct arl_softc));
  222 
  223         sc->arl_unit = device_get_unit(dev);
  224 
  225         error = arl_alloc_memory(dev, 0, ARL_BASE_STEP);
  226         if (error) {
  227                 if (bootverbose)
  228                         device_printf(dev, "Error allocating memory (%d)\n", error);
  229                 return (error);
  230         }
  231 
  232         ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
  233         if (bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1)) {
  234                 if (bootverbose)
  235                         device_printf(dev, "not found\n");
  236                 error = ENOENT;
  237                 goto bad;
  238         }
  239 
  240         irq = ar->irqLevel;
  241         if (irq == 2)
  242                 irq = 9;
  243 
  244         error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
  245         if (error)
  246                 goto bad;
  247 
  248         error = arl_alloc_irq(dev, 0, 0);
  249         if (error) {
  250                 if (bootverbose)
  251                         device_printf(dev, "Can't allocate IRQ %d\n", irq);
  252                 goto bad;
  253         }
  254 
  255         ar->controlRegister = 1;        /* freeze board */
  256 
  257         /* Memory test */
  258         for (ptr = (u_char *) ar;
  259              ptr < ((u_char *) ar + ARL_BASE_STEP - 1); ptr++) {
  260                 u_char c;
  261 
  262                 c = *ptr; *ptr = ~(*ptr);
  263                 if (*ptr != (u_char)~c) {
  264                         device_printf(dev, "board memory failed at [%lx]\n",
  265                             rman_get_start(sc->mem_res) + (ptr - (u_char *)ar));
  266                         break; /* skip memory test */
  267                 }
  268         }
  269 
  270         bzero((void *) ar,  ARL_BASE_STEP - 1); /* clear board ram */
  271 
  272         if (arl_wait_reset(sc, 100, ARDELAY)) {
  273                 error = ENXIO;
  274                 goto bad;
  275         }
  276 
  277         if (ar->diagnosticInfo == 0xFF) {
  278                 device_set_desc_copy(dev, arl_make_desc(ar->hardwareType,
  279                         ar->radioModule));
  280                 error = 0;
  281         } else {
  282                 if (bootverbose)
  283                         device_printf(dev, "board self-test failed (0x%x)!\n",
  284                                ar->diagnosticInfo);
  285                 error = ENXIO;
  286         }
  287 
  288 bad:
  289         arl_release_resources(dev);
  290 
  291         return (error);
  292 }
  293 
  294 static int
  295 arl_isa_attach (device_t dev)
  296 {
  297         struct arl_softc *sc = device_get_softc(dev);
  298         int error;
  299 
  300         if (bootverbose)
  301                 device_printf(dev, "in attach\n");
  302 
  303         arl_alloc_memory(dev, sc->mem_rid, ARL_BASE_STEP);
  304         arl_alloc_irq(dev, sc->irq_rid, 0);
  305 
  306         error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
  307                                arl_intr, sc, &sc->irq_handle);
  308         if (error) {
  309                 arl_release_resources(dev);
  310                 return (error);
  311         }
  312 
  313 #if __FreeBSD_version < 502108
  314         device_printf(dev, "Ethernet address %6D\n", IFP2ENADDR(sc->arl_ifp), ":");
  315 #endif
  316 
  317         return arl_attach(dev);
  318 }
  319 
  320 static int
  321 arl_isa_detach(device_t dev)
  322 {
  323         struct arl_softc *sc = device_get_softc(dev);
  324 
  325         arl_stop(sc);
  326         ifmedia_removeall(&sc->arl_ifmedia);
  327 #if __FreeBSD_version < 500100
  328         ether_ifdetach(sc->arl_ifp, ETHER_BPF_SUPPORTED);
  329 #else
  330         ether_ifdetach(sc->arl_ifp);
  331         if_free(sc->arl_ifp);
  332 #endif
  333         bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
  334         arl_release_resources(dev);
  335 
  336         return (0);
  337 }
  338 
  339 static device_method_t arl_isa_methods[] = {
  340         /* Device interface */
  341         DEVMETHOD(device_identify,      arl_isa_identify),
  342         DEVMETHOD(device_probe,         arl_isa_probe),
  343         DEVMETHOD(device_attach,        arl_isa_attach),
  344         DEVMETHOD(device_detach,        arl_isa_detach),
  345 
  346         { 0, 0 }
  347 };
  348 
  349 static driver_t arl_isa_driver = {
  350         "arl",
  351         arl_isa_methods,
  352         sizeof(struct arl_softc)
  353 };
  354 
  355 extern devclass_t arl_devclass;
  356 
  357 DRIVER_MODULE(arl, isa, arl_isa_driver, arl_devclass, 0, 0);
  358 MODULE_DEPEND(arl, isa, 1, 1, 1);
  359 MODULE_DEPEND(arl, ether, 1, 1, 1);

Cache object: fda1feb197a1d8581042d81d5db525fa


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