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/netisdn/i4b_ipr.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_ipr.c - isdn4bsd IP over raw HDLC ISDN network driver
   28  *      ---------------------------------------------------------
   29  *
   30  *      $Id: i4b_ipr.c,v 1.15 2003/04/11 14:45:29 drochner Exp $
   31  *
   32  * $FreeBSD$
   33  *
   34  *      last edit-date: [Fri Jan  5 11:33:47 2001]
   35  *
   36  *---------------------------------------------------------------------------*
   37  *
   38  *      statistics counter usage (interface lifetime):
   39  *      ----------------------------------------------
   40  *      sc->sc_if.if_ipackets   # of received packets
   41  *      sc->sc_if.if_ierrors    # of error packets not going to upper layers
   42  *      sc->sc_if.if_opackets   # of transmitted packets
   43  *      sc->sc_if.if_oerrors    # of error packets not being transmitted
   44  *      sc->sc_if.if_collisions # of invalid ip packets after VJ decompression
   45  *      sc->sc_if.if_ibytes     # of bytes coming in from the line (before VJ)
   46  *      sc->sc_if.if_obytes     # of bytes going out to the line (after VJ)
   47  *      sc->sc_if.if_imcasts      (currently unused)
   48  *      sc->sc_if.if_omcasts    # of frames sent out of the fastqueue
   49  *      sc->sc_if.if_iqdrops    # of frames dropped on input because queue full
   50  *      sc->sc_if.if_noproto    # of frames dropped on output because !AF_INET
   51  *
   52  *      statistics counter usage (connection lifetime):
   53  *      -----------------------------------------------
   54  *      sc->sc_iinb             # of ISDN incoming bytes from HSCX
   55  *      sc->sc_ioutb            # of ISDN outgoing bytes from HSCX
   56  *      sc->sc_inb              # of incoming bytes after decompression
   57  *      sc->sc_outb             # of outgoing bytes before compression
   58  *
   59  *---------------------------------------------------------------------------*/ 
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: i4b_ipr.c,v 1.15 2003/04/11 14:45:29 drochner Exp $");
   63 
   64 #include "irip.h"
   65 #include "opt_irip.h"
   66 
   67 #if NIRIP > 0
   68 
   69 #ifdef __FreeBSD__
   70 #include "opt_i4b.h"
   71 #endif
   72 
   73 #include <sys/param.h>
   74 #include <sys/systm.h>
   75 #include <sys/mbuf.h>
   76 #include <sys/socket.h>
   77 #include <sys/errno.h>
   78 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
   79 #include <sys/ioccom.h>
   80 #include <sys/sockio.h>
   81 #ifdef IPR_VJ
   82 #include <sys/malloc.h>
   83 #endif
   84 #else
   85 #include <sys/ioctl.h>
   86 #endif
   87 
   88 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
   89 #include <sys/callout.h>
   90 #endif
   91 
   92 #include <sys/kernel.h>
   93 #include <sys/protosw.h>
   94 
   95 #include <net/if.h>
   96 #include <net/if_types.h>
   97 #include <net/netisr.h>
   98 #include <net/route.h>
   99 
  100 #include <netinet/in.h>
  101 #include <netinet/in_systm.h>
  102 #include <netinet/in_var.h>
  103 #include <netinet/ip.h>
  104 
  105 #ifdef IRIP_VJ
  106 #include <net/slcompress.h>       
  107 #define IPR_COMPRESS IFF_LINK0  /* compress TCP traffic */
  108 #define IPR_AUTOCOMP IFF_LINK1  /* auto-enable TCP compression */
  109 
  110 /*---------------------------------------------------------------------------
  111  * NOTICE: using NO separate buffer relies on the assumption, that the HSCX
  112  * IRQ handler _always_ allocates a single, continuous mbuf cluster large
  113  * enough to hold the maximum MTU size if the ipr interface !
  114  *
  115  * CAUTION: i have re-defined IPR_VJ_USEBUFFER because it makes problems
  116  *          with 2 i4b's back to back running cvs over ssh, cvs simply
  117  *          aborts because it gets bad data. Everything else (telnet/ftp?etc)
  118  *          functions fine. 
  119  *---------------------------------------------------------------------------*/
  120 #define IPR_VJ_USEBUFFER        /* define to use an allocated separate buffer*/
  121                                 /* undef to uncompress in the mbuf itself    */
  122 #endif /* IRIP_VJ */
  123 
  124 #if defined(__FreeBSD_version) &&  __FreeBSD_version >= 400008
  125 #include "bpf.h"
  126 #else
  127 #include "bpfilter.h"
  128 #endif
  129 #if NBPFILTER > 0 || NBPF > 0
  130 #include <sys/time.h>
  131 #include <net/bpf.h>
  132 #endif
  133 
  134 #ifdef __FreeBSD__
  135 #include <machine/i4b_ioctl.h>
  136 #include <machine/i4b_debug.h>
  137 #else
  138 #include <netisdn/i4b_debug.h>
  139 #include <netisdn/i4b_ioctl.h>
  140 #endif
  141 
  142 #include <netisdn/i4b_global.h>
  143 #include <netisdn/i4b_mbuf.h>
  144 #include <netisdn/i4b_l3l4.h>
  145 
  146 #include <netisdn/i4b_l4.h>
  147 
  148 #ifndef __FreeBSD__
  149 #include <machine/cpu.h> /* For softnet */
  150 #endif
  151 
  152 #ifdef __FreeBSD__
  153 #define IPR_FMT "irip%d: "
  154 #define IPR_ARG(sc)     ((sc)->sc_if.if_unit)
  155 #define PDEVSTATIC      static
  156 #elif defined(__bsdi__)
  157 #define IPR_FMT "irip%d: "
  158 #define IPR_ARG(sc)     ((sc)->sc_if.if_unit)
  159 #define PDEVSTATIC      /* not static */
  160 #else
  161 #define IPR_FMT "%s: "
  162 #define IPR_ARG(sc)     ((sc)->sc_if.if_xname)
  163 #define PDEVSTATIC      /* not static */
  164 #endif
  165 
  166 #define I4BIPRMTU       1500            /* regular MTU */
  167 #define I4BIPRMAXMTU    2000            /* max MTU */
  168 #define I4BIPRMINMTU    500             /* min MTU */
  169 
  170 #define I4BIPRMAXQLEN   50              /* max queue length */
  171 
  172 #define I4BIPRACCT      1               /* enable accounting messages */
  173 #define I4BIPRACCTINTVL 2               /* accounting msg interval in secs */
  174 #define I4BIPRADJFRXP   1               /* adjust 1st rxd packet */
  175 
  176 
  177 struct ipr_softc {
  178         struct ifnet    sc_if;          /* network-visible interface    */
  179         int             sc_state;       /* state of the interface       */
  180 
  181         call_desc_t     *sc_cdp;        /* ptr to call descriptor       */
  182         isdn_link_t     *sc_ilt;        /* ptr to B channel driver/state */
  183 
  184         int             sc_unit;        /* which instance are we?       */
  185         int             sc_updown;      /* soft state of interface      */
  186         struct ifqueue  sc_fastq;       /* interactive traffic          */
  187         int             sc_dialresp;    /* dialresponse                 */
  188         int             sc_lastdialresp;/* last dialresponse            */
  189         
  190 #if I4BIPRACCT
  191         int             sc_iinb;        /* isdn driver # of inbytes     */
  192         int             sc_ioutb;       /* isdn driver # of outbytes    */
  193         int             sc_inb;         /* # of bytes rx'd              */
  194         int             sc_outb;        /* # of bytes tx'd              */
  195         int             sc_linb;        /* last # of bytes rx'd         */
  196         int             sc_loutb;       /* last # of bytes tx'd         */
  197         int             sc_fn;          /* flag, first null acct        */
  198 #endif  
  199 
  200 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
  201         struct callout  sc_callout;
  202 #endif
  203 #if defined(__FreeBSD__)
  204         struct callout_handle   sc_callout;
  205 #endif
  206 
  207 #ifdef I4BIPRADJFRXP
  208         int             sc_first_pkt;   /* flag, first rxd packet       */
  209 #endif
  210 #if IPR_LOG
  211         int             sc_log_first;   /* log first n packets          */
  212 #endif
  213 
  214 #ifdef IRIP_VJ
  215         struct slcompress sc_compr;     /* tcp compression data         */
  216 #ifdef IPR_VJ_USEBUFFER
  217         u_char          *sc_cbuf;       /* tcp decompression buffer     */
  218 #endif
  219 #endif
  220 
  221 } ipr_softc[NIRIP];
  222 
  223 enum ipr_states {
  224         ST_IDLE,                        /* initialized, ready, idle     */
  225         ST_DIALING,                     /* dialling out to remote       */
  226         ST_CONNECTED_W,                 /* connected to remote          */
  227         ST_CONNECTED_A,                 /* connected to remote          */
  228 };
  229 
  230 #if defined(__FreeBSD__) || defined(__bsdi__)
  231 #define THE_UNIT        sc->sc_if.if_unit
  232 #else
  233 #define THE_UNIT        sc->sc_unit
  234 #endif
  235 
  236 #ifdef __FreeBSD__
  237 #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001
  238 #  define IOCTL_CMD_T u_long
  239 #else
  240 #ifdef __NetBSD__
  241 #  define IOCTL_CMD_T u_long
  242 #else
  243 #  define IOCTL_CMD_T int
  244 #endif
  245 #endif
  246 PDEVSTATIC void iripattach(void *);
  247 PSEUDO_SET(iripattach, i4b_ipr);
  248 static int irpioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data);
  249 #else
  250 PDEVSTATIC void iripattach __P((void));
  251 static int iripioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
  252 #endif
  253 
  254 #ifdef __bsdi__
  255 static int iprwatchdog(int unit);
  256 #else
  257 static void iprwatchdog(struct ifnet *ifp);
  258 #endif
  259 static void ipr_tx_queue_empty(void *);
  260 static int iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rtp);
  261 static void iripclearqueues(struct ipr_softc *sc);
  262 static void ipr_set_linktab(void *softc, isdn_link_t *ilt);
  263 static void ipr_activity(void *softc, int rxtx);
  264 static void ipr_rx_data_rdy(void *softc);
  265 static void ipr_disconnect(void *softc, void *cdp);
  266 static void ipr_connect(void *softc, void *cdp);
  267 static void ipr_dialresponse(void *softc, int status, cause_t cause);
  268 static void ipr_updown(void *softc, int updown);
  269 static void* ipr_get_softc(int unit);
  270 
  271 static const struct isdn_l4_driver_functions
  272 ipr_l4_functions = {
  273         ipr_rx_data_rdy,
  274         ipr_tx_queue_empty,
  275         ipr_activity,
  276         ipr_connect,
  277         ipr_disconnect,
  278         ipr_dialresponse,
  279         ipr_updown,
  280         ipr_get_softc,
  281         ipr_set_linktab,
  282         NULL
  283 };
  284 
  285 static int irip_driver_id = -1;
  286 
  287 /*===========================================================================*
  288  *                      DEVICE DRIVER ROUTINES
  289  *===========================================================================*/
  290 
  291 /*---------------------------------------------------------------------------*
  292  *      interface attach routine at kernel boot time
  293  *---------------------------------------------------------------------------*/
  294 PDEVSTATIC void
  295 #ifdef __FreeBSD__
  296 iripattach(void *dummy)
  297 #else
  298 iripattach()
  299 #endif
  300 {
  301         struct ipr_softc *sc = ipr_softc;
  302         int i;
  303 
  304         irip_driver_id = isdn_l4_driver_attach("irip", NIRIP, &ipr_l4_functions);
  305         
  306         for(i=0; i < NIRIP; sc++, i++)
  307         {
  308                 NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
  309 
  310                 sc->sc_state = ST_IDLE;
  311                 sc->sc_unit = i;
  312                 
  313 #ifdef __FreeBSD__              
  314                 sc->sc_if.if_name = "irip";
  315 #if __FreeBSD__ < 3
  316                 sc->sc_if.if_next = NULL;
  317 #endif
  318                 sc->sc_if.if_unit = i;
  319 #elif defined(__bsdi__)
  320                 sc->sc_if.if_name = "irip";
  321                 sc->sc_if.if_unit = i;
  322 #else
  323                 sprintf(sc->sc_if.if_xname, "irip%d", i);
  324                 sc->sc_if.if_softc = sc;
  325 #endif
  326 
  327 #ifdef  IRIP_VJ
  328                 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_SIMPLEX | IPR_AUTOCOMP;
  329 #else
  330                 sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_SIMPLEX;
  331 #endif
  332 
  333 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
  334                 callout_init(&sc->sc_callout);
  335 #endif
  336 
  337                 sc->sc_if.if_mtu = I4BIPRMTU;
  338                 sc->sc_if.if_type = IFT_ISDNBASIC;
  339                 sc->sc_if.if_ioctl = iripioctl;
  340                 sc->sc_if.if_output = iripoutput;
  341 
  342                 IFQ_SET_MAXLEN(&sc->sc_if.if_snd, I4BIPRMAXQLEN);
  343                 sc->sc_fastq.ifq_maxlen = I4BIPRMAXQLEN;
  344                 IFQ_SET_READY(&sc->sc_if.if_snd);
  345                 
  346                 sc->sc_if.if_ipackets = 0;
  347                 sc->sc_if.if_ierrors = 0;
  348                 sc->sc_if.if_opackets = 0;
  349                 sc->sc_if.if_oerrors = 0;
  350                 sc->sc_if.if_collisions = 0;
  351                 sc->sc_if.if_ibytes = 0;
  352                 sc->sc_if.if_obytes = 0;
  353                 sc->sc_if.if_imcasts = 0;
  354                 sc->sc_if.if_omcasts = 0;
  355                 sc->sc_if.if_iqdrops = 0;
  356                 sc->sc_if.if_noproto = 0;
  357 
  358 #if I4BIPRACCT
  359                 sc->sc_if.if_timer = 0; 
  360                 sc->sc_if.if_watchdog = iprwatchdog;    
  361                 sc->sc_iinb = 0;
  362                 sc->sc_ioutb = 0;
  363                 sc->sc_inb = 0;
  364                 sc->sc_outb = 0;
  365                 sc->sc_linb = 0;
  366                 sc->sc_loutb = 0;
  367                 sc->sc_fn = 1;
  368 #endif
  369 #if IPR_LOG
  370                 sc->sc_log_first = IPR_LOG;
  371 #endif
  372 
  373 #ifdef  IRIP_VJ
  374 #ifdef __FreeBSD__
  375                 sl_compress_init(&sc->sc_compr, -1);
  376 #else
  377                 sl_compress_init(&sc->sc_compr);
  378 #endif
  379 
  380 #ifdef IPR_VJ_USEBUFFER
  381                 if(!((sc->sc_cbuf =
  382                    (u_char *)malloc(I4BIPRMAXMTU+128, M_DEVBUF, M_WAITOK))))
  383                 {
  384                         panic("if_ipr.c, ipr_attach: VJ malloc failed");
  385                 }
  386 #endif
  387 #endif
  388 
  389                 sc->sc_updown = SOFT_ENA;       /* soft enabled */
  390 
  391                 sc->sc_dialresp = DSTAT_NONE;   /* no response */
  392                 sc->sc_lastdialresp = DSTAT_NONE;
  393                 
  394 #if defined(__FreeBSD_version) && ((__FreeBSD_version >= 500009) || (410000 <= __FreeBSD_version && __FreeBSD_version < 500000))
  395                 /* do not call bpfattach in ether_ifattach */
  396                 ether_ifattach(&sc->sc_if, 0);
  397 #else
  398                 if_attach(&sc->sc_if);
  399                 if_alloc_sadl(&sc->sc_if);
  400 #endif
  401 
  402 #if NBPFILTER > 0 || NBPF > 0
  403 #ifdef __FreeBSD__
  404                 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
  405 #else
  406                 bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
  407 #endif
  408 #endif          
  409         }
  410 }
  411 
  412 /*---------------------------------------------------------------------------*
  413  *      output a packet to the ISDN B-channel
  414  *---------------------------------------------------------------------------*/
  415 static int
  416 iripoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  417          struct rtentry *rtp)
  418 {
  419         struct ipr_softc *sc;
  420         int s, rv;
  421         struct ifqueue *ifq = NULL;
  422         struct ip *ip;
  423         ALTQ_DECL(struct altq_pktattr pktattr;)
  424         
  425         s = splnet();
  426 
  427 #if defined(__FreeBSD__) || defined(__bsdi__)
  428         unit = ifp->if_unit;
  429         sc = &ipr_softc[unit];
  430 #else
  431         sc = ifp->if_softc;
  432 #endif
  433 
  434         /* check for IP */
  435         
  436         if(dst->sa_family != AF_INET)
  437         {
  438                 printf(IPR_FMT "af%d not supported\n", IPR_ARG(sc), dst->sa_family);
  439                 m_freem(m);
  440                 splx(s);
  441                 sc->sc_if.if_noproto++;
  442                 sc->sc_if.if_oerrors++;
  443                 return(EAFNOSUPPORT);
  444         }
  445 
  446         /* check interface state = UP */
  447         
  448         if(!(ifp->if_flags & IFF_UP))
  449         {
  450                 NDBGL4(L4_IPRDBG, "%s: interface is DOWN!", sc->sc_if.if_xname);
  451                 m_freem(m);
  452                 splx(s);
  453                 sc->sc_if.if_oerrors++;
  454                 return(ENETDOWN);
  455         }
  456 
  457         /* dial if necessary */
  458         
  459         if(sc->sc_state == ST_IDLE || sc->sc_state == ST_DIALING)
  460         {
  461 
  462 #ifdef NOTDEF
  463                 switch(sc->sc_dialresp)
  464                 {
  465                         case DSTAT_TFAIL:       /* transient failure */
  466                                 NDBGL4(L4_IPRDBG, "%s: transient dial failure!", sc->sc_if.if_xname);
  467                                 m_freem(m);
  468                                 iripclearqueues(sc);
  469                                 sc->sc_dialresp = DSTAT_NONE;
  470                                 splx(s);
  471                                 sc->sc_if.if_oerrors++;
  472                                 return(ENETUNREACH);
  473                                 break;
  474 
  475                         case DSTAT_PFAIL:       /* permanent failure */
  476                                 NDBGL4(L4_IPRDBG, "%s: permanent dial failure!", sc->sc_if.if_xname);
  477                                 m_freem(m);
  478                                 iripclearqueues(sc);
  479                                 sc->sc_dialresp = DSTAT_NONE;
  480                                 splx(s);
  481                                 sc->sc_if.if_oerrors++;
  482                                 return(EHOSTUNREACH);                           
  483                                 break;
  484 
  485                         case DSTAT_INONLY:      /* no dialout allowed*/
  486                                 NDBGL4(L4_IPRDBG, "%s: dialout not allowed failure!", sc->sc_if.if_xname);
  487                                 m_freem(m);
  488                                 iripclearqueues(sc);
  489                                 sc->sc_dialresp = DSTAT_NONE;
  490                                 splx(s);
  491                                 sc->sc_if.if_oerrors++;
  492                                 return(EHOSTUNREACH);                           
  493                                 break;
  494                 }
  495 #endif
  496 
  497                 NDBGL4(L4_IPRDBG, "%s: send dial request message!", sc->sc_if.if_xname);
  498                 NDBGL4(L4_DIALST, "%s: setting dial state to ST_DIALING", sc->sc_if.if_xname);
  499                 i4b_l4_dialout(irip_driver_id, sc->sc_unit);
  500                 sc->sc_state = ST_DIALING;
  501         }
  502 
  503 #if IPR_LOG
  504         if(sc->sc_log_first > 0)
  505         {
  506                 --(sc->sc_log_first);
  507                 i4b_l4_packet_ind(irip_driver_id, sc->sc_unit, 1, m );
  508         }
  509 #endif
  510 
  511         /*
  512          * check, if type of service indicates interactive, i.e. telnet,
  513          * traffic. in case it is interactive, put it into the fast queue,
  514          * else (i.e. ftp traffic) put it into the "normal" queue
  515          */
  516 
  517         IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
  518 
  519         ip = mtod(m, struct ip *);              /* get ptr to ip header */
  520          
  521         if(ip->ip_tos & IPTOS_LOWDELAY)
  522                 ifq = &sc->sc_fastq;
  523 
  524         /* check for space in choosen send queue */
  525 
  526         if ((ifq != NULL)
  527 #ifdef ALTQ
  528            && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0
  529 #endif
  530         ) {
  531                 if(IF_QFULL(ifq))
  532                 {
  533                         NDBGL4(L4_IPRDBG, "%s: send queue full!", sc->sc_if.if_xname);
  534                         IF_DROP(ifq);
  535                         m_freem(m);
  536                         sc->sc_if.if_oerrors++;
  537                         splx(s);
  538                         return(ENOBUFS);
  539                 }
  540                 IF_ENQUEUE(ifq, m);
  541         } else {
  542                 IFQ_ENQUEUE(&sc->sc_if.if_snd, m, &pktattr, rv);
  543                 if (rv != 0) {
  544                         sc->sc_if.if_oerrors++;
  545                         splx(s);
  546                         return rv;
  547                 }
  548         }
  549         
  550         NDBGL4(L4_IPRDBG, "%s: added packet to send queue!", sc->sc_if.if_xname);
  551 
  552         ipr_tx_queue_empty(sc);
  553 
  554         splx(s);
  555 
  556         return (0);
  557 }
  558 
  559 /*---------------------------------------------------------------------------*
  560  *      process ioctl
  561  *---------------------------------------------------------------------------*/
  562 #ifdef __FreeBSD__
  563 static int
  564 iripioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data)
  565 #else
  566 static int
  567 iripioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  568 #endif
  569 {
  570 #if defined(__FreeBSD__) || defined(__bsdi__)
  571         struct ipr_softc *sc = &ipr_softc[ifp->if_unit];
  572 #else
  573         struct ipr_softc *sc = ifp->if_softc;
  574 #endif
  575 
  576         struct ifreq *ifr = (struct ifreq *)data;
  577         struct ifaddr *ifa = (struct ifaddr *)data;
  578         int s;
  579         int error = 0;
  580 
  581         s = splnet();
  582         
  583         switch (cmd)
  584         {
  585                 case SIOCAIFADDR:       /* add interface address */
  586                 case SIOCSIFADDR:       /* set interface address */
  587                 case SIOCSIFDSTADDR:    /* set interface destination address */
  588                         if(ifa->ifa_addr->sa_family != AF_INET)
  589                                 error = EAFNOSUPPORT;
  590                         else
  591                                 sc->sc_if.if_flags |= IFF_UP;
  592                         break;
  593 
  594                 case SIOCSIFFLAGS:      /* set interface flags */
  595                         if(!(ifr->ifr_flags & IFF_UP))
  596                         {
  597                                 if(sc->sc_if.if_flags & IFF_RUNNING)
  598                                 {
  599                                         /* disconnect ISDN line */
  600                                         i4b_l4_drvrdisc(sc->sc_cdp->cdid);
  601                                         sc->sc_if.if_flags &= ~IFF_RUNNING;
  602                                 }
  603 
  604                                 sc->sc_state = ST_IDLE;
  605 
  606                                 /* empty queues */
  607 
  608                                 iripclearqueues(sc);
  609                         }
  610 
  611                         if(ifr->ifr_flags & IFF_DEBUG)
  612                         {
  613                                 /* enable debug messages */
  614                         }
  615                         
  616                         break;
  617 
  618 #if !defined(__OpenBSD__)                       
  619                 case SIOCSIFMTU:        /* set interface MTU */
  620                         if(ifr->ifr_mtu > I4BIPRMAXMTU)
  621                                 error = EINVAL;
  622                         else if(ifr->ifr_mtu < I4BIPRMINMTU)
  623                                 error = EINVAL;
  624                         else
  625                                 ifp->if_mtu = ifr->ifr_mtu;
  626                         break;
  627 #endif /* __OPENBSD__ */
  628 
  629 #if 0
  630         /* not needed for FreeBSD, done in sl_compress_init() (-hm) */
  631         
  632                         /* need to add an ioctl:        set VJ max slot ID
  633                          * #define IPRIOCSMAXCID        _IOW('I', XXX, int)
  634                          */
  635 #ifdef IPR_VJ
  636                 case IPRIOCSMAXCID:
  637                         {
  638                         struct proc *p = curproc;       /* XXX */
  639 
  640 #if defined(__FreeBSD_version) && __FreeBSD_version >= 400005
  641                         if((error = suser(p)) != 0)
  642 #else
  643                         if((error = suser(p->p_ucred, &p->p_acflag)) != 0)
  644 #endif
  645                                 break;
  646                         sl_compress_setup(sc->sc_compr, *(int *)data);
  647                         }
  648                         break;
  649 #endif
  650 #endif
  651                 default:
  652                         error = EINVAL;
  653                         break;
  654         }
  655 
  656         splx(s);
  657 
  658         return(error);
  659 }
  660 
  661 /*---------------------------------------------------------------------------*
  662  *      clear the interface's send queues
  663  *---------------------------------------------------------------------------*/
  664 static void
  665 iripclearqueues(struct ipr_softc *sc)
  666 {
  667         int x;
  668         struct mbuf *m;
  669         
  670         for(;;)
  671         {
  672                 x = splnet();
  673                 IF_DEQUEUE(&sc->sc_fastq, m);
  674                 splx(x);
  675 
  676                 if(m)
  677                         m_freem(m);
  678                 else
  679                         break;
  680         }
  681 
  682         for(;;)
  683         {
  684                 x = splnet();
  685                 IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
  686                 splx(x);
  687 
  688                 if(m)
  689                         m_freem(m);
  690                 else
  691                         break;
  692         }
  693 }
  694         
  695 #if I4BIPRACCT
  696 /*---------------------------------------------------------------------------*
  697  *      watchdog routine
  698  *---------------------------------------------------------------------------*/
  699 #ifdef __bsdi__
  700 static int
  701 iprwatchdog(int unit)
  702 {
  703 #else
  704 static void
  705 iprwatchdog(struct ifnet *ifp)
  706 {
  707 #endif
  708 #ifdef __FreeBSD__
  709         int unit = ifp->if_unit;
  710         struct ipr_softc *sc = &ipr_softc[unit];
  711 #elif defined(__bsdi__)
  712         struct ipr_softc *sc = &ipr_softc[unit];
  713         struct ifnet *ifp = &ipr_softc[unit].sc_if;
  714 #else
  715         struct ipr_softc *sc = ifp->if_softc;
  716 #endif
  717         bchan_statistics_t bs;
  718         
  719         /* get # of bytes in and out from the HSCX driver */ 
  720         
  721         (*sc->sc_ilt->bchannel_driver->bch_stat)
  722                 (sc->sc_ilt->l1token, sc->sc_ilt->channel, &bs);
  723 
  724         sc->sc_ioutb += bs.outbytes;
  725         sc->sc_iinb += bs.inbytes;
  726         
  727         if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn) 
  728         {
  729                 int ri = (sc->sc_iinb - sc->sc_linb)/I4BIPRACCTINTVL;
  730                 int ro = (sc->sc_ioutb - sc->sc_loutb)/I4BIPRACCTINTVL;
  731 
  732                 if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb))
  733                         sc->sc_fn = 0;
  734                 else
  735                         sc->sc_fn = 1;
  736                         
  737                 sc->sc_linb = sc->sc_iinb;
  738                 sc->sc_loutb = sc->sc_ioutb;
  739 
  740                 if (sc->sc_cdp)
  741                         i4b_l4_accounting(sc->sc_cdp->cdid, ACCT_DURING,
  742                             sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
  743         }
  744         sc->sc_if.if_timer = I4BIPRACCTINTVL;   
  745 #ifdef __bsdi__
  746         return 0;
  747 #endif
  748 }
  749 #endif /* I4BIPRACCT */
  750 
  751 /*===========================================================================*
  752  *                      ISDN INTERFACE ROUTINES
  753  *===========================================================================*/
  754 
  755 /*---------------------------------------------------------------------------*
  756  *      start transmitting after connect
  757  *---------------------------------------------------------------------------*/
  758 static void
  759 i4bipr_connect_startio(struct ipr_softc *sc)
  760 {
  761         int s = splnet();
  762         
  763         if(sc->sc_state == ST_CONNECTED_W)
  764         {
  765                 sc->sc_state = ST_CONNECTED_A;
  766                 ipr_tx_queue_empty(sc);
  767         }
  768 
  769         splx(s);
  770 }
  771  
  772 /*---------------------------------------------------------------------------*
  773  *      this routine is called from L4 handler at connect time
  774  *---------------------------------------------------------------------------*/
  775 static void
  776 ipr_connect(void *softc, void *cdp)
  777 {
  778         struct ipr_softc *sc = softc;
  779         int s;
  780 
  781         sc->sc_cdp = (call_desc_t *)cdp;
  782 
  783         s = splnet();
  784 
  785         NDBGL4(L4_DIALST, "%s: setting dial state to ST_CONNECTED", sc->sc_if.if_xname);
  786 
  787         sc->sc_if.if_flags |= IFF_RUNNING;
  788         sc->sc_state = ST_CONNECTED_W;
  789 
  790         sc->sc_dialresp = DSTAT_NONE;
  791         sc->sc_lastdialresp = DSTAT_NONE;       
  792         
  793 #if I4BIPRACCT
  794         sc->sc_iinb = 0;
  795         sc->sc_ioutb = 0;
  796         sc->sc_inb = 0;
  797         sc->sc_outb = 0;
  798         sc->sc_linb = 0;
  799         sc->sc_loutb = 0;
  800         sc->sc_if.if_timer = I4BIPRACCTINTVL;
  801 #endif
  802 
  803 #ifdef I4BIPRADJFRXP
  804         sc->sc_first_pkt = 1;
  805 #endif
  806 
  807         /*
  808          * Sometimes ISDN B-channels are switched thru asymmetic. This
  809          * means that under such circumstances B-channel data (the first
  810          * three packets of a TCP connection in my case) may get lost,
  811          * causing a large delay until the connection is started.
  812          * When the sending of the very first packet of a TCP connection
  813          * is delayed for a to be empirically determined delay (close
  814          * to a second in my case) those packets go thru and the TCP
  815          * connection comes up "almost" immediately (-hm).
  816          */
  817 
  818         if(sc->sc_cdp->isdntxdelay > 0)
  819         {
  820                 int delay;
  821 
  822                 if (hz == 100) {
  823                         delay = sc->sc_cdp->isdntxdelay;        /* avoid any rounding */
  824                 } else {
  825                         delay = sc->sc_cdp->isdntxdelay*hz;
  826                         delay /= 100;
  827                 }
  828 
  829                 START_TIMER(sc->sc_callout, (TIMEOUT_FUNC_T)i4bipr_connect_startio, (void *)sc,  delay);
  830         }
  831         else
  832         {
  833                 sc->sc_state = ST_CONNECTED_A;
  834                 ipr_tx_queue_empty(sc);
  835         }
  836 
  837         splx(s);
  838 
  839         /* we don't need any negotiation - pass event back right now */
  840         i4b_l4_negcomplete(sc->sc_cdp);
  841 }
  842         
  843 /*---------------------------------------------------------------------------*
  844  *      this routine is called from L4 handler at disconnect time
  845  *---------------------------------------------------------------------------*/
  846 static void
  847 ipr_disconnect(void *softc, void *cdp)
  848 {
  849         call_desc_t *cd = (call_desc_t *)cdp;
  850         struct ipr_softc *sc = softc;
  851 
  852         /* new stuff to check that the active channel is being closed */
  853 
  854         if (cd != sc->sc_cdp)
  855         {
  856                 NDBGL4(L4_IPRDBG, "%s: channel %d not active",
  857                                 sc->sc_if.if_xname, cd->channelid);
  858                 return;
  859         }
  860 
  861 #if I4BIPRACCT
  862         sc->sc_if.if_timer = 0;
  863 #endif
  864 #if IPR_LOG
  865         /* show next IPR_LOG packets again */
  866         sc->sc_log_first = IPR_LOG;
  867 #endif
  868 
  869         i4b_l4_accounting(cd->cdid, ACCT_FINAL,
  870                  sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb);
  871         
  872         sc->sc_cdp = NULL;
  873 
  874         NDBGL4(L4_DIALST, "setting dial state to ST_IDLE");
  875 
  876         sc->sc_dialresp = DSTAT_NONE;
  877         sc->sc_lastdialresp = DSTAT_NONE;       
  878 
  879         sc->sc_if.if_flags &= ~IFF_RUNNING;
  880         sc->sc_state = ST_IDLE;
  881 }
  882 
  883 /*---------------------------------------------------------------------------*
  884  *      this routine is used to give a feedback from userland daemon
  885  *      in case of dial problems
  886  *---------------------------------------------------------------------------*/
  887 static void
  888 ipr_dialresponse(void *softc, int status, cause_t cause)
  889 {
  890         struct ipr_softc *sc = softc;
  891         sc->sc_dialresp = status;
  892 
  893         NDBGL4(L4_IPRDBG, "%s: last=%d, this=%d",
  894                 sc->sc_if.if_xname, sc->sc_lastdialresp, sc->sc_dialresp);
  895 
  896         if(status != DSTAT_NONE)
  897         {
  898                 NDBGL4(L4_IPRDBG, "%s: clearing queues", sc->sc_if.if_xname);
  899                 iripclearqueues(sc);
  900         }
  901 }
  902         
  903 /*---------------------------------------------------------------------------*
  904  *      interface soft up/down
  905  *---------------------------------------------------------------------------*/
  906 static void
  907 ipr_updown(void *softc, int updown)
  908 {
  909         struct ipr_softc *sc = softc;
  910         sc->sc_updown = updown;
  911 }
  912         
  913 /*---------------------------------------------------------------------------*
  914  *      this routine is called from the HSCX interrupt handler
  915  *      when a new frame (mbuf) has been received and was put on
  916  *      the rx queue. It is assumed that this routines runs at
  917  *      appropriate protection level! Keep it short !
  918  *---------------------------------------------------------------------------*/
  919 static void
  920 ipr_rx_data_rdy(void *softc)
  921 {
  922         register struct ipr_softc *sc = softc;
  923         register struct mbuf *m;
  924 #ifdef IRIP_VJ
  925 #ifdef IPR_VJ_USEBUFFER
  926         u_char *cp = sc->sc_cbuf;
  927 #endif  
  928         int len, c;
  929 #endif
  930         
  931         if((m = *sc->sc_ilt->rx_mbuf) == NULL)
  932                 return;
  933 
  934         m->m_pkthdr.rcvif = &sc->sc_if;
  935 
  936         m->m_pkthdr.len = m->m_len;
  937 
  938 #ifdef I4BIPRADJFRXP
  939 
  940         /*
  941          * The very first packet after the B channel is switched thru
  942          * has very often several bytes of random data prepended. This
  943          * routine looks where the IP header starts and removes the
  944          * the bad data.
  945          */
  946 
  947         if(sc->sc_first_pkt)
  948         {
  949                 unsigned char *mp = m->m_data;
  950                 int i;
  951                 
  952                 sc->sc_first_pkt = 0;
  953 
  954                 for(i = 0; i < m->m_len; i++, mp++)
  955                 {
  956                         if( ((*mp & 0xf0) == 0x40) &&
  957                             ((*mp & 0x0f) >= 0x05) )
  958                         {
  959                                 m->m_data = mp;
  960                                 m->m_pkthdr.len -= i;                           
  961                                 break;
  962                         }
  963                 }
  964         }
  965 #endif
  966                 
  967         sc->sc_if.if_ipackets++;
  968         sc->sc_if.if_ibytes += m->m_pkthdr.len;
  969 
  970 #ifdef  IRIP_VJ
  971         if((c = (*(mtod(m, u_char *)) & 0xf0)) != (IPVERSION << 4))
  972         {
  973                 /* copy data to buffer */
  974 
  975                 len = m->m_len;
  976 
  977 #ifdef IPR_VJ_USEBUFFER
  978 /* XXX */       m_copydata(m, 0, len, cp);
  979 #endif
  980                 
  981                 if(c & 0x80)
  982                 {
  983                         c = TYPE_COMPRESSED_TCP;
  984                 }
  985                 else if(c == TYPE_UNCOMPRESSED_TCP)
  986                 {
  987 #ifdef IPR_VJ_USEBUFFER
  988                         *cp &= 0x4f;            /* XXX */
  989 #else
  990                         *(mtod(m, u_char *)) &= 0x4f;                   
  991 #endif                  
  992                 }
  993 
  994                 /*
  995                  * We've got something that's not an IP packet.
  996                  * If compression is enabled, try to decompress it.
  997                  * Otherwise, if `auto-enable' compression is on and
  998                  * it's a reasonable packet, decompress it and then
  999                  * enable compression.  Otherwise, drop it.
 1000                  */
 1001                 if(sc->sc_if.if_flags & IPR_COMPRESS)
 1002                 {
 1003 #ifdef IPR_VJ_USEBUFFER
 1004                         len = sl_uncompress_tcp(&cp,len,(u_int)c,&sc->sc_compr);
 1005 #else
 1006                         len = sl_uncompress_tcp((u_char **)&m->m_data, len,
 1007                                         (u_int)c, &sc->sc_compr);
 1008 #endif                  
 1009 
 1010                         if(len <= 0)
 1011                         {
 1012 #ifdef DEBUG_IPR_VJ
 1013                                 printf("i4b_ipr, ipr_rx_data_rdy: len <= 0 IPR_COMPRESS!\n");
 1014 #endif
 1015                                 goto error;
 1016                         }
 1017                 }
 1018                 else if((sc->sc_if.if_flags & IPR_AUTOCOMP) &&
 1019                         (c == TYPE_UNCOMPRESSED_TCP) && (len >= 40))
 1020                 {
 1021 #ifdef IPR_VJ_USEBUFFER
 1022                         len = sl_uncompress_tcp(&cp,len,(u_int)c,&sc->sc_compr);
 1023 #else
 1024                         len = sl_uncompress_tcp((u_char **)&m->m_data, len,
 1025                                         (u_int)c, &sc->sc_compr);
 1026 #endif
 1027 
 1028                         if(len <= 0)
 1029                         {
 1030 #ifdef DEBUG_IPR_VJ
 1031                                 printf("i4b_ipr, ipr_rx_data_rdy: len <= 0 IPR_AUTOCOMP!\n");
 1032 #endif
 1033                                 goto error;
 1034                         }
 1035 
 1036                         sc->sc_if.if_flags |= IPR_COMPRESS;
 1037                 }
 1038                 else
 1039                 {
 1040 #ifdef DEBUG_IPR_VJ
 1041                         printf("i4b_ipr, ipr_input: invalid ip packet!\n");
 1042 #endif
 1043 
 1044 error:
 1045                         sc->sc_if.if_ierrors++;
 1046                         sc->sc_if.if_collisions++;
 1047                         m_freem(m);
 1048                         return;
 1049                 }
 1050 #ifdef IPR_VJ_USEBUFFER
 1051 /* XXX */       m_copyback(m, 0, len, cp);
 1052 #else
 1053                 m->m_len = m->m_pkthdr.len = len;
 1054 #endif
 1055         }
 1056 #endif
 1057 
 1058 #if I4BIPRACCT
 1059         /* NB. do the accounting after decompression!           */
 1060         sc->sc_inb += m->m_pkthdr.len;
 1061 #endif
 1062 #if IPR_LOG
 1063         if(sc->sc_log_first > 0)
 1064         {
 1065                 --(sc->sc_log_first);
 1066                 i4b_l4_packet_ind(irip_driver_id, sc->sc_unit, 0, m );
 1067         }
 1068 #endif
 1069 
 1070 #if NBPFILTER > 0 || NBPF > 0
 1071         if(sc->sc_if.if_bpf)
 1072         {
 1073                 /* prepend the address family as a four byte field */           
 1074                 struct mbuf mm;
 1075                 u_int af = AF_INET;
 1076                 mm.m_next = m;
 1077                 mm.m_len = 4;
 1078                 mm.m_data = (char *)&af;
 1079 
 1080 #ifdef __FreeBSD__
 1081                 bpf_mtap(&sc->sc_if, &mm);
 1082 #else
 1083                 bpf_mtap(sc->sc_if.if_bpf, &mm);
 1084 #endif
 1085         }
 1086 #endif /* NBPFILTER > 0  || NBPF > 0 */
 1087 
 1088         if(IF_QFULL(&ipintrq))
 1089         {
 1090                 NDBGL4(L4_IPRDBG, "%s: ipintrq full!", sc->sc_if.if_xname);
 1091 
 1092                 IF_DROP(&ipintrq);
 1093                 sc->sc_if.if_ierrors++;
 1094                 sc->sc_if.if_iqdrops++;         
 1095                 m_freem(m);
 1096         }
 1097         else
 1098         {
 1099                 IF_ENQUEUE(&ipintrq, m);
 1100                 schednetisr(NETISR_IP);
 1101         }
 1102 }
 1103 
 1104 /*---------------------------------------------------------------------------*
 1105  *      this routine is called from the HSCX interrupt handler
 1106  *      when the last frame has been sent out and there is no
 1107  *      further frame (mbuf) in the tx queue.
 1108  *---------------------------------------------------------------------------*/
 1109 static void
 1110 ipr_tx_queue_empty(void *softc)
 1111 {
 1112         register struct ipr_softc *sc = softc;
 1113         register struct mbuf *m;
 1114 #ifdef  IRIP_VJ 
 1115         struct ip *ip;  
 1116 #endif
 1117         int x = 0;
 1118 
 1119         if(sc->sc_state != ST_CONNECTED_A)
 1120                 return;
 1121                 
 1122         for(;;)
 1123         {
 1124                 IF_DEQUEUE(&sc->sc_fastq, m);
 1125                 if(m)
 1126                 {
 1127                         sc->sc_if.if_omcasts++;
 1128                 }
 1129                 else
 1130                 {
 1131                         IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
 1132                         if(m == NULL)
 1133                                 break;
 1134                 }
 1135 
 1136 #if NBPFILTER > 0 || NBPF > 0
 1137                 if(sc->sc_if.if_bpf)
 1138                 {
 1139                         /* prepend the address family as a four byte field */
 1140         
 1141                         struct mbuf mm;
 1142                         u_int af = AF_INET;
 1143                         mm.m_next = m;
 1144                         mm.m_len = 4;
 1145                         mm.m_data = (char *)&af;
 1146         
 1147 #ifdef __FreeBSD__
 1148                         bpf_mtap(&sc->sc_if, &mm);
 1149 #else
 1150                         bpf_mtap(sc->sc_if.if_bpf, &mm);
 1151 #endif
 1152                 }
 1153 #endif /* NBPFILTER */
 1154         
 1155 #if I4BIPRACCT
 1156                 sc->sc_outb += m->m_pkthdr.len; /* size before compression */
 1157 #endif
 1158 
 1159 #ifdef  IRIP_VJ 
 1160                 if((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP)
 1161                 {
 1162                         if(sc->sc_if.if_flags & IPR_COMPRESS)
 1163                         {
 1164                                 *mtod(m, u_char *) |= sl_compress_tcp(m, ip,
 1165                                         &sc->sc_compr, 1);
 1166                         }
 1167                 }
 1168 #endif
 1169                 x = 1;
 1170 
 1171                 if(IF_QFULL(sc->sc_ilt->tx_queue))
 1172                 {
 1173                         NDBGL4(L4_IPRDBG, "%s: tx queue full!", sc->sc_if.if_xname);
 1174                         m_freem(m);
 1175                 }
 1176                 else
 1177                 {
 1178                         IF_ENQUEUE(sc->sc_ilt->tx_queue, m);
 1179 
 1180                         sc->sc_if.if_obytes += m->m_pkthdr.len;
 1181 
 1182                         sc->sc_if.if_opackets++;
 1183                 }
 1184         }
 1185 
 1186         if(x)
 1187                 (*sc->sc_ilt->bchannel_driver->bch_tx_start)(sc->sc_ilt->l1token, sc->sc_ilt->channel);
 1188 }
 1189 
 1190 /*---------------------------------------------------------------------------*
 1191  *      this routine is called from the HSCX interrupt handler
 1192  *      each time a packet is received or transmitted. It should
 1193  *      be used to implement an activity timeout mechanism.
 1194  *---------------------------------------------------------------------------*/
 1195 static void
 1196 ipr_activity(void *softc, int rxtx)
 1197 {
 1198         struct ipr_softc *sc = softc;
 1199         sc->sc_cdp->last_active_time = SECOND;
 1200 }
 1201 
 1202 /*---------------------------------------------------------------------------*
 1203  *      return this drivers linktab address
 1204  *---------------------------------------------------------------------------*/
 1205 static void*
 1206 ipr_get_softc(int unit)
 1207 {
 1208         return &ipr_softc[unit];
 1209 }
 1210 
 1211 /*---------------------------------------------------------------------------*
 1212  *      setup the isdn_linktab for this driver
 1213  *---------------------------------------------------------------------------*/
 1214 static void
 1215 ipr_set_linktab(void *softc, isdn_link_t *ilt)
 1216 {
 1217         struct ipr_softc *sc = softc;
 1218         sc->sc_ilt = ilt;
 1219 }
 1220 
 1221 /*===========================================================================*/
 1222 
 1223 #endif /* NIRIP > 0 */

Cache object: 2892d0df5b3decf565b04e3e23ea06dd


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