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/isacsx.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: isacsx.c,v 1.6 2008/04/08 12:07:26 cegger Exp $     */
    2 /*
    3  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
    4  * Copyright (c) 2001 Gary Jennejohn. 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 THE 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 THE 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  *---------------------------------------------------------------------------
   28  *
   29  *      i4b_ifpi2_isac.c - i4b Fritz PCI Version 2 ISACSX handler
   30  *      --------------------------------------------
   31  *
   32  *      $Id: isacsx.c,v 1.6 2008/04/08 12:07:26 cegger Exp $
   33  *
   34  * $FreeBSD: src/sys/i4b/layer1/ifpi2/i4b_ifpi2_isacsx.c,v 1.3 2002/09/02 00:52:07 brooks Exp $
   35  *
   36  *
   37  *---------------------------------------------------------------------------*/
   38 
   39 #include <sys/cdefs.h>
   40 __KERNEL_RCSID(0, "$NetBSD: isacsx.c,v 1.6 2008/04/08 12:07:26 cegger Exp $");
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/socket.h>
   46 #include <sys/device.h>
   47 
   48 #include <net/if.h>
   49 
   50 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   51 #include <sys/callout.h>
   52 #endif
   53 
   54 #ifdef __FreeBSD__
   55 #include <machine/i4b_debug.h>
   56 #include <machine/i4b_ioctl.h>
   57 #include <machine/i4b_trace.h>
   58 
   59 #include <i4b/layer1/i4b_l1.h>
   60 
   61 #include <i4b/layer1/isic/i4b_isic.h>
   62 #include <i4b/layer1/isic/i4b_hscx.h>
   63 
   64 #include <i4b/layer1/ifpi2/i4b_ifpi2_ext.h>
   65 #include <i4b/layer1/ifpi2/i4b_ifpi2_isacsx.h>
   66 
   67 #include <i4b/include/i4b_global.h>
   68 #include <i4b/include/i4b_mbuf.h>
   69 #else
   70 #include <sys/bus.h>
   71 
   72 #include <netisdn/i4b_debug.h>
   73 #include <netisdn/i4b_ioctl.h>
   74 #include <netisdn/i4b_trace.h>
   75 
   76 #include <netisdn/i4b_global.h>
   77 #include <netisdn/i4b_l2.h>
   78 #include <netisdn/i4b_l1l2.h>
   79 #include <netisdn/i4b_mbuf.h>
   80 
   81 #include <dev/ic/isacsx.h>
   82 #include <dev/ic/isic_l1.h>
   83 #include <dev/ic/hscx.h>
   84 
   85 #endif
   86 
   87 static u_char isic_isacsx_exir_hdlr(register struct isic_softc *sc, u_char exir);
   88 static void isic_isacsx_ind_hdlr(register struct isic_softc *sc, int ind);
   89 
   90 /* the ISACSX has 2 mask registers of interest - cannot use ISAC_IMASK */
   91 unsigned char isacsx_imaskd;
   92 unsigned char isacsx_imask;
   93 
   94 /*---------------------------------------------------------------------------*
   95  *      ISACSX interrupt service routine
   96  *---------------------------------------------------------------------------*/
   97 void
   98 isic_isacsx_irq(struct isic_softc *sc, int ista)
   99 {
  100         register u_char c = 0;
  101         register u_char istad = 0;
  102 
  103         NDBGL1(L1_F_MSG, "%s: ista = 0x%02x", device_xname(&sc->sc_dev), ista);
  104 
  105         /* was it an HDLC interrupt ? */
  106         if (ista & ISACSX_ISTA_ICD)
  107         {
  108                 istad = ISAC_READ(I_ISTAD);
  109                 NDBGL1(L1_F_MSG, "%s: istad = 0x%02x", device_xname(&sc->sc_dev), istad);
  110 
  111                 if(istad & (ISACSX_ISTAD_RFO|ISACSX_ISTAD_XMR|ISACSX_ISTAD_XDU))
  112                 {
  113                         /* not really EXIR, but very similar */
  114                         c |= isic_isacsx_exir_hdlr(sc, istad);
  115                 }
  116         }
  117 
  118         if(istad & ISACSX_ISTAD_RME)    /* receive message end */
  119         {
  120                 register int rest;
  121                 u_char rsta;
  122 
  123                 /* get rx status register */
  124 
  125                 rsta = ISAC_READ(I_RSTAD);
  126 
  127                 /* Check for Frame and CRC valid */
  128                 if((rsta & ISACSX_RSTAD_MASK) != (ISACSX_RSTAD_VFR|ISACSX_RSTAD_CRC))
  129                 {
  130                         int error = 0;
  131 
  132                         if(!(rsta & ISACSX_RSTAD_VFR))  /* VFR error */
  133                         {
  134                                 error++;
  135                                 NDBGL1(L1_I_ERR, "%s: Frame not valid error", device_xname(&sc->sc_dev));
  136                         }
  137 
  138                         if(!(rsta & ISACSX_RSTAD_CRC))  /* CRC error */
  139                         {
  140                                 error++;
  141                                 NDBGL1(L1_I_ERR, "%s: CRC error", device_xname(&sc->sc_dev));
  142                         }
  143 
  144                         if(rsta & ISACSX_RSTAD_RDO)     /* ReceiveDataOverflow */
  145                         {
  146                                 error++;
  147                                 NDBGL1(L1_I_ERR, "%s: Data Overrun error", device_xname(&sc->sc_dev));
  148                         }
  149 
  150                         if(rsta & ISACSX_RSTAD_RAB)     /* ReceiveABorted */
  151                         {
  152                                 error++;
  153                                 NDBGL1(L1_I_ERR, "%s: Receive Aborted error", device_xname(&sc->sc_dev));
  154                         }
  155 
  156                         if(error == 0)
  157                                 NDBGL1(L1_I_ERR, "%s: RME unknown error, RSTAD = 0x%02x!", device_xname(&sc->sc_dev), rsta);
  158 
  159                         i4b_Dfreembuf(sc->sc_ibuf);
  160 
  161                         c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;
  162 
  163                         sc->sc_ibuf = NULL;
  164                         sc->sc_ib = NULL;
  165                         sc->sc_ilen = 0;
  166 
  167                         ISAC_WRITE(I_CMDRD, ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES);
  168 
  169                         return;
  170                 }
  171 
  172                 rest = (ISAC_READ(I_RBCLD) & (ISACSX_FIFO_LEN-1));
  173 
  174                 if(rest == 0)
  175                         rest = ISACSX_FIFO_LEN;
  176 
  177                 if(sc->sc_ibuf == NULL)
  178                 {
  179                         if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
  180                                 sc->sc_ib = sc->sc_ibuf->m_data;
  181                         else
  182                                 panic("isic_isacsx_irq: RME, i4b_Dgetmbuf returns NULL!\n");
  183                         sc->sc_ilen = 0;
  184                 }
  185 
  186                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
  187                 {
  188                         ISAC_RDFIFO(sc->sc_ib, rest);
  189                          /* the  last byte contains status, strip it */
  190                         sc->sc_ilen += rest - 1;
  191 
  192                         sc->sc_ibuf->m_pkthdr.len =
  193                                 sc->sc_ibuf->m_len = sc->sc_ilen;
  194 
  195                         if(sc->sc_trace & TRACE_D_RX)
  196                         {
  197                                 i4b_trace_hdr hdr;
  198 
  199                                 memset(&hdr, 0, sizeof hdr);
  200                                 hdr.type = TRC_CH_D;
  201                                 hdr.dir = FROM_NT;
  202                                 hdr.count = ++sc->sc_trace_dcount;
  203                                 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
  204                         }
  205 
  206                         c |= ISACSX_CMDRD_RMC;
  207 
  208                         if(sc->sc_intr_valid == ISIC_INTR_VALID &&
  209                            (((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S))
  210                         {
  211                                 isdn_layer2_data_ind(&sc->sc_l2, sc->sc_l3token, sc->sc_ibuf);
  212                         }
  213                         else
  214                         {
  215                                 i4b_Dfreembuf(sc->sc_ibuf);
  216                         }
  217                 }
  218                 else
  219                 {
  220                         NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
  221                         i4b_Dfreembuf(sc->sc_ibuf);
  222                         c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;
  223                 }
  224 
  225                 sc->sc_ibuf = NULL;
  226                 sc->sc_ib = NULL;
  227                 sc->sc_ilen = 0;
  228         }
  229 
  230         if(istad & ISACSX_ISTAD_RPF)    /* receive fifo full */
  231         {
  232                 if(sc->sc_ibuf == NULL)
  233                 {
  234                         if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
  235                                 sc->sc_ib= sc->sc_ibuf->m_data;
  236                         else
  237                                 panic("isic_isacsx_irq: RPF, i4b_Dgetmbuf returns NULL!\n");
  238                         sc->sc_ilen = 0;
  239                 }
  240 
  241                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISACSX_FIFO_LEN))
  242                 {
  243                         ISAC_RDFIFO(sc->sc_ib, ISACSX_FIFO_LEN);
  244                         sc->sc_ilen += ISACSX_FIFO_LEN;
  245                         sc->sc_ib += ISACSX_FIFO_LEN;
  246                         c |= ISACSX_CMDRD_RMC;
  247                 }
  248                 else
  249                 {
  250                         NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
  251                         i4b_Dfreembuf(sc->sc_ibuf);
  252                         sc->sc_ibuf = NULL;
  253                         sc->sc_ib = NULL;
  254                         sc->sc_ilen = 0;
  255                         c |= ISACSX_CMDRD_RMC|ISACSX_CMDRD_RRES;
  256                 }
  257         }
  258 
  259         if(istad & ISACSX_ISTAD_XPR)    /* transmit fifo empty (XPR bit set) */
  260         {
  261                 if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
  262                 {
  263                         sc->sc_freeflag = sc->sc_freeflag2;
  264                         sc->sc_obuf = sc->sc_obuf2;
  265                         sc->sc_op = sc->sc_obuf->m_data;
  266                         sc->sc_ol = sc->sc_obuf->m_len;
  267                         sc->sc_obuf2 = NULL;
  268 #ifdef NOTDEF
  269                         printf("ob2=%x, op=%x, ol=%d, f=%d #",
  270                                 sc->sc_obuf,
  271                                 sc->sc_op,
  272                                 sc->sc_ol,
  273                                 sc->sc_state);
  274 #endif
  275                 }
  276                 else
  277                 {
  278 #ifdef NOTDEF
  279                         printf("ob=%x, op=%x, ol=%d, f=%d #",
  280                                 sc->sc_obuf,
  281                                 sc->sc_op,
  282                                 sc->sc_ol,
  283                                 sc->sc_state);
  284 #endif
  285                 }
  286 
  287                 if(sc->sc_obuf)
  288                 {
  289                         ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISACSX_FIFO_LEN));
  290 
  291                         if(sc->sc_ol > ISACSX_FIFO_LEN) /* length > 32 ? */
  292                         {
  293                                 sc->sc_op += ISACSX_FIFO_LEN; /* bufferptr+32 */
  294                                 sc->sc_ol -= ISACSX_FIFO_LEN; /* length - 32 */
  295                                 c |= ISACSX_CMDRD_XTF;      /* set XTF bit */
  296                         }
  297                         else
  298                         {
  299                                 if(sc->sc_freeflag)
  300                                 {
  301                                         i4b_Dfreembuf(sc->sc_obuf);
  302                                         sc->sc_freeflag = 0;
  303                                 }
  304                                 sc->sc_obuf = NULL;
  305                                 sc->sc_op = NULL;
  306                                 sc->sc_ol = 0;
  307 
  308                                 c |= ISACSX_CMDRD_XTF | ISACSX_CMDRD_XME;
  309                         }
  310                 }
  311                 else
  312                 {
  313                         sc->sc_state &= ~ISAC_TX_ACTIVE;
  314                 }
  315         }
  316 
  317         if(ista & ISACSX_ISTA_CIC)      /* channel status change CISQ */
  318         {
  319                 register u_char ci;
  320 
  321                 /* get command/indication rx register*/
  322 
  323                 ci = ISAC_READ(I_CIR0);
  324 
  325                 /* C/I code change IRQ (flag already cleared by CIR0 read) */
  326 
  327                 if(ci & ISACSX_CIR0_CIC0)
  328                         isic_isacsx_ind_hdlr(sc, (ci >> 4) & 0xf);
  329         }
  330 
  331         if(c)
  332         {
  333                 ISAC_WRITE(I_CMDRD, c);
  334         }
  335 }
  336 
  337 /*---------------------------------------------------------------------------*
  338  *      ISACSX L1 Extended IRQ handler
  339  *---------------------------------------------------------------------------*/
  340 static u_char
  341 isic_isacsx_exir_hdlr(register struct isic_softc *sc, u_char exir)
  342 {
  343         u_char c = 0;
  344 
  345         if(exir & ISACSX_ISTAD_XMR)
  346         {
  347                 NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
  348 
  349                 c |= ISACSX_CMDRD_XRES;
  350         }
  351 
  352         if(exir & ISACSX_ISTAD_XDU)
  353         {
  354                 NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
  355 
  356                 c |= ISACSX_CMDRD_XRES;
  357         }
  358 
  359         if(exir & ISACSX_ISTAD_RFO)
  360         {
  361                 NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
  362 
  363                 c |= ISACSX_CMDRD_RMC;
  364         }
  365 
  366 #if 0 /* all blocked per default */
  367         if(exir & ISACSX_EXIR_SOV)
  368         {
  369                 NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
  370         }
  371 
  372         if(exir & ISACSX_EXIR_MOS)
  373         {
  374                 NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
  375         }
  376 
  377         if(exir & ISACSX_EXIR_SAW)
  378         {
  379                 /* cannot happen, STCR:TSF is set to 0 */
  380 
  381                 NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
  382         }
  383 
  384         if(exir & ISACSX_EXIR_WOV)
  385         {
  386                 /* cannot happen, STCR:TSF is set to 0 */
  387 
  388                 NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
  389         }
  390 #endif
  391 
  392         return(c);
  393 }
  394 
  395 /*---------------------------------------------------------------------------*
  396  *      ISACSX L1 Indication handler
  397  *---------------------------------------------------------------------------*/
  398 static void
  399 isic_isacsx_ind_hdlr(register struct isic_softc *sc, int ind)
  400 {
  401         register int event;
  402 
  403         switch(ind)
  404         {
  405                 case ISACSX_CIR0_IAI8:
  406                         NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc));
  407                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  408                                 isic_isacsx_l1_cmd(sc, CMD_AR8);
  409                         event = EV_INFO48;
  410                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
  411                         break;
  412 
  413                 case ISACSX_CIR0_IAI10:
  414                         NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc));
  415                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  416                                 isic_isacsx_l1_cmd(sc, CMD_AR10);
  417                         event = EV_INFO410;
  418                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
  419                         break;
  420 
  421                 case ISACSX_CIR0_IRSY:
  422                         NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc));
  423                         event = EV_RSY;
  424                         break;
  425 
  426                 case ISACSX_CIR0_IPU:
  427                         NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc));
  428                         event = EV_PU;
  429                         break;
  430 
  431                 case ISACSX_CIR0_IDR:
  432                         NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc));
  433                         isic_isacsx_l1_cmd(sc, CMD_DIU);
  434                         event = EV_DR;
  435                         break;
  436 
  437                 case ISACSX_CIR0_IDID:
  438                         NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc));
  439                         event = EV_INFO0;
  440                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_IDLE);
  441                         break;
  442 
  443                 case ISACSX_CIR0_IDIS:
  444                         NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc));
  445                         event = EV_DIS;
  446                         break;
  447 
  448                 case ISACSX_CIR0_IEI:
  449                         NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc));
  450                         isic_isacsx_l1_cmd(sc, CMD_DIU);
  451                         event = EV_EI;
  452                         break;
  453 
  454                 case ISACSX_CIR0_IARD:
  455                         NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc));
  456                         event = EV_INFO2;
  457                         break;
  458 
  459                 case ISACSX_CIR0_ITI:
  460                         NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc));
  461                         event = EV_INFO0;
  462                         break;
  463 
  464                 case ISACSX_CIR0_IATI:
  465                         NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc));
  466                         event = EV_INFO0;
  467                         break;
  468 
  469                 case ISACSX_CIR0_ISD:
  470                         NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc));
  471                         event = EV_INFO0;
  472                         break;
  473 
  474                 default:
  475                         NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc));
  476                         event = EV_INFO0;
  477                         break;
  478         }
  479         isic_next_state(sc, event);
  480 }
  481 
  482 /*---------------------------------------------------------------------------*
  483  *      execute a layer 1 command
  484  *---------------------------------------------------------------------------*/
  485 void
  486 isic_isacsx_l1_cmd(struct isic_softc *sc, int command)
  487 {
  488         u_char cmd;
  489 
  490 #ifdef I4B_SMP_WORKAROUND
  491 
  492         /* XXXXXXXXXXXXXXXXXXX */
  493 
  494         /*
  495          * patch from Wolfgang Helbig:
  496          *
  497          * Here is a patch that makes i4b work on an SMP:
  498          * The card (TELES 16.3) didn't interrupt on an SMP machine.
  499          * This is a gross workaround, but anyway it works *and* provides
  500          * some information as how to finally fix this problem.
  501          */
  502 
  503         HSCX_WRITE(0, H_MASK, 0xff);
  504         HSCX_WRITE(1, H_MASK, 0xff);
  505         ISAC_WRITE(I_MASKD, 0xff);
  506         ISAC_WRITE(I_MASK, 0xff);
  507         DELAY(100);
  508         HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
  509         HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
  510         ISAC_WRITE(I_MASKD, isacsx_imaskd);
  511         ISAC_WRITE(I_MASK, isacsx_imask);
  512 
  513         /* XXXXXXXXXXXXXXXXXXX */
  514 
  515 #endif /* I4B_SMP_WORKAROUND */
  516 
  517         if(command < 0 || command > CMD_ILL)
  518         {
  519                 NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc));
  520                 return;
  521         }
  522 
  523         cmd = ISACSX_CIX0_LOW;
  524 
  525         switch(command)
  526         {
  527                 case CMD_TIM:
  528                         NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc));
  529                         cmd |= (ISACSX_CIX0_CTIM << 4);
  530                         break;
  531 
  532                 case CMD_RS:
  533                         NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc));
  534                         cmd |= (ISACSX_CIX0_CRS << 4);
  535                         break;
  536 
  537                 case CMD_AR8:
  538                         NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc));
  539                         cmd |= (ISACSX_CIX0_CAR8 << 4);
  540                         break;
  541 
  542                 case CMD_AR10:
  543                         NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc));
  544                         cmd |= (ISACSX_CIX0_CAR10 << 4);
  545                         break;
  546 
  547                 case CMD_DIU:
  548                         NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc));
  549                         cmd |= (ISACSX_CIX0_CDIU << 4);
  550                         break;
  551         }
  552         ISAC_WRITE(I_CIX0, cmd);
  553 }
  554 
  555 /*---------------------------------------------------------------------------*
  556  *      L1 ISACSX initialization
  557  *---------------------------------------------------------------------------*/
  558 int
  559 isic_isacsx_init(struct isic_softc *sc)
  560 {
  561         isacsx_imaskd = 0xff;           /* disable all irqs */
  562         isacsx_imask = 0xff;            /* disable all irqs */
  563 
  564         ISAC_WRITE(I_MASKD, isacsx_imaskd);
  565         ISAC_WRITE(I_MASK, isacsx_imask);
  566 
  567         /* the ISACSX only runs in IOM-2 mode */
  568         NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
  569 
  570         /* TR_CONF0: Transceiver Configuration Register 0:
  571          *      DIS_TR - transceiver enabled
  572          *      EN_ICV - normal operation
  573          *      EXLP - no external loop
  574          *      LDD - automatic clock generation
  575          */
  576         ISAC_WRITE(I_WTR_CONF0, 0);
  577 
  578         /* TR_CONF2: Transceiver Configuration Register 1:
  579          *      DIS_TX - transmitter enabled
  580          *      PDS - phase deviation 2 S-bits
  581          *      RLP - remote line loop open
  582          */
  583         ISAC_WRITE(I_WTR_CONF2, 0);
  584 
  585         /* MODED: Mode Register:
  586          *      MDSx - transparent mode 0
  587          *      TMD  - timer mode = external
  588          *      RAC  - Receiver enabled
  589          *      DIMx - digital i/f mode
  590          */
  591         ISAC_WRITE(I_WMODED, ISACSX_MODED_MDS2|ISACSX_MODED_MDS1|ISACSX_MODED_RAC|ISACSX_MODED_DIM0);
  592 
  593         /* enabled interrupts:
  594          * ===================
  595          * RME  - receive message end
  596          * RPF  - receive pool full
  597          * RPO  - receive pool overflow
  598          * XPR  - transmit pool ready
  599          * XMR  - transmit message repeat
  600          * XDU  - transmit data underrun
  601          */
  602 
  603         isacsx_imaskd = ISACSX_MASKD_LOW;
  604         ISAC_WRITE(I_MASKD, isacsx_imaskd);
  605 
  606         /* enabled interrupts:
  607          * ===================
  608          * ICD - HDLC interrupt from D-channel
  609          * CIC - C/I channel change
  610          */
  611 
  612         isacsx_imask = ~(ISACSX_MASK_ICD | ISACSX_MASK_CIC);
  613 
  614         ISAC_WRITE(I_MASK, isacsx_imask);
  615 
  616         return(0);
  617 }
  618 
  619 /*---------------------------------------------------------------------------*
  620  *      L1 ISACSX disable interrupts
  621  *---------------------------------------------------------------------------*/
  622 void
  623 isic_isacsx_disable_intr(struct isic_softc *sc)
  624 {
  625         ISAC_WRITE(I_WMODED, ISACSX_MODED_MDS2|ISACSX_MODED_MDS1|ISACSX_MODED_DIM0);
  626         isacsx_imaskd = 0xff;           /* disable all irqs */
  627         isacsx_imask  = 0xff;           /* disable all irqs */
  628 
  629         ISAC_WRITE(I_MASKD, isacsx_imaskd);
  630         ISAC_WRITE(I_MASK, isacsx_imask);
  631 }
  632 
  633 /*---------------------------------------------------------------------------*
  634  *      ISACSX recover - try to recover from irq lockup
  635  *---------------------------------------------------------------------------*/
  636 void
  637 isic_isacsx_recover(struct isic_softc *sc)
  638 {
  639         u_char byte, istad;
  640 
  641 
  642         /*
  643          * XXX
  644          * Leo: Unknown if this function does anything good... At least it
  645          *      prints some stuff that might be helpful.
  646          */
  647 
  648         printf("%s: isic_isacsx_recover\n", device_xname(&sc->sc_dev));
  649         /* get isac irq status */
  650 
  651         byte = ISAC_READ(I_ISTAD);
  652 
  653         NDBGL1(L1_ERROR, "  ISAC: ISTAD = 0x%x", byte);
  654 
  655         if(byte & ISACSX_ISTA_ICD) {
  656                 istad = ISAC_READ(I_ISTAD);
  657                 NDBGL1(L1_ERROR, "  ISACSX: istad = 0x%02x", istad);
  658         }
  659 
  660         if(byte & ISACSX_ISTA_CIC)
  661         {
  662                 byte = ISAC_READ(I_CIR0);
  663 
  664                 NDBGL1(L1_ERROR, "  ISACSX: CIR0 = 0x%x", byte);
  665         }
  666 
  667         NDBGL1(L1_ERROR, "  ISACSX: IMASKD/IMASK = 0x%02x/%02x", isacsx_imaskd,
  668                                                         isacsx_imask);
  669 
  670         ISAC_WRITE(I_MASKD, 0xff);
  671         ISAC_WRITE(I_MASK, 0xff);
  672         DELAY(100);
  673         ISAC_WRITE(I_MASKD, isacsx_imaskd);
  674         ISAC_WRITE(I_MASK, isacsx_imask);
  675 }

Cache object: 99f645d9fd60b8adf40e50e24b16be7b


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