Make all network interrupt service routines MPSAFE part 1/3.
[dragonfly.git] / sys / net / i4b / driver / i4b_ipr.c
index c04cf18..6636868 100644 (file)
@@ -28,7 +28,7 @@
  *     ---------------------------------------------------------
  *
  * $FreeBSD: src/sys/i4b/driver/i4b_ipr.c,v 1.8.2.3 2001/10/27 15:48:17 hm Exp $
- * $DragonFly: src/sys/net/i4b/driver/i4b_ipr.c,v 1.12 2004/09/16 04:36:30 dillon Exp $
+ * $DragonFly: src/sys/net/i4b/driver/i4b_ipr.c,v 1.18 2005/11/28 17:13:45 dillon Exp $
  *
  *     last edit-date: [Fri Oct 26 19:32:38 2001]
  *
@@ -61,9 +61,7 @@
 
 #if NI4BIPR > 0
 
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 #include "opt_i4b.h"
-#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/socket.h>
 #include <sys/errno.h>
 
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 #include <sys/ioccom.h>
 #include <sys/sockio.h>
 #ifdef IPR_VJ
 #include <sys/malloc.h>
 #endif
-#else
-#include <sys/ioctl.h>
-#endif
-
-#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
-#include <sys/callout.h>
-#endif
 
 #include <sys/kernel.h>
+#include <sys/thread2.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
                                /* undef to uncompress in the mbuf itself    */
 #endif /* IPR_VJ */
 
-#if defined(__DragonFly__) || (defined(__FreeBSD_version) &&  __FreeBSD_version >= 400008)
 #include "use_bpf.h"
-#else
-#include "bpfilter.h"
-#endif
 
 #if NBPFILTER > 0 || NBPF > 0
 #include <sys/time.h>
 #include <net/bpf.h>
 #endif
 
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 #include <net/i4b/include/machine/i4b_debug.h>
 #include <net/i4b/include/machine/i4b_ioctl.h>
-#else
-#include <i4b/i4b_debug.h>
-#include <i4b/i4b_ioctl.h>
-#endif
 
 #include "../include/i4b_global.h"
 #include "../include/i4b_l3l4.h"
 
 #include "../layer4/i4b_l4.h"
 
-#if !defined(__DragonFly__) || !defined(__FreeBSD__)
-#include <machine/cpu.h> /* For softnet */
-#endif
-
-#if defined(__FreeBSD__) && !defined(__DragonFly__)
-#define IPR_FMT        "ipr%d: "
-#define        IPR_ARG(sc)     ((sc)->sc_if.if_unit)
-#define        PDEVSTATIC      static
-#elif defined(__bsdi__)
-#define IPR_FMT        "ipr%d: "
-#define        IPR_ARG(sc)     ((sc)->sc_if.if_unit)
-#define        PDEVSTATIC      /* not static */
-#else
 #define        IPR_FMT "%s: "
 #define        IPR_ARG(sc)     ((sc)->sc_if.if_xname)
 #define        PDEVSTATIC      /* not static */
-#endif
 
 #define I4BIPRMTU      1500            /* regular MTU */
 #define I4BIPRMAXMTU   2000            /* max MTU */
@@ -175,11 +143,7 @@ static isdn_link_t *isdn_linktab[NI4BIPR];
 struct ipr_softc {
        struct ifnet    sc_if;          /* network-visible interface    */
        int             sc_state;       /* state of the interface       */
-
-#if !defined(__FreeBSD__) || defined(__DragonFly__)
-       int             sc_unit;        /* unit number for Net/OpenBSD  */
-#endif
-
+       int             sc_unit;        /* unit number                  */
        call_desc_t     *sc_cdp;        /* ptr to call descriptor       */
        int             sc_updown;      /* soft state of interface      */
        struct ifqueue  sc_fastq;       /* interactive traffic          */
@@ -221,33 +185,15 @@ enum ipr_states {
        ST_CONNECTED_A,                 /* connected to remote          */
 };
 
-#if (defined(__FreeBSD__) && !defined(__DragonFly__)) || (defined(__bsdi__))
-#define        THE_UNIT        sc->sc_if.if_unit
-#else
 #define        THE_UNIT        sc->sc_unit
-#endif
 
-#if defined(__DragonFly__) || defined __FreeBSD__ || defined __NetBSD__
 #  define IOCTL_CMD_T u_long
-#else
-#  define IOCTL_CMD_T int
-#endif
 
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 PDEVSTATIC void i4biprattach(void *);
 PSEUDO_SET(i4biprattach, i4b_ipr);
 static int i4biprioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data,
                       struct ucred *cr);
