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/isac.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_isac.c - i4b siemens isdn chipset driver ISAC handler
   28  *      ---------------------------------------------------------
   29  *
   30  *      $Id: isac.c,v 1.22 2008/04/08 12:07:26 cegger 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: isac.c,v 1.22 2008/04/08 12:07:26 cegger Exp $");
   38 
   39 #ifdef __FreeBSD__
   40 #include "opt_i4b.h"
   41 #endif
   42 #include <sys/param.h>
   43 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   44 #include <sys/ioccom.h>
   45 #else
   46 #include <sys/ioctl.h>
   47 #endif
   48 #include <sys/kernel.h>
   49 #include <sys/systm.h>
   50 #include <sys/mbuf.h>
   51 #include <machine/stdarg.h>
   52 
   53 #ifdef __FreeBSD__
   54 #include <machine/clock.h>
   55 #include <i386/isa/isa_device.h>
   56 #else
   57 #ifndef __bsdi__
   58 #include <sys/bus.h>
   59 #endif
   60 #include <sys/device.h>
   61 #endif
   62 
   63 #include <sys/socket.h>
   64 #include <net/if.h>
   65 
   66 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   67 #include <sys/callout.h>
   68 #endif
   69 
   70 #ifdef __FreeBSD__
   71 #include <machine/i4b_debug.h>
   72 #include <machine/i4b_ioctl.h>
   73 #include <machine/i4b_trace.h>
   74 #else
   75 #include <netisdn/i4b_debug.h>
   76 #include <netisdn/i4b_ioctl.h>
   77 #include <netisdn/i4b_trace.h>
   78 #endif
   79 
   80 #include <netisdn/i4b_global.h>
   81 #include <netisdn/i4b_l2.h>
   82 #include <netisdn/i4b_l1l2.h>
   83 #include <netisdn/i4b_mbuf.h>
   84 
   85 #include <dev/ic/isic_l1.h>
   86 #include <dev/ic/isac.h>
   87 #include <dev/ic/ipac.h>
   88 #include <dev/ic/hscx.h>
   89 
   90 static u_char isic_isac_exir_hdlr(register struct isic_softc *sc, u_char exir);
   91 static void isic_isac_ind_hdlr(register struct isic_softc *sc, int ind);
   92 
   93 /*---------------------------------------------------------------------------*
   94  *      ISAC interrupt service routine
   95  *---------------------------------------------------------------------------*/
   96 void
   97 isic_isac_irq(struct isic_softc *sc, int ista)
   98 {
   99         register u_char c = 0;
  100         NDBGL1(L1_F_MSG, "%s: ista = 0x%02x", device_xname(&sc->sc_dev), ista);
  101 
  102         if(ista & ISAC_ISTA_EXI)        /* extended interrupt */
  103         {
  104                 u_int8_t exirstat = ISAC_READ(I_EXIR);
  105                 if (sc->sc_intr_valid == ISIC_INTR_VALID)
  106                         c |= isic_isac_exir_hdlr(sc, exirstat);
  107         }
  108 
  109         if(ista & ISAC_ISTA_RME)        /* receive message end */
  110         {
  111                 register int rest;
  112                 u_char rsta;
  113 
  114                 /* get rx status register */
  115 
  116                 rsta = ISAC_READ(I_RSTA);
  117 
  118                 if((rsta & ISAC_RSTA_MASK) != 0x20)
  119                 {
  120                         int error = 0;
  121 
  122                         if(!(rsta & ISAC_RSTA_CRC))     /* CRC error */
  123                         {
  124                                 error++;
  125                                 NDBGL1(L1_I_ERR, "%s: CRC error", device_xname(&sc->sc_dev));
  126                         }
  127 
  128                         if(rsta & ISAC_RSTA_RDO)        /* ReceiveDataOverflow */
  129                         {
  130                                 error++;
  131                                 NDBGL1(L1_I_ERR, "%s: Data Overrun error", device_xname(&sc->sc_dev));
  132                         }
  133 
  134                         if(rsta & ISAC_RSTA_RAB)        /* ReceiveABorted */
  135                         {
  136                                 error++;
  137                                 NDBGL1(L1_I_ERR, "%s: Receive Aborted error", device_xname(&sc->sc_dev));
  138                         }
  139 
  140                         if(error == 0)
  141                         {
  142                                 NDBGL1(L1_I_ERR, "%s: RME unknown error, RSTA = 0x%02x!", device_xname(&sc->sc_dev), rsta);
  143                         }
  144 
  145                         i4b_Dfreembuf(sc->sc_ibuf);
  146 
  147                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
  148 
  149                         sc->sc_ibuf = NULL;
  150                         sc->sc_ib = NULL;
  151                         sc->sc_ilen = 0;
  152 
  153                         ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES);
  154                         ISACCMDRWRDELAY();
  155 
  156                         return;
  157                 }
  158 
  159                 rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1));
  160 
  161                 if(rest == 0)
  162                         rest = ISAC_FIFO_LEN;
  163 
  164                 if(sc->sc_ibuf == NULL)
  165                 {
  166                         if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL)
  167                                 sc->sc_ib = sc->sc_ibuf->m_data;
  168                         else
  169                                 panic("isic_isac_irq: RME, i4b_Dgetmbuf returns NULL!");
  170                         sc->sc_ilen = 0;
  171                 }
  172 
  173                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest))
  174                 {
  175                         ISAC_RDFIFO(sc->sc_ib, rest);
  176                         sc->sc_ilen += rest;
  177 
  178                         sc->sc_ibuf->m_pkthdr.len =
  179                                 sc->sc_ibuf->m_len = sc->sc_ilen;
  180 
  181                         if(sc->sc_trace & TRACE_D_RX)
  182                         {
  183                                 i4b_trace_hdr hdr;
  184                                 memset(&hdr, 0, sizeof hdr);
  185                                 hdr.type = TRC_CH_D;
  186                                 hdr.dir = FROM_NT;
  187                                 hdr.count = ++sc->sc_trace_dcount;
  188                                 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data);
  189                         }
  190 
  191                         c |= ISAC_CMDR_RMC;
  192 
  193                         if(sc->sc_intr_valid == ISIC_INTR_VALID &&
  194                            (((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S))
  195                         {
  196                                 isdn_layer2_data_ind(&sc->sc_l2, sc->sc_l3token, sc->sc_ibuf);
  197                         }
  198                         else
  199                         {
  200                                 i4b_Dfreembuf(sc->sc_ibuf);
  201                         }
  202                 }
  203                 else
  204                 {
  205                         NDBGL1(L1_I_ERR, "RME, input buffer overflow!");
  206                         i4b_Dfreembuf(sc->sc_ibuf);
  207                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
  208                 }
  209 
  210                 sc->sc_ibuf = NULL;
  211                 sc->sc_ib = NULL;
  212                 sc->sc_ilen = 0;
  213         }
  214 
  215         if(ista & ISAC_ISTA_RPF)        /* receive fifo full */
  216         {
  217                 if(sc->sc_ibuf == NULL)
  218                 {
  219                         if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL)
  220                                 sc->sc_ib= sc->sc_ibuf->m_data;
  221                         else
  222                                 panic("isic_isac_irq: RPF, i4b_Dgetmbuf returns NULL!");
  223                         sc->sc_ilen = 0;
  224                 }
  225 
  226                 if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN))
  227                 {
  228                         ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN);
  229                         sc->sc_ilen += ISAC_FIFO_LEN;
  230                         sc->sc_ib += ISAC_FIFO_LEN;
  231                         c |= ISAC_CMDR_RMC;
  232                 }
  233                 else
  234                 {
  235                         NDBGL1(L1_I_ERR, "RPF, input buffer overflow!");
  236                         i4b_Dfreembuf(sc->sc_ibuf);
  237                         sc->sc_ibuf = NULL;
  238                         sc->sc_ib = NULL;
  239                         sc->sc_ilen = 0;
  240                         c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
  241                 }
  242         }
  243 
  244         if(ista & ISAC_ISTA_XPR)        /* transmit fifo empty (XPR bit set) */
  245         {
  246                 if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL))
  247                 {
  248                         sc->sc_freeflag = sc->sc_freeflag2;
  249                         sc->sc_obuf = sc->sc_obuf2;
  250                         sc->sc_op = sc->sc_obuf->m_data;
  251                         sc->sc_ol = sc->sc_obuf->m_len;
  252                         sc->sc_obuf2 = NULL;
  253 #ifdef NOTDEF
  254                         printf("ob2=%x, op=%x, ol=%d, f=%d #",
  255                                 sc->sc_obuf,
  256                                 sc->sc_op,
  257                                 sc->sc_ol,
  258                                 sc->sc_state);
  259 #endif
  260                 }
  261                 else
  262                 {
  263 #ifdef NOTDEF
  264                         printf("ob=%x, op=%x, ol=%d, f=%d #",
  265                                 sc->sc_obuf,
  266                                 sc->sc_op,
  267                                 sc->sc_ol,
  268                                 sc->sc_state);
  269 #endif
  270                 }
  271 
  272                 if(sc->sc_obuf)
  273                 {
  274                         ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN));
  275 
  276                         if(sc->sc_ol > ISAC_FIFO_LEN)   /* length > 32 ? */
  277                         {
  278                                 sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */
  279                                 sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */
  280                                 c |= ISAC_CMDR_XTF;         /* set XTF bit */
  281                         }
  282                         else
  283                         {
  284                                 if(sc->sc_freeflag)
  285                                 {
  286                                         i4b_Dfreembuf(sc->sc_obuf);
  287                                         sc->sc_freeflag = 0;
  288                                 }
  289                                 sc->sc_obuf = NULL;
  290                                 sc->sc_op = NULL;
  291                                 sc->sc_ol = 0;
  292 
  293                                 c |= ISAC_CMDR_XTF | ISAC_CMDR_XME;
  294                         }
  295                 }
  296                 else
  297                 {
  298                         sc->sc_state &= ~ISAC_TX_ACTIVE;
  299                 }
  300         }
  301 
  302         if(ista & ISAC_ISTA_CISQ)       /* channel status change CISQ */
  303         {
  304                 register u_char ci;
  305 
  306                 /* get command/indication rx register*/
  307 
  308                 ci = ISAC_READ(I_CIRR);
  309 
  310                 /* if S/Q IRQ, read SQC reg to clr SQC IRQ */
  311 
  312                 if(ci & ISAC_CIRR_SQC)
  313                         (void) ISAC_READ(I_SQRR);
  314 
  315                 /* C/I code change IRQ (flag already cleared by CIRR read) */
  316 
  317                 if(ci & ISAC_CIRR_CIC0)
  318                         isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf);
  319         }
  320 
  321         if(c)
  322         {
  323                 ISAC_WRITE(I_CMDR, c);
  324                 ISACCMDRWRDELAY();
  325         }
  326 }
  327 
  328 /*---------------------------------------------------------------------------*
  329  *      ISAC L1 Extended IRQ handler
  330  *---------------------------------------------------------------------------*/
  331 static u_char
  332 isic_isac_exir_hdlr(register struct isic_softc *sc, u_char exir)
  333 {
  334         u_char c = 0;
  335 
  336         if(exir & ISAC_EXIR_XMR)
  337         {
  338                 NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat");
  339 
  340                 c |= ISAC_CMDR_XRES;
  341         }
  342 
  343         if(exir & ISAC_EXIR_XDU)
  344         {
  345                 NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun");
  346 
  347                 c |= ISAC_CMDR_XRES;
  348         }
  349 
  350         if(exir & ISAC_EXIR_PCE)
  351         {
  352                 NDBGL1(L1_I_ERR, "EXIRQ Protocol Error");
  353         }
  354 
  355         if(exir & ISAC_EXIR_RFO)
  356         {
  357                 NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow");
  358 
  359                 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES;
  360         }
  361 
  362         if(exir & ISAC_EXIR_SOV)
  363         {
  364                 NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow");
  365         }
  366 
  367         if(exir & ISAC_EXIR_MOS)
  368         {
  369                 NDBGL1(L1_I_ERR, "EXIRQ Monitor Status");
  370         }
  371 
  372         if(exir & ISAC_EXIR_SAW)
  373         {
  374                 /* cannot happen, STCR:TSF is set to 0 */
  375 
  376                 NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake");
  377         }
  378 
  379         if(exir & ISAC_EXIR_WOV)
  380         {
  381                 /* cannot happen, STCR:TSF is set to 0 */
  382 
  383                 NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow");
  384         }
  385 
  386         return(c);
  387 }
  388 
  389 /*---------------------------------------------------------------------------*
  390  *      ISAC L1 Indication handler
  391  *---------------------------------------------------------------------------*/
  392 static void
  393 isic_isac_ind_hdlr(register struct isic_softc *sc, int ind)
  394 {
  395         register int event;
  396 
  397         switch(ind)
  398         {
  399                 case ISAC_CIRR_IAI8:
  400                         NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc));
  401                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  402                                 isic_isac_l1_cmd(sc, CMD_AR8);
  403                         event = EV_INFO48;
  404                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
  405                         break;
  406 
  407                 case ISAC_CIRR_IAI10:
  408                         NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc));
  409                         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  410                                 isic_isac_l1_cmd(sc, CMD_AR10);
  411                         event = EV_INFO410;
  412                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE);
  413                         break;
  414 
  415                 case ISAC_CIRR_IRSY:
  416                         NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc));
  417                         event = EV_RSY;
  418                         break;
  419 
  420                 case ISAC_CIRR_IPU:
  421                         NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc));
  422                         event = EV_PU;
  423                         break;
  424 
  425                 case ISAC_CIRR_IDR:
  426                         NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc));
  427                         isic_isac_l1_cmd(sc, CMD_DIU);
  428                         event = EV_DR;
  429                         break;
  430 
  431                 case ISAC_CIRR_IDID:
  432                         NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc));
  433                         event = EV_INFO0;
  434                         isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_IDLE);
  435                         break;
  436 
  437                 case ISAC_CIRR_IDIS:
  438                         NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc));
  439                         event = EV_DIS;
  440                         break;
  441 
  442                 case ISAC_CIRR_IEI:
  443                         NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc));
  444                         isic_isac_l1_cmd(sc, CMD_DIU);
  445                         event = EV_EI;
  446                         break;
  447 
  448                 case ISAC_CIRR_IARD:
  449                         NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc));
  450                         event = EV_INFO2;
  451                         break;
  452 
  453                 case ISAC_CIRR_ITI:
  454                         NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc));
  455                         event = EV_INFO0;
  456                         break;
  457 
  458                 case ISAC_CIRR_IATI:
  459                         NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc));
  460                         event = EV_INFO0;
  461                         break;
  462 
  463                 case ISAC_CIRR_ISD:
  464                         NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc));
  465                         event = EV_INFO0;
  466                         break;
  467 
  468                 default:
  469                         NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc));
  470                         event = EV_INFO0;
  471                         break;
  472         }
  473         isic_next_state(sc, event);
  474 }
  475 
  476 /*---------------------------------------------------------------------------*
  477  *      execute a layer 1 command
  478  *---------------------------------------------------------------------------*/
  479 void
  480 isic_isac_l1_cmd(struct isic_softc *sc, int command)
  481 {
  482         u_char cmd;
  483 
  484 #ifdef I4B_SMP_WORKAROUND
  485 
  486         /* XXXXXXXXXXXXXXXXXXX */
  487 
  488         /*
  489          * patch from Wolfgang Helbig:
  490          *
  491          * Here is a patch that makes i4b work on an SMP:
  492          * The card (TELES 16.3) didn't interrupt on an SMP machine.
  493          * This is a gross workaround, but anyway it works *and* provides
  494          * some information as how to finally fix this problem.
  495          */
  496 
  497         HSCX_WRITE(0, H_MASK, 0xff);
  498         HSCX_WRITE(1, H_MASK, 0xff);
  499         ISAC_WRITE(I_MASK, 0xff);
  500         DELAY(100);
  501         HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
  502         HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
  503         ISAC_WRITE(I_MASK, ISAC_IMASK);
  504 
  505         /* XXXXXXXXXXXXXXXXXXX */
  506 
  507 #endif /* I4B_SMP_WORKAROUND */
  508 
  509         if(command < 0 || command > CMD_ILL)
  510         {
  511                 NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc));
  512                 return;
  513         }
  514 
  515         if(sc->sc_bustyp == BUS_TYPE_IOM2)
  516                 cmd = ISAC_CIX0_LOW;
  517         else
  518                 cmd = 0;
  519 
  520         switch(command)
  521         {
  522                 case CMD_TIM:
  523                         NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc));
  524                         cmd |= (ISAC_CIXR_CTIM << 2);
  525                         break;
  526 
  527                 case CMD_RS:
  528                         NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc));
  529                         cmd |= (ISAC_CIXR_CRS << 2);
  530                         break;
  531 
  532                 case CMD_AR8:
  533                         NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc));
  534                         cmd |= (ISAC_CIXR_CAR8 << 2);
  535                         break;
  536 
  537                 case CMD_AR10:
  538                         NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc));
  539                         cmd |= (ISAC_CIXR_CAR10 << 2);
  540                         break;
  541 
  542                 case CMD_DIU:
  543                         NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc));
  544                         cmd |= (ISAC_CIXR_CDIU << 2);
  545                         break;
  546         }
  547         ISAC_WRITE(I_CIXR, cmd);
  548 }
  549 
  550 /*---------------------------------------------------------------------------*
  551  *      L1 ISAC initialization
  552  *---------------------------------------------------------------------------*/
  553 int
  554 isic_isac_init(struct isic_softc *sc)
  555 {
  556         ISAC_IMASK = 0xff;              /* disable all irqs */
  557 
  558         ISAC_WRITE(I_MASK, ISAC_IMASK);
  559 
  560         if(sc->sc_bustyp != BUS_TYPE_IOM2)
  561         {
  562                 NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode");
  563 
  564                 /* ADF2: Select mode IOM-1 */
  565                 ISAC_WRITE(I_ADF2, 0x00);
  566 
  567                 /* SPCR: serial port control register:
  568                  *      SPU - software power up = 0
  569                  *      SAC - SIP port high Z
  570                  *      SPM - timing mode 0
  571                  *      TLP - test loop = 0
  572                  *      C1C, C2C - B1 and B2 switched to/from SPa
  573                  */
  574                 ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1);
  575 
  576                 /* SQXR: S/Q channel xmit register:
  577                  *      SQIE - S/Q IRQ enable = 0
  578                  *      SQX1-4 - Fa bits = 1
  579                  */
  580                 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
  581 
  582                 /* ADF1: additional feature reg 1:
  583                  *      WTC - watchdog = 0
  584                  *      TEM - test mode = 0
  585                  *      PFS - pre-filter = 0
  586                  *      CFS - IOM clock/frame always active
  587                  *      FSC1/2 - polarity of 8kHz strobe
  588                  *      ITF - interframe fill = idle
  589                  */
  590                 ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2);      /* ADF1 */
  591 
  592                 /* STCR: sync transfer control reg:
  593                  *      TSF - terminal secific functions = 0
  594                  *      TBA - TIC bus address = 7
  595                  *      STx/SCx = 0
  596                  */
  597                 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
  598         }
  599         else
  600         {
  601                 NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode");
  602 
  603                 /* ADF2: Select mode IOM-2 */
  604                 ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS);
  605 
  606                 /* SPCR: serial port control register:
  607                  *      SPU - software power up = 0
  608                  *      SPM - timing mode 0
  609                  *      TLP - test loop = 0
  610                  *      C1C, C2C - B1 + C1 and B2 + IC2 monitoring
  611                  */
  612                 ISAC_WRITE(I_SPCR, 0x00);
  613 
  614                 /* SQXR: S/Q channel xmit register:
  615                  *      IDC  - IOM direction = 0 (master)
  616                  *      CFS  - Config Select = 0 (clock always active)
  617                  *      CI1E - C/I channel 1 IRQ enable = 0
  618                  *      SQIE - S/Q IRQ enable = 0
  619                  *      SQX1-4 - Fa bits = 1
  620                  */
  621                 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4);
  622 
  623                 /* ADF1: additional feature reg 1:
  624                  *      WTC - watchdog = 0
  625                  *      TEM - test mode = 0
  626                  *      PFS - pre-filter = 0
  627                  *      IOF - IOM i/f off = 0
  628                  *      ITF - interframe fill = idle
  629                  */
  630                 ISAC_WRITE(I_ADF1, 0x00);
  631 
  632                 /* STCR: sync transfer control reg:
  633                  *      TSF - terminal secific functions = 0
  634                  *      TBA - TIC bus address = 7
  635                  *      STx/SCx = 0
  636                  */
  637                 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0);
  638         }
  639 
  640 
  641         /* MODE: Mode Register:
  642          *      MDSx - transparent mode 2
  643          *      TMD  - timer mode = external
  644          *      RAC  - Receiver enabled
  645          *      DIMx - digital i/f mode
  646          */
  647         ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0);
  648 
  649         /* enabled interrupts:
  650          * ===================
  651          * RME  - receive message end
  652          * RPF  - receive pool full
  653          * XPR  - transmit pool ready
  654          * CISQ - CI or S/Q channel change
  655          * EXI  - extended interrupt
  656          */
  657 
  658         ISAC_IMASK = ISAC_MASK_RSC |    /* auto mode only       */
  659                      ISAC_MASK_TIN |    /* timer irq            */
  660                      ISAC_MASK_SIN;     /* sync xfer irq        */
  661 
  662         ISAC_WRITE(I_MASK, ISAC_IMASK);
  663 
  664         ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES);
  665         ISACCMDRWRDELAY();
  666 
  667         return(0);
  668 }
  669 
  670 /*---------------------------------------------------------------------------*
  671  *      isic_recovery - try to recover from irq lockup
  672  *---------------------------------------------------------------------------*/
  673 void
  674 isic_recover(struct isic_softc *sc)
  675 {
  676         u_char byte;
  677 
  678         /* get hscx irq status from hscx b ista */
  679 
  680         byte = HSCX_READ(HSCX_CH_B, H_ISTA);
  681 
  682         NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte);
  683 
  684         if(byte & HSCX_ISTA_ICA)
  685                 NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA));
  686 
  687         if(byte & HSCX_ISTA_EXB)
  688                 NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR));
  689 
  690         if(byte & HSCX_ISTA_EXA)
  691                 NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR));
  692 
  693         /* get isac irq status */
  694 
  695         byte = ISAC_READ(I_ISTA);
  696 
  697         NDBGL1(L1_ERROR, "  ISAC: ISTA = 0x%x", byte);
  698 
  699         if(byte & ISAC_ISTA_EXI)
  700                 NDBGL1(L1_ERROR, "  ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
  701 
  702         if(byte & ISAC_ISTA_CISQ)
  703         {
  704                 byte = ISAC_READ(I_CIRR);
  705 
  706                 NDBGL1(L1_ERROR, "  ISAC: CISQ = 0x%x", byte);
  707 
  708                 if(byte & ISAC_CIRR_SQC)
  709                         NDBGL1(L1_ERROR, "  ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
  710         }
  711 
  712         NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK);
  713         NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK);
  714 
  715         HSCX_WRITE(0, H_MASK, 0xff);
  716         HSCX_WRITE(1, H_MASK, 0xff);
  717         DELAY(100);
  718         HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
  719         HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
  720         DELAY(100);
  721 
  722         NDBGL1(L1_ERROR, "  ISAC: IMASK = 0x%x", ISAC_IMASK);
  723 
  724         ISAC_WRITE(I_MASK, 0xff);
  725         DELAY(100);
  726         ISAC_WRITE(I_MASK, ISAC_IMASK);
  727 }

Cache object: e743083963d1a3a3b98d83212e3f259c


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