Make all network interrupt service routines MPSAFE part 1/3.
[dragonfly.git] / sys / dev / netif / ex / if_ex.c
index c342302..3514d74 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ex/if_ex.c,v 1.26.2.3 2001/03/05 05:33:20 imp Exp $
- * $DragonFly: src/sys/dev/netif/ex/if_ex.c,v 1.8 2004/03/14 15:36:49 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/ex/if_ex.c,v 1.21 2005/11/28 17:13:42 dillon Exp $
  *
  * MAINTAINER: Matthew N. Dodd <winter@jurai.net>
  *                             <mdodd@FreeBSD.org>
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
+#include <sys/thread2.h>
 
 #include <sys/module.h>
 #include <sys/bus.h>
+#include <sys/serialize.h>
 
 #include <machine/bus.h>
 #include <machine/resource.h>
 #include <sys/rman.h>
 
+#include <net/if.h>
+#include <net/ifq_var.h>
 #include <net/if.h>
 #include <net/if_arp.h>
 #include <net/if_media.h> 
@@ -97,7 +101,7 @@ u_char plus_ee2irqmap[] =
 /* Network Interface Functions */
 static void    ex_init         (void *);
 static void    ex_start        (struct ifnet *);
-static int     ex_ioctl        (struct ifnet *, u_long, caddr_t);
+static int     ex_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
 static void    ex_watchdog     (struct ifnet *);
 
 /* ifmedia Functions   */
@@ -166,16 +170,16 @@ ex_alloc_resources (device_t dev)
        struct ex_softc *       sc = device_get_softc(dev);
        int                     error = 0;
 
-       sc->ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->ioport_rid,
-                                       0, ~0, 1, RF_ACTIVE);
+       sc->ioport = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->ioport_rid,
+           RF_ACTIVE);
        if (!sc->ioport) {
                device_printf(dev, "No I/O space?!\n");
                error = ENOMEM;
                goto bad;
        }
 
-       sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
-                                       0, ~0, 1, RF_ACTIVE);
+       sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
+           RF_ACTIVE);
 
        if (!sc->irq) {
                device_printf(dev, "No IRQ?!\n");
@@ -239,12 +243,12 @@ ex_attach(device_t dev)
        if_initname(ifp, "ex", unit);
        ifp->if_mtu = ETHERMTU;
        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */;
-       ifp->if_output = ether_output;
        ifp->if_start = ex_start;
        ifp->if_ioctl = ex_ioctl;
        ifp->if_watchdog = ex_watchdog;
        ifp->if_init = ex_init;
-       ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
+       ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
+       ifq_set_ready(&ifp->if_snd);
 
        ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts);
 
@@ -265,10 +269,7 @@ ex_attach(device_t dev)
        /*
         * Attach the interface.
         */
-       ether_ifattach(ifp, sc->arpcom.ac_enaddr);
-
-       device_printf(sc->dev, "Ethernet address %6D\n",
-                       sc->arpcom.ac_enaddr, ":");
+       ether_ifattach(ifp, sc->arpcom.ac_enaddr, NULL);
 
        return(0);
 }
@@ -278,17 +279,12 @@ ex_init(void *xsc)
 {
        struct ex_softc *       sc = (struct ex_softc *) xsc;
        struct ifnet *          ifp = &sc->arpcom.ac_if;
-       int                     s;
        int                     i;
-       register int            iobase = sc->iobase;
+       int                     iobase = sc->iobase;
        unsigned short          temp_reg;
 
        DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_dunit););
 
-       if (TAILQ_FIRST(&ifp->if_addrhead) == NULL) {
-               return;
-       }
-       s = splimp();
        ifp->if_timer = 0;
 
        /*
@@ -360,7 +356,6 @@ ex_init(void *xsc)
        outb(iobase + CMD_REG, Rcv_Enable_CMD);
 
        ex_start(ifp);
-       splx(s);
 
        DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_dunit););
 }
@@ -371,21 +366,21 @@ ex_start(struct ifnet *ifp)
 {
        struct ex_softc *       sc = ifp->if_softc;
        int                     iobase = sc->iobase;
-       int                     i, s, len, data_len, avail, dest, next;
+       int                     i, len, data_len, avail, dest, next;
        unsigned char           tmp16[2];
        struct mbuf *           opkt;
        struct mbuf *           m;
 
        DODEBUG(Start_End, printf("ex_start%d: start\n", unit););
 
-       s = splimp();
-
        /*
         * Main loop: send outgoing packets to network card until there are no
         * more packets left, or the card cannot accept any more yet.
         */