-#else
-PDEVSTATIC void i4biprattach (void);
-static int i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
-#endif
-
-#ifdef __bsdi__
-static int iprwatchdog(int unit);
-#else
 static void iprwatchdog(struct ifnet *ifp);
-#endif
 static void ipr_init_linktab(int unit);
 static void ipr_tx_queue_empty(int unit);
 static int i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rtp);
@@ -261,11 +207,7 @@ static void iprclearqueues(struct ipr_softc *sc);
  *     interface attach routine at kernel boot time
  *---------------------------------------------------------------------------*/
 PDEVSTATIC void
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 i4biprattach(void *dummy)
-#else
-i4biprattach()
-#endif
 {
        struct ipr_softc *sc = ipr_softc;
        int i;
@@ -284,19 +226,7 @@ i4biprattach()
 
                sc->sc_state = ST_IDLE;
                
-#ifdef __DragonFly__
                if_initname(&(sc->sc_if), "ipr", i);
-#elif defined(__FreeBSD__)
-               sc->sc_if.if_name = "ipr";
-               sc->sc_if.if_unit = i;
-#elif defined(__bsdi__)
-               sc->sc_if.if_name = "ipr";
-               sc->sc_if.if_unit = i;
-#else
-               sprintf(sc->sc_if.if_xname, "ipr%d", i);
-               sc->sc_if.if_softc = sc;
-               sc->sc_unit = i;
-#endif
 
 #ifdef IPR_VJ
                sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_SIMPLEX | IPR_AUTOCOMP;
@@ -314,9 +244,6 @@ i4biprattach()
                sc->sc_if.if_snd.ifq_maxlen = I4BIPRMAXQLEN;
                sc->sc_fastq.ifq_maxlen = I4BIPRMAXQLEN;
 
-#if defined (__FreeBSD__) && __FreeBSD__ > 4
-               mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ipr_fastq", MTX_DEF);
-#endif         
                sc->sc_if.if_ipackets = 0;
                sc->sc_if.if_ierrors = 0;
                sc->sc_if.if_opackets = 0;
@@ -345,11 +272,7 @@ i4biprattach()
 #endif
 
 #ifdef IPR_VJ
-#if defined(__DragonFly__) || defined(__FreeBSD__)
                sl_compress_init(&sc->sc_compr, -1);
-#else
-               sl_compress_init(&sc->sc_compr);
-#endif
 
 #ifdef IPR_VJ_USEBUFFER
                if(!((sc->sc_cbuf =
@@ -363,15 +286,8 @@ i4biprattach()
                sc->sc_dialresp = DSTAT_NONE;   /* no response */
                sc->sc_lastdialresp = DSTAT_NONE;
                
-               if_attach(&sc->sc_if);
-
-#if NBPFILTER > 0 || NBPF > 0
-#if defined(__DragonFly__) || defined(__FreeBSD__)
+               if_attach(&sc->sc_if, NULL);
                bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int));
-#else
-               bpfattach(&sc->sc_if.if_bpf, &sc->sc_if, DLT_NULL, sizeof(u_int));
-#endif
-#endif         
        }
 }
 
