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/hfa/hfa_freebsd.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) 2002 Matthew N. Dodd <winter@jurai.net>
    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. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 /*
   30  *
   31  * ===================================
   32  * HARP  |  Host ATM Research Platform
   33  * ===================================
   34  *
   35  *
   36  * This Host ATM Research Platform ("HARP") file (the "Software") is
   37  * made available by Network Computing Services, Inc. ("NetworkCS")
   38  * "AS IS".  NetworkCS does not provide maintenance, improvements or
   39  * support of any kind.
   40  *
   41  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   42  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   43  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   44  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   45  * In no event shall NetworkCS be responsible for any damages, including
   46  * but not limited to consequential damages, arising from or relating to
   47  * any use of the Software or related support.
   48  *
   49  * Copyright 1994-1998 Network Computing Services, Inc.
   50  *
   51  * Copies of this Software may be made, however, the above copyright
   52  * notice must be reproduced on all copies.
   53  *
   54  */
   55 
   56 #include <sys/param.h>
   57 #include <sys/systm.h>
   58 #include <sys/socket.h>
   59 #include <sys/socketvar.h>
   60 #include <sys/kernel.h>
   61 #include <sys/lock.h>
   62 #include <sys/malloc.h>
   63 #include <sys/socket.h>
   64 #include <sys/sysctl.h>
   65 
   66 #include <sys/bus.h>
   67 #include <sys/conf.h>
   68 
   69 #include <sys/module.h>
   70 #include <machine/bus_memio.h>
   71 #include <machine/bus.h>
   72 #include <machine/resource.h>
   73 #include <sys/rman.h>
   74 
   75 #include <net/if.h>
   76 #include <netatm/port.h>
   77 #include <netatm/queue.h>
   78 #include <netatm/atm.h>
   79 #include <netatm/atm_sys.h>
   80 #include <netatm/atm_sap.h>
   81 #include <netatm/atm_cm.h>
   82 #include <netatm/atm_if.h>
   83 #include <netatm/atm_stack.h>
   84 #include <netatm/atm_pcb.h>
   85 #include <netatm/atm_var.h>
   86 
   87 #include <dev/hfa/fore.h>
   88 #include <dev/hfa/fore_aali.h>
   89 #include <dev/hfa/fore_slave.h>
   90 #include <dev/hfa/fore_stats.h>
   91 #include <dev/hfa/fore_var.h>
   92 #include <dev/hfa/fore_include.h>
   93 
   94 #include <dev/hfa/hfa_freebsd.h>
   95 
   96 devclass_t hfa_devclass;
   97 
   98 static int hfa_modevent(module_t, int, void *);
   99 
  100 SYSCTL_DECL(_hw_atm);
  101 
  102 /*
  103  * Sysctl handler for the traffic shaping option
  104  */
  105 static int
  106 hfa_sysctl_shape(SYSCTL_HANDLER_ARGS)
  107 {
  108         struct hfa_softc *sc = arg1;
  109         int error;
  110         u_int new;
  111 
  112         error = SYSCTL_OUT(req, &sc->fup.fu_shape , sizeof(sc->fup.fu_shape));
  113         if (error != 0 || req->newptr == NULL) {
  114                 return (error);
  115         }
  116 
  117         error = SYSCTL_IN(req, &new, sizeof(new));
  118         if (error != 0) {
  119                 return (error);
  120         }
  121 
  122         if (new > FUS_SHAPE_ALL) {
  123                 return (EINVAL);
  124         }
  125 
  126         sc->fup.fu_shape = new;
  127         return (0);
  128 }
  129 
  130 int
  131 hfa_alloc (device_t dev)
  132 {
  133         struct hfa_softc *sc;
  134         int error;
  135 
  136         sc = (struct hfa_softc *)device_get_softc(dev);
  137         error = 0;
  138 
  139         sc->mem = bus_alloc_resource_any(dev, sc->mem_type, &sc->mem_rid,
  140                                            RF_ACTIVE);
  141         if (sc->mem == NULL) {
  142                 device_printf(dev, "Unable to allocate memory resource.\n");
  143                 error = ENXIO;
  144                 goto fail;
  145         }
  146 
  147         sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
  148                                         RF_SHAREABLE | RF_ACTIVE);
  149         if (sc->irq == NULL) {
  150                 device_printf(dev, "Unable to allocate interrupt resource.\n");
  151                 error = ENXIO;
  152                 goto fail;
  153         }
  154 
  155         /*
  156          * Make the sysctl tree
  157          */
  158         if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
  159             SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO,
  160             device_get_nameunit(dev), CTLFLAG_RW, 0, "")) == NULL)
  161                 goto fail;
  162 
  163         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
  164             OID_AUTO, "shape", CTLFLAG_RW | CTLTYPE_UINT, sc, 0,
  165             hfa_sysctl_shape, "IU", "traffic shaping") == NULL)
  166                 goto fail;
  167 
  168         mtx_init(&sc->mtx, device_get_nameunit(dev), "Interrupt lock", MTX_DEF|MTX_RECURSE);
  169 
  170 fail:
  171         return (error);
  172 }
  173 
  174 int
  175 hfa_free (device_t dev)
  176 {
  177         struct hfa_softc *sc;
  178 
  179         sc = (struct hfa_softc *)device_get_softc(dev);
  180 
  181         if (sc->mem)
  182                 bus_release_resource(dev, sc->mem_type, sc->mem_rid, sc->mem);
  183         if (sc->irq_ih)
  184                 bus_teardown_intr(dev, sc->irq, sc->irq_ih);
  185         if (sc->irq)
  186                 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
  187 
  188         /*
  189          * Destroy the mutex.
  190          */
  191         if (mtx_initialized(&sc->mtx) != 0)
  192                  mtx_destroy(&sc->mtx);
  193 
  194         return (0);
  195 }
  196 
  197 int
  198 hfa_attach (device_t dev)
  199 {
  200         struct hfa_softc *sc;
  201         Fore_unit *fup;
  202         int error;
  203         int err_count;
  204 
  205         sc = (struct hfa_softc *)device_get_softc(dev);
  206         fup = &sc->fup;
  207         error = 0;
  208         err_count = BOOT_LOOPS;
  209 
  210         /*
  211          * Start initializing it
  212          */
  213         fup->fu_unit = device_get_unit(dev);
  214         fup->fu_mtu = FORE_IFF_MTU;
  215         fup->fu_vcc_zone = fore_vcc_zone;
  216         fup->fu_nif_zone = fore_nif_zone;
  217         fup->fu_ioctl = fore_atm_ioctl;
  218         fup->fu_instvcc = fore_instvcc;
  219         fup->fu_openvcc = fore_openvcc;
  220         fup->fu_closevcc = fore_closevcc;
  221         fup->fu_output = fore_output;
  222         fup->fu_softc = (void *)sc;
  223 
  224         callout_handle_init(&fup->fu_thandle);
  225 
  226         /*
  227          * Poke the hardware - boot the CP and prepare it for downloading
  228          */
  229         hfa_reset(dev);
  230 
  231         /*
  232          * Wait for the monitor to perform self-test
  233          */
  234         while (CP_READ(fup->fu_mon->mon_bstat) != BOOT_MONREADY) {
  235                  if (CP_READ(fup->fu_mon->mon_bstat) == BOOT_FAILTEST) {
  236                           device_printf(dev, "failed self-test\n");
  237                           goto fail;
  238                  } else if ( --err_count == 0 ) {
  239                           device_printf(dev, "unable to boot - status=0x%lx\n",
  240                                    (u_long)CP_READ(fup->fu_mon->mon_bstat));
  241                           goto fail;
  242                  }
  243                  DELAY ( BOOT_DELAY );
  244         }
  245 
  246         /*
  247          * Setup the adapter config info - at least as much as we can
  248          */
  249         fup->fu_config.ac_vendor = VENDOR_FORE;
  250         fup->fu_config.ac_vendapi = VENDAPI_FORE_1;
  251         fup->fu_config.ac_media = MEDIA_OC3C;
  252         fup->fu_pif.pif_pcr = ATM_PCR_OC3C;
  253 
  254         /*
  255          * Save device ram info for user-level programs
  256          */
  257         fup->fu_config.ac_ram = (long)fup->fu_ram;
  258         fup->fu_config.ac_ramsize = fup->fu_ramsize;
  259 
  260         /*
  261          * Set device capabilities
  262          */
  263         fup->fu_pif.pif_maxvpi = FORE_MAX_VPI;
  264         fup->fu_pif.pif_maxvci = FORE_MAX_VCI;
  265 
  266         /*
  267          * Register this interface with ATM core services
  268          */
  269         error = atm_physif_register((Cmn_unit *)fup, FORE_DEV_NAME, fore_services);
  270         if (error)
  271                  goto fail;
  272 
  273         fore_units[device_get_unit(dev)] = fup;
  274         fore_nunits++;
  275 
  276         /*
  277          * Initialize the CP microcode program.
  278          */
  279         fore_initialize(fup);
  280 
  281 fail:
  282         return (error);
  283 }
  284 
  285 int
  286 hfa_detach (device_t dev)
  287 {
  288         struct hfa_softc *sc;
  289         Fore_unit *fup;
  290         int error;
  291 
  292         sc = (struct hfa_softc *)device_get_softc(dev);
  293         fup = &sc->fup;
  294         error = 0;
  295 
  296         /*
  297          * De-Register this interface with ATM core services
  298          */
  299         error = atm_physif_deregister((Cmn_unit *)fup);
  300 
  301         /*
  302          * Reset the board and return it to cold_start state.
  303          * Hopefully, this will prevent use of resources as
  304          * we're trying to free things up.
  305          */
  306         hfa_reset(dev);
  307 
  308         /*
  309          * Lock out all device interrupts
  310          */
  311         DEVICE_LOCK((Cmn_unit *)fup);
  312 
  313         /*
  314          * Remove any pending timeout()'s
  315          */
  316         (void)untimeout((KTimeout_ret(*)(void *))fore_initialize,
  317                  (void *)fup, fup->fu_thandle);
  318 
  319         hfa_free(dev);
  320 
  321         DEVICE_UNLOCK((Cmn_unit *)fup);
  322 
  323         /*
  324          * Free any Fore-specific device resources
  325          */
  326         fore_interface_free(fup);
  327 
  328         return (error);
  329 }
  330 
  331 void
  332 hfa_intr (void * arg)
  333 {
  334         struct hfa_softc *sc;
  335 
  336         sc = (struct hfa_softc *)arg;
  337 
  338         HFA_LOCK(sc);
  339         fore_intr(&sc->fup);
  340         HFA_UNLOCK(sc);
  341 
  342         return;
  343 }
  344 
  345 void
  346 hfa_reset (device_t dev)
  347 {
  348         struct hfa_softc *sc;
  349         Fore_unit *fup;
  350 
  351         sc = (struct hfa_softc *)device_get_softc(dev);
  352         fup = &sc->fup;
  353         HFA_LOCK(sc);
  354 
  355         /*
  356          * Reset the board and return it to cold_start state
  357          */
  358         if (fup->fu_mon)
  359                 fup->fu_mon->mon_bstat = CP_WRITE(BOOT_COLDSTART);
  360 
  361         if (fup->fu_ctlreg) {
  362 
  363                 switch (fup->fu_config.ac_device) {
  364                 case DEV_FORE_ESA200E:
  365 
  366                         break;
  367 
  368                 case DEV_FORE_SBA200E:
  369                         /*
  370                          * Reset i960 by setting and clearing RESET
  371                          */
  372                         SBA200E_HCR_INIT(*fup->fu_ctlreg, SBA200E_RESET);
  373                         SBA200E_HCR_CLR(*fup->fu_ctlreg, SBA200E_RESET);
  374                         break;
  375 
  376                 case DEV_FORE_SBA200:
  377                         /*
  378                          * Reset i960 by setting and clearing RESET
  379                          *
  380                          * SBA200 will NOT reset if bit is OR'd in!
  381                          */
  382                         *fup->fu_ctlreg = SBA200_RESET;
  383                         *fup->fu_ctlreg = SBA200_RESET_CLR;
  384                         break;
  385 
  386                 case DEV_FORE_PCA200E:
  387                         /*
  388                          * Reset i960 by setting and clearing RESET
  389                          */
  390                         PCA200E_HCR_INIT(*fup->fu_ctlreg, PCA200E_RESET);
  391                         DELAY(10000);
  392                         PCA200E_HCR_CLR(*fup->fu_ctlreg, PCA200E_RESET);
  393                         break;
  394                 default:
  395                         break;
  396                 }
  397         }
  398 
  399         HFA_UNLOCK(sc);
  400         return;
  401 }
  402 
  403 static int       
  404 hfa_modevent (module_t mod, int type, void *data)
  405 {
  406         int error;
  407 
  408         error = 0;
  409 
  410         switch (type) {
  411         case MOD_LOAD:
  412                 /*
  413                 * Verify software version
  414                 */
  415                 if (atm_version != ATM_VERSION) {
  416                         printf("hfa: version mismatch: fore=%d.%d kernel=%d.%d\n",
  417                                 ATM_VERS_MAJ(ATM_VERSION),
  418                                 ATM_VERS_MIN(ATM_VERSION),
  419                                 ATM_VERS_MAJ(atm_version),
  420                                 ATM_VERS_MIN(atm_version));
  421                         error = EINVAL;
  422                         break;
  423                 }
  424 
  425                 fore_nif_zone = uma_zcreate("fore nif", sizeof(struct atm_nif), NULL,
  426                     NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  427                 if (fore_nif_zone == NULL)
  428                         panic("hfa_modevent:uma_zcreate nif");
  429                 uma_zone_set_max(fore_nif_zone, 52);
  430 
  431                 fore_vcc_zone = uma_zcreate("fore vcc", sizeof(Fore_vcc), NULL,
  432                     NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
  433                 if (fore_vcc_zone == NULL)
  434                         panic("hfa_modevent: uma_zcreate vcc");
  435                 uma_zone_set_max(fore_vcc_zone, 100);
  436         
  437                 /*
  438                 * Start up watchdog timer
  439                 */
  440                 atm_timeout(&fore_timer, ATM_HZ * FORE_TIME_TICK, fore_timeout);
  441 
  442                 break;
  443         case MOD_UNLOAD:
  444                 /*
  445                  * Stop watchdog timer
  446                  */
  447                 atm_untimeout(&fore_timer);
  448 
  449                 uma_zdestroy(fore_nif_zone);
  450                 uma_zdestroy(fore_vcc_zone);
  451 
  452                 break;
  453         default:
  454                 return (EOPNOTSUPP);
  455                 break;
  456         }
  457 
  458         return (error);
  459 }
  460 
  461 static moduledata_t hfa_moduledata = {
  462         "hfa",
  463         hfa_modevent,
  464         NULL
  465 };
  466 DECLARE_MODULE(hfa, hfa_moduledata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
  467 MODULE_VERSION(hfa, 1);

Cache object: 2c551c8697dcb33a948955c926fa87bd


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