-       while (((opkt = ifp->if_snd.ifq_head) != NULL) &&
-              !(ifp->if_flags & IFF_OACTIVE)) {
+       while ((ifp->if_flags & IFF_OACTIVE) == 0) {
+               opkt = ifq_poll(&ifp->if_snd);
+               if (opkt == NULL)
+                       break;
 
                /*
                 * Ensure there is enough free transmit buffer space for
@@ -418,7 +413,7 @@ ex_start(struct ifnet *ifp)
                DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail););
 
                if (avail >= len + XMT_HEADER_LEN) {
-                       IF_DEQUEUE(&ifp->if_snd, opkt);
+                       ifq_dequeue(&ifp->if_snd, opkt);
 
 #ifdef EX_PSA_INTR      
                        /*
@@ -526,9 +521,7 @@ ex_start(struct ifnet *ifp)
                        sc->tx_last = dest;
                        sc->tx_tail = next;
         
-                       if (ifp->if_bpf != NULL) {
-                               bpf_mtap(ifp, opkt);
-                       }
+                       BPF_MTAP(ifp, opkt);
 
                        ifp->if_timer = 2;
                        ifp->if_opackets++;
@@ -538,9 +531,6 @@ ex_start(struct ifnet *ifp)
                        DODEBUG(Status, printf("OACTIVE start\n"););
                }
        }
-
-       splx(s);
-
        DODEBUG(Start_End, printf("ex_start%d: finish\n", unit););
 }
 
@@ -608,9 +598,8 @@ ex_intr(void *arg)
         * be sent, attempt to send more packets to the network card.
         */
 
-       if (send_pkts && (ifp->if_snd.ifq_head != NULL)) {
+       if (send_pkts && !ifq_is_empty(&ifp->if_snd))
                ex_start(ifp);
-       }
 
 #ifdef EXDEBUG
        exintr_count--;
@@ -679,7 +668,6 @@ ex_rx_intr(struct ex_softc *sc)
        int                     QQQ;
        struct mbuf *           m;
        struct mbuf *           ipkt;
-       struct ether_header *   eh;
 
        DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit););
 
@@ -700,7 +688,7 @@ ex_rx_intr(struct ex_softc *sc)
                QQQ = pkt_len = inw(iobase + IO_PORT_REG);
 
                if (rx_status & RCV_OK_bit) {
-                       MGETHDR(m, M_DONTWAIT, MT_DATA);
+                       MGETHDR(m, MB_DONTWAIT, MT_DATA);
                        ipkt = m;
                        if (ipkt == NULL) {
                                ifp->if_iqdrops++;
@@ -711,7 +699,7 @@ ex_rx_intr(struct ex_softc *sc)
 
                                while (pkt_len > 0) {
                                        if (pkt_len > MINCLSIZE) {
-                                               MCLGET(m, M_DONTWAIT);
+                                               MCLGET(m, MB_DONTWAIT);
                                                if (m->m_flags & M_EXT) {
                                                        m->m_len = MCLBYTES;
                                                } else {
@@ -736,7 +724,7 @@ ex_rx_intr(struct ex_softc *sc)
                                        pkt_len -= m->m_len;
 
                                        if (pkt_len > 0) {
-                                               MGET(m->m_next, M_DONTWAIT, MT_DATA);
+                                               MGET(m->m_next, MB_DONTWAIT, MT_DATA);
                                                if (m->m_next == NULL) {
                                                        m_freem(ipkt);
                                                        ifp->if_iqdrops++;
@@ -746,17 +734,7 @@ ex_rx_intr(struct ex_softc *sc)
                                                m->m_len = MLEN;
                                        }
                                }
-                               eh = mtod(ipkt, struct ether_header *);
-#ifdef EXDEBUG
-       if (debug_mask & Rcvd_Pkts) {
-               if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) {
-                       printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":");
-                       printf("%6D\n", eh->ether_dhost, ":");
-               } /* QQQ */
-       }
-#endif
-                               m_adj(ipkt, sizeof(struct ether_header));
-                               ether_input(ifp, eh, ipkt);
+                               ifp->if_input(ifp, ipkt);
                                ifp->if_ipackets++;
                        }
                } else {
@@ -778,24 +756,15 @@ rx_another: ;
 
 
 static int
-ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
+ex_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
 {
        struct ex_softc *       sc = ifp->if_softc;
        struct ifreq *          ifr = (struct ifreq *)data;
-       int                     s;
        int                     error = 0;
 
        DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_dunit););
 
-       s = splimp();
-
        switch(cmd) {
-               case SIOCSIFADDR:
-               case SIOCGIFADDR:
-               case SIOCSIFMTU:
-                       error = ether_ioctl(ifp, cmd, data);
-                       break;
-
                case SIOCSIFFLAGS:
                        DODEBUG(Start_End, printf("SIOCSIFFLAGS"););
                        if ((ifp->if_flags & IFF_UP) == 0 &&
@@ -827,11 +796,10 @@ ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
                        break;
                default:
                        DODEBUG(Start_End, printf("unknown"););
-                       error = EINVAL;
+                       error = ether_ioctl(ifp, cmd, data);
+                       break;
        }
 
-       splx(s);
-
        DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_dunit););
 
        return(error);
@@ -841,20 +809,12 @@ ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data)
 static void
 ex_reset(struct ex_softc *sc)
 {
-       int s;
-
        DODEBUG(Start_End, printf("ex_reset%d: start\n", unit););
-  
-       s = splimp();
 
        ex_stop(sc);
        ex_init(sc);
 
-       splx(s);
-
        DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit););
-
-       return;
 }
 
 static void