@@ -384,19 +300,12 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
 {
        struct ipr_softc *sc;
        int unit;
-       int s;
-       struct ifqueue *ifq;
        struct ip *ip;
        
-       s = SPLI4B();
+       crit_enter();
 
-#if (defined(__FreeBSD__) && !defined(__DragonFly__)) || (defined(__bsdi__))
-       unit = ifp->if_unit;
-       sc = &ipr_softc[unit];
-#else
        sc = ifp->if_softc;
        unit = sc->sc_unit;
-#endif
 
        /* check for IP */
        
@@ -404,7 +313,7 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
        {
                printf(IPR_FMT "af%d not supported\n", IPR_ARG(sc), dst->sa_family);
                m_freem(m);
-               splx(s);
+               crit_exit();
                sc->sc_if.if_noproto++;
                sc->sc_if.if_oerrors++;
                return(EAFNOSUPPORT);
@@ -416,7 +325,7 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
        {
                NDBGL4(L4_IPRDBG, "ipr%d: interface is DOWN!", unit);
                m_freem(m);
-               splx(s);
+               crit_exit();
                sc->sc_if.if_oerrors++;
                return(ENETDOWN);
        }
@@ -434,7 +343,7 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                                m_freem(m);
                                iprclearqueues(sc);
                                sc->sc_dialresp = DSTAT_NONE;
-                               splx(s);
+                               crit_exit();
                                sc->sc_if.if_oerrors++;
                                return(ENETUNREACH);
                                break;
@@ -444,7 +353,7 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                                m_freem(m);
                                iprclearqueues(sc);
                                sc->sc_dialresp = DSTAT_NONE;
-                               splx(s);
+                               crit_exit();
                                sc->sc_if.if_oerrors++;
                                return(EHOSTUNREACH);                           
                                break;
@@ -454,7 +363,7 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                                m_freem(m);
                                iprclearqueues(sc);
                                sc->sc_dialresp = DSTAT_NONE;
-                               splx(s);
+                               crit_exit();
                                sc->sc_if.if_oerrors++;
                                return(EHOSTUNREACH);                           
                                break;
@@ -487,28 +396,21 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
 
        ip = mtod(m, struct ip *);              /* get ptr to ip header */
         
-       if(ip->ip_tos & IPTOS_LOWDELAY)
-               ifq = &sc->sc_fastq;
-       else
-               ifq = &sc->sc_if.if_snd;
-
        /* check for space in choosen send queue */
        
-#if defined(__DragonFly__) || defined (__FreeBSD__)
        if (netisr_queue(NETISR_IP, m))
        {
                NDBGL4(L4_IPRDBG, "ipr%d: send queue full!", unit);
-               splx(s);
+               crit_exit();
                sc->sc_if.if_oerrors++;
                return(ENOBUFS);
        }
-#endif
        
        NDBGL4(L4_IPRDBG, "ipr%d: add packet to send queue!", unit);
        
        ipr_tx_queue_empty(unit);
 
-       splx(s);
+       crit_exit();
 
        return (0);
 }
@@ -516,26 +418,16 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
 /*---------------------------------------------------------------------------*
  *     process ioctl
  *---------------------------------------------------------------------------*/
-#if defined(__DragonFly__) || defined(__FreeBSD__)
 static int
 i4biprioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data, struct ucred *cr)
-#else
-static int
-i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-#endif
 {
-#if (defined(__FreeBSD__) && !defined(__DragonFly__)) || (defined(__bsdi__))
-       struct ipr_softc *sc = &ipr_softc[ifp->if_unit];
-#else
        struct ipr_softc *sc = ifp->if_softc;
-#endif
 
        struct ifreq *ifr = (struct ifreq *)data;
        struct ifaddr *ifa = (struct ifaddr *)data;
-       int s;
        int error = 0;
 
-       s = SPLI4B();
+       crit_enter();
        
        switch (cmd)
        {
@@ -555,11 +447,7 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                                if(sc->sc_if.if_flags & IFF_RUNNING)
                                {
                                        /* disconnect ISDN line */
-#if (defined(__FreeBSD__) && !defined(__DragonFly__)) || (defined(__bsdi__))
-                                       i4b_l4_drvrdisc(BDRV_IPR, ifp->if_unit);
-#else
                                        i4b_l4_drvrdisc(BDRV_IPR, sc->sc_unit);
-#endif
                                        sc->sc_if.if_flags &= ~IFF_RUNNING;
                                }
 
@@ -578,7 +466,6 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                        microtime(&sc->sc_if.if_lastchange);
                        break;
 
-#if !defined(__OpenBSD__)                      
                case SIOCSIFMTU:        /* set interface MTU */
                        if(ifr->ifr_mtu > I4BIPRMAXMTU)
                                error = EINVAL;
@@ -590,7 +477,6 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                                microtime(&sc->sc_if.if_lastchange);
                        }
                        break;
-#endif /* __OPENBSD__ */
 
 #if 0
        /* not needed for FreeBSD, done in sl_compress_init() (-hm) */
@@ -615,7 +501,7 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                        break;
        }
 
