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/ic/isic.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) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  *
   13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  *---------------------------------------------------------------------------
   26  *
   27  *      i4b_isic.c - global isic stuff
   28  *      ==============================
   29  *
   30  *      $Id: isic.c,v 1.21 2005/02/27 00:27:01 perry Exp $
   31  *
   32  *      last edit-date: [Fri Jan  5 11:36:10 2001]
   33  *
   34  *---------------------------------------------------------------------------*/
   35 
   36 #include <sys/cdefs.h>
   37 __KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.21 2005/02/27 00:27:01 perry Exp $");
   38 
   39 #include <sys/param.h>
   40 #include <sys/ioccom.h>
   41 #include <sys/kernel.h>
   42 #include <sys/systm.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/socket.h>
   45 #include <net/if.h>
   46 #include <sys/callout.h>
   47 #include <sys/device.h>
   48 #include <machine/bus.h>
   49 
   50 #include <netisdn/i4b_debug.h>
   51 #include <netisdn/i4b_ioctl.h>
   52 #include <netisdn/i4b_trace.h>
   53 
   54 #include <netisdn/i4b_l2.h>
   55 #include <netisdn/i4b_l1l2.h>
   56 #include <netisdn/i4b_mbuf.h>
   57 #include <netisdn/i4b_global.h>
   58 
   59 #include <dev/ic/isic_l1.h>
   60 #include <dev/ic/ipac.h>
   61 #include <dev/ic/isac.h>
   62 #include <dev/ic/hscx.h>
   63 
   64 isdn_link_t *isic_ret_linktab(void*, int channel);
   65 void isic_set_link(void*, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc);
   66 void n_connect_request(struct call_desc *cd);
   67 void n_connect_response(struct call_desc *cd, int response, int cause);
   68 void n_disconnect_request(struct call_desc *cd, int cause);
   69 void n_alert_request(struct call_desc *cd);
   70 void n_mgmt_command(struct isdn_l3_driver *drv, int cmd, void *parm);
   71 
   72 const struct isdn_l3_driver_functions
   73 isic_l3_driver = {
   74         isic_ret_linktab,
   75         isic_set_link,
   76         n_connect_request,
   77         n_connect_response,
   78         n_disconnect_request,
   79         n_alert_request,
   80         NULL,
   81         NULL,
   82         n_mgmt_command
   83 };
   84 
   85 /*---------------------------------------------------------------------------*
   86  *      isic - device driver interrupt routine
   87  *---------------------------------------------------------------------------*/
   88 int
   89 isicintr(void *arg)
   90 {
   91         struct isic_softc *sc = arg;
   92 
   93         /* could this be an interrupt for us? */
   94         if (sc->sc_intr_valid == ISIC_INTR_DYING)
   95                 return 0;       /* do not touch removed hardware */
   96 
   97         if(sc->sc_ipac == 0)    /* HSCX/ISAC interrupt routine */
   98         {
   99                 u_char was_hscx_irq = 0;
  100                 u_char was_isac_irq = 0;
  101 
  102                 register u_char hscx_irq_stat;
  103                 register u_char isac_irq_stat;
  104 
  105                 for(;;)
  106                 {
  107                         /* get hscx irq status from hscx b ista */
  108                         hscx_irq_stat =
  109                             HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK;
  110 
  111                         /* get isac irq status */
  112                         isac_irq_stat = ISAC_READ(I_ISTA);
  113 
  114                         /* do as long as there are pending irqs in the chips */
  115                         if(!hscx_irq_stat && !isac_irq_stat)
  116                                 break;
  117 
  118                         if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF |
  119                                             HSCX_ISTA_RSC | HSCX_ISTA_XPR |
  120                                             HSCX_ISTA_TIN | HSCX_ISTA_EXB))
  121                         {
  122                                 isic_hscx_irq(sc, hscx_irq_stat,
  123                                                 HSCX_CH_B,
  124                                                 hscx_irq_stat & HSCX_ISTA_EXB);
  125                                 was_hscx_irq = 1;
  126                         }
  127 
  128                         if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA))
  129                         {
  130                                 isic_hscx_irq(sc,
  131                                     HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK,
  132                                     HSCX_CH_A,
  133                                     hscx_irq_stat & HSCX_ISTA_EXA);
  134                                 was_hscx_irq = 1;
  135                         }
  136 
  137                         if(isac_irq_stat)
  138                         {
  139                                 /* isac handler */
  140                                 isic_isac_irq(sc, isac_irq_stat);
  141                                 was_isac_irq = 1;
  142                         }
  143                 }
  144 
  145                 HSCX_WRITE(0, H_MASK, 0xff);
  146                 ISAC_WRITE(I_MASK, 0xff);
  147                 HSCX_WRITE(1, H_MASK, 0xff);
  148 
  149                 if (sc->clearirq)
  150                 {
  151                         DELAY(80);
  152                         sc->clearirq(sc);
  153                 } else
  154                         DELAY(100);
  155 
  156                 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
  157                 ISAC_WRITE(I_MASK, ISAC_IMASK);
  158                 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
  159 
  160                 return(was_hscx_irq || was_isac_irq);
  161         }
  162         else    /* IPAC interrupt routine */
  163         {
  164                 register u_char ipac_irq_stat;
  165                 register u_char was_ipac_irq = 0;
  166 
  167                 for(;;)
  168                 {
  169                         /* get global irq status */
  170 
  171                         ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f;
  172 
  173                         /* check hscx a */
  174 
  175                         if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA))
  176                         {
  177                                 /* HSCX A interrupt */
  178                                 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA),
  179                                                 HSCX_CH_A,
  180                                                 ipac_irq_stat & IPAC_ISTA_EXA);
  181                                 was_ipac_irq = 1;
  182                         }
  183                         if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB))
  184                         {
  185                                 /* HSCX B interrupt */
  186                                 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA),
  187                                                 HSCX_CH_B,
  188                                                 ipac_irq_stat & IPAC_ISTA_EXB);
  189                                 was_ipac_irq = 1;
  190                         }
  191                         if(ipac_irq_stat & IPAC_ISTA_ICD)
  192                         {
  193                                 /* ISAC interrupt, Obey ISAC-IPAC differences */
  194                                 u_int8_t isac_ista = ISAC_READ(I_ISTA);
  195                                 if (isac_ista & 0xfe)
  196                                         isic_isac_irq(sc, isac_ista & 0xfe);
  197                                 if (isac_ista & 0x01) /* unexpected */
  198                                         printf("%s: unexpected ipac timer2 irq\n",
  199                                             sc->sc_dev.dv_xname);
  200                                 was_ipac_irq = 1;
  201                         }
  202                         if(ipac_irq_stat & IPAC_ISTA_EXD)
  203                         {
  204                                 /* ISAC EXI interrupt */
  205                                 isic_isac_irq(sc, ISAC_ISTA_EXI);
  206                                 was_ipac_irq = 1;
  207                         }
  208 
  209                         /* do as long as there are pending irqs in the chip */
  210                         if(!ipac_irq_stat)
  211                                 break;
  212                 }
  213 
  214 #if 0
  215                 /*
  216                  * This seems not to be necessary on IPACs - no idea why
  217                  * it is here - but due to limit range of test cards, leave
  218                  * it in for now, in case we have to resurrect it.
  219                  */
  220                 IPAC_WRITE(IPAC_MASK, 0xff);
  221                 DELAY(50);
  222                 IPAC_WRITE(IPAC_MASK, 0xc0);
  223 #endif
  224 
  225                 return(was_ipac_irq);
  226         }
  227 }
  228 
  229 int
  230 isic_attach_bri(struct isic_softc *sc, const char *cardname, const struct isdn_layer1_isdnif_driver *dchan_driver)
  231 {
  232         struct isdn_l3_driver * drv;
  233 
  234         drv = isdn_attach_isdnif(sc->sc_dev.dv_xname, cardname,
  235             &sc->sc_l2, &isic_l3_driver, NBCH_BRI);
  236         sc->sc_l3token = drv;
  237         sc->sc_l2.driver = dchan_driver;
  238         sc->sc_l2.l1_token = sc;
  239         sc->sc_l2.drv = drv;
  240         isdn_layer2_status_ind(&sc->sc_l2, drv, STI_ATTACH, 1);
  241         isdn_isdnif_ready(drv->isdnif);
  242         return 1;
  243 }
  244 
  245 int
  246 isic_detach_bri(struct isic_softc *sc)
  247 {
  248         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_ATTACH, 0);
  249         isdn_detach_isdnif(sc->sc_l3token);
  250         sc->sc_l3token = NULL;
  251         return 1;
  252 }

Cache object: b6962cbf2522483aa7a959b154f63c6b


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