-       splx(s);
+       crit_exit();
 
        return(error);
 }
@@ -626,21 +512,13 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 static void
 iprclearqueues(struct ipr_softc *sc)
 {
-       int x;
-
-#if defined (__FreeBSD__) && __FreeBSD__ > 4
-       x = splimp();
-       IF_DRAIN(&sc->sc_fastq);
-       IF_DRAIN(&sc->sc_if.if_snd);
-       splx(x);
-#else
         struct mbuf *m;
 
        for(;;)
        {
-               x = splimp();
+               crit_enter();
                IF_DEQUEUE(&sc->sc_fastq, m);
-               splx(x);
+               crit_exit();
                if(m)
                        m_freem(m);
                else
@@ -649,40 +527,25 @@ iprclearqueues(struct ipr_softc *sc)
 
        for(;;)
         {
-               x = splimp();
+               crit_enter();
                IF_DEQUEUE(&sc->sc_if.if_snd, m);
-               splx(x);
+               crit_exit();
                if(m)
                        m_freem(m);
                else
                        break;
        }
-#endif
 }
         
 #if I4BIPRACCT
 /*---------------------------------------------------------------------------*
  *     watchdog routine
  *---------------------------------------------------------------------------*/
-#ifdef __bsdi__
-static int
-iprwatchdog(int unit)
-{
-#else
 static void
 iprwatchdog(struct ifnet *ifp)
 {
-#endif
-#if defined(__FreeBSD__) && !defined(__DragonFly__)
-       int unit = ifp->if_unit;
-       struct ipr_softc *sc = &ipr_softc[unit];
-#elif defined(__bsdi__)
-       struct ipr_softc *sc = &ipr_softc[unit];
-       struct ifnet *ifp = &ipr_softc[unit].sc_if;
-#else
        struct ipr_softc *sc = ifp->if_softc;
        int unit = sc->sc_unit;
-#endif
        bchan_statistics_t bs;
        
        /* get # of bytes in and out from the HSCX driver */ 
@@ -710,9 +573,6 @@ iprwatchdog(struct ifnet *ifp)
                         sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb);
        }
        sc->sc_if.if_timer = I4BIPRACCTINTVL;   
-#ifdef __bsdi__
-       return 0;
-#endif
 }
 #endif /* I4BIPRACCT */
 
@@ -726,7 +586,7 @@ iprwatchdog(struct ifnet *ifp)
 static void
 i4bipr_connect_startio(struct ipr_softc *sc)
 {
-       int s = SPLI4B();
+       crit_enter();
        
        if(sc->sc_state == ST_CONNECTED_W)
        {
@@ -734,7 +594,7 @@ i4bipr_connect_startio(struct ipr_softc *sc)
                ipr_tx_queue_empty(THE_UNIT);
        }
 
-       splx(s);
+       crit_exit();
 }
  
 /*---------------------------------------------------------------------------*
@@ -744,11 +604,10 @@ static void
 ipr_connect(int unit, void *cdp)
 {
        struct ipr_softc *sc = &ipr_softc[unit];
-       int s;
 
        sc->sc_cdp = (call_desc_t *)cdp;
 
-       s = SPLI4B();
+       crit_enter();
 
        NDBGL4(L4_DIALST, "ipr%d: setting dial state to ST_CONNECTED", unit);
 
@@ -803,7 +662,7 @@ ipr_connect(int unit, void *cdp)
                ipr_tx_queue_empty(unit);
        }
 
-       splx(s);
+       crit_exit();
 
        /* we don't need any negotiation - pass event back right now */
        i4b_l4_negcomplete(sc->sc_cdp);
@@ -882,8 +741,8 @@ ipr_updown(int unit, int updown)
 /*---------------------------------------------------------------------------*
  *     this routine is called from the HSCX interrupt handler
  *     when a new frame (mbuf) has been received and was put on
- *     the rx queue. It is assumed that this routines runs at
- *     pri level splimp() ! Keep it short !
+ *     the rx queue. It is assumed that this routines runs in
+ *     a critical section ! Keep it short !
  *---------------------------------------------------------------------------*/
 static void
 ipr_rx_data_rdy(int unit)
@@ -896,6 +755,7 @@ ipr_rx_data_rdy(int unit)
 #endif 
        int len, c;
 #endif
+       static const uint32_t af = AF_INET;
        
        if((m = *isdn_linktab[unit]->rx_mbuf) == NULL)
                return;
@@ -1038,31 +898,14 @@ error:
        }
 #endif
 
-#if NBPFILTER > 0 || NBPF > 0
-       if(sc->sc_if.if_bpf)
-       {
-               /* prepend the address family as a four byte field */           
-               struct mbuf mm;
-               u_int af = AF_INET;
-               mm.m_next = m;
-               mm.m_len = 4;
-               mm.m_data = (char *)&af;
-
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-               bpf_mtap(&sc->sc_if, &mm);
-#else
-               bpf_mtap(sc->sc_if.if_bpf, &mm);
-#endif
-       }
-#endif /* NBPFILTER > 0  || NBPF > 0 */
+       if (sc->sc_if.if_bpf)
+               bpf_ptap(sc->sc_if.if_bpf, m, &af, sizeof(af));
 
-#if defined(__DragonFly__) || defined (__FreeBSD__)
        if (netisr_queue(NETISR_IP, m)) {
                NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit);
                sc->sc_if.if_ierrors++;
                sc->sc_if.if_iqdrops++;         
        }
-#endif
 }
 
 /*---------------------------------------------------------------------------*
@@ -1073,6 +916,7 @@ error:
 static void
 ipr_tx_queue_empty(int unit)
 {
+       static const uint32_t af = AF_INET;
        struct ipr_softc *sc = &ipr_softc[unit];
        struct mbuf *m;
 #ifdef IPR_VJ  
@@ -1098,25 +942,9 @@ ipr_tx_queue_empty(int unit)
                }
 
                microtime(&sc->sc_if.if_lastchange);
-               
-#if NBPFILTER > 0 || NBPF > 0
-               if(sc->sc_if.if_bpf)
-               {
-                       /* prepend the address family as a four byte field */
-       
-                       struct mbuf mm;
-                       u_int af = AF_INET;
-                       mm.m_next = m;
-                       mm.m_len = 4;
-                       mm.m_data = (char *)&af;
-       
-#if defined(__DragonFly__) || defined(__FreeBSD__)
-                       bpf_mtap(&sc->sc_if, &mm);
-#else
-                       bpf_mtap(sc->sc_if.if_bpf, &mm);
-#endif
-               }
-#endif /* NBPFILTER */
+
+               if (sc->sc_if.if_bpf)
+                       bpf_ptap(sc->sc_if.if_bpf, m, &af, sizeof(af));
        
 #if I4BIPRACCT
                sc->sc_outb += m->m_pkthdr.len; /* size before compression */
@@ -1134,8 +962,7 @@ ipr_tx_queue_empty(int unit)
 #endif
                x = 1;
 
-               IF_LOCK(isdn_linktab[unit]->tx_queue);
-               if(_IF_QFULL(isdn_linktab[unit]->tx_queue))
+               if(IF_QFULL(isdn_linktab[unit]->tx_queue))
                {
                        NDBGL4(L4_IPRDBG, "ipr%d: tx queue full!", unit);
                        m_freem(m);
@@ -1146,10 +973,9 @@ ipr_tx_queue_empty(int unit)
 
                        sc->sc_if.if_opackets++;
 
-                       _IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
+                       IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
 
                }
-               IF_UNLOCK(isdn_linktab[unit]->tx_queue);
        }
 
        if(x)