Rewrite the polling code. Instead of trying to do fancy polling enablement
authorMatthew Dillon <dillon@dragonflybsd.org>
Wed, 25 May 2005 01:44:33 +0000 (01:44 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Wed, 25 May 2005 01:44:33 +0000 (01:44 +0000)
from inside the IF interrupt itself, which creates a headache in the code,
simply allow IFF_POLLING to be set and cleared via ifconfig.  This greatly
simplifies both the networking code and the polling code and allows polling
to be enabled and disabled at will on a per-network-interface basis.

* Drivers no longer have to have polling checks in the interrupt path.
* An if_poll function vector has been added.  Polling is supported if the
  driver initializes the vector.
* Registration command added to the poll function command list.
* Driver code for registration and deregistration is now greatly simplified.

The kernel polling code no longer randomly turns off the polling bit if an
interface goes down or is reset.

Remove IFCAP_POLLING, it serves no purpose.

Fix a couple of bugs in the serializer code.  Add a warning in
nexus_setup_intr if a driver tries to specify a serializer and an SPL.
A driver can specify one or the other, not both.

Convert the EM driver to use the new serializer API instead of SPLs.

Add ifconfig poll and ifconfig -poll support to ifconfig, and fix bugs
in the rtsock code that only returned the low 16 bits of the interface
flags so ifconfig properly reports when polling mode is turned on for an
interface.

NOTE to people using polling.  You must first enable polling via
kern.polling.enable, and then may specify the 'poll' directive in ifconfig
to enable it on a per interface basis.  If IFF_POLLING refuses to be set,
the device does not support polling.

22 files changed:
sbin/ifconfig/ifconfig.c
sys/cpu/i386/include/atomic.h
sys/dev/netif/dc/if_dc.c
sys/dev/netif/em/if_em.c
sys/dev/netif/em/if_em.h
sys/dev/netif/fwe/if_fwe.c
sys/dev/netif/fxp/if_fxp.c
sys/dev/netif/nge/if_nge.c
sys/dev/netif/re/if_re.c
sys/dev/netif/rl/if_rl.c
sys/dev/netif/sis/if_sis.c
sys/dev/netif/vr/if_vr.c
sys/dev/netif/wi/if_wi.c
sys/i386/i386/nexus.c
sys/i386/include/atomic.h
sys/kern/kern_poll.c
sys/kern/lwkt_serialize.c
sys/net/altq/altq_rmclass.c
sys/net/if.c
sys/net/if_var.h
sys/net/rtsock.c
sys/platform/pc32/i386/nexus.c

index 88f1bed..497e1d0 100644 (file)
@@ -29,7 +29,7 @@
  * @(#) Copyright (c) 1983, 1993 The Regents of the University of California.  All rights reserved.
  * @(#)ifconfig.c      8.2 (Berkeley) 2/16/94
  * $FreeBSD: src/sbin/ifconfig/ifconfig.c,v 1.96 2004/02/27 06:43:14 kan Exp $
- * $DragonFly: src/sbin/ifconfig/ifconfig.c,v 1.21 2005/04/25 17:33:26 swildner Exp $
+ * $DragonFly: src/sbin/ifconfig/ifconfig.c,v 1.22 2005/05/25 01:44:18 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -193,6 +193,8 @@ struct      cmd {
 } cmds[] = {
        { "up",         IFF_UP,         setifflags,     NULL },
        { "down",       -IFF_UP,        setifflags,     NULL },
+       { "poll",       IFF_POLLING,    setifflags,     NULL },
+       { "-poll",      -IFF_POLLING,   setifflags,     NULL },
        { "arp",        -IFF_NOARP,     setifflags,     NULL },
        { "-arp",       IFF_NOARP,      setifflags,     NULL },
        { "debug",      IFF_DEBUG,      setifflags,     NULL },
@@ -1149,6 +1151,7 @@ status(const struct afswtch *afp, int addrcount, struct sockaddr_dl *sdl,
        if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
                err(1, "socket");
 
+       printf("flags %08x\n", flags);
        printf("%s: ", name);
        printb("flags", flags, IFFBITS);
        if (ifm->ifm_data.ifi_metric)
index 32c046d..7650c99 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.10 2005/05/24 20:58:38 dillon Exp $
+ * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.11 2005/05/25 01:44:12 dillon Exp $
  */
 #ifndef _MACHINE_ATOMIC_H_
 #define _MACHINE_ATOMIC_H_
@@ -243,7 +243,7 @@ static __inline
 void
 atomic_intr_handler_enable(atomic_intr_t *p)
 {
-       __asm __volatile(MPLOCKED "andl $0xB0000000,%0" : "+m" (*p));
+       __asm __volatile(MPLOCKED "andl $0xBFFFFFFF,%0" : "+m" (*p));
 }
 
 static __inline
index 343d7c5..9286918 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_dc.c,v 1.9.2.45 2003/06/08 14:31:53 mux Exp $
- * $DragonFly: src/sys/dev/netif/dc/if_dc.c,v 1.26 2005/05/24 20:59:01 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/dc/if_dc.c,v 1.27 2005/05/25 01:44:20 dillon Exp $
  */
 
 /*
@@ -206,6 +206,10 @@ static void dc_intr                (void *);
 static void dc_start           (struct ifnet *);
 static int dc_ioctl            (struct ifnet *, u_long, caddr_t,
                                        struct ucred *);
+#ifdef DEVICE_POLLING
+static void dc_poll            (struct ifnet *ifp, enum poll_cmd cmd, 
+                                       int count);
+#endif
 static void dc_init            (void *);
 static void dc_stop            (struct dc_softc *);
 static void dc_watchdog                (struct ifnet *);
@@ -2054,6 +2058,9 @@ static int dc_attach(dev)
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = dc_ioctl;
        ifp->if_start = dc_start;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = dc_poll;
+#endif
        ifp->if_watchdog = dc_watchdog;
        ifp->if_init = dc_init;
        ifp->if_baudrate = 10000000;
@@ -2780,33 +2787,41 @@ static void dc_tx_underrun(sc)
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t dc_poll;
 
 static void
 dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct  dc_softc *sc = ifp->if_softc;
+       u_int32_t status;
 
-       if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* Disable interrupts */
+               CSR_WRITE_4(sc, DC_IMR, 0x00000000);
+               break;
+       case POLL_DEREGISTER:
                /* Re-enable interrupts. */
                CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
-               return;
-       }
-       sc->rxcycles = count;
-       dc_rxeof(sc);
-       dc_txeof(sc);
-       if ((ifp->if_flags & IFF_OACTIVE) == 0 && !ifq_is_empty(&ifp->if_snd))
-               dc_start(ifp);
-
-       if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
-               u_int32_t          status;
-
+               break;
+       case POLL_ONLY:
+               sc->rxcycles = count;
+               dc_rxeof(sc);
+               dc_txeof(sc);
+               if ((ifp->if_flags & IFF_OACTIVE) == 0 && !ifq_is_empty(&ifp->if_snd))
+                       dc_start(ifp);
+               break;
+       case POLL_AND_CHECK_STATUS:
+               sc->rxcycles = count;
+               dc_rxeof(sc);
+               dc_txeof(sc);
+               if ((ifp->if_flags & IFF_OACTIVE) == 0 && !ifq_is_empty(&ifp->if_snd))
+                       dc_start(ifp);
                status = CSR_READ_4(sc, DC_ISR);
                status &= (DC_ISR_RX_WATDOGTIMEO|DC_ISR_RX_NOBUF|
                        DC_ISR_TX_NOBUF|DC_ISR_TX_IDLE|DC_ISR_TX_UNDERRUN|
                        DC_ISR_BUS_ERR);
                if (!status)
-                       return ;
+                       break;
                /* ack what we have */
                CSR_WRITE_4(sc, DC_ISR, status);
 
@@ -2829,6 +2844,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
                        dc_reset(sc);
                        dc_init(sc);
                }
+               break;
        }
 }
 #endif /* DEVICE_POLLING */
@@ -2848,15 +2864,6 @@ static void dc_intr(arg)
 
        ifp = &sc->arpcom.ac_if;
 
-#ifdef DEVICE_POLLING
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-       if (ether_poll_register(dc_poll, ifp)) { /* ok, disable interrupts */
-               CSR_WRITE_4(sc, DC_IMR, 0x00000000);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        if ( (CSR_READ_4(sc, DC_ISR) & DC_INTRS) == 0)
                return ;
 
@@ -3400,9 +3407,6 @@ static void dc_stop(sc)
        callout_stop(&sc->dc_stat_timer);
 
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif
 
        DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON|DC_NETCFG_TX_ON));
        CSR_WRITE_4(sc, DC_IMR, 0x00000000);
index 5b873a2..d7726ee 100644 (file)
@@ -34,7 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
 ***************************************************************************/
 
 /*$FreeBSD: src/sys/dev/em/if_em.c,v 1.2.2.15 2003/06/09 22:10:15 pdeuskar Exp $*/
-/*$DragonFly: src/sys/dev/netif/em/if_em.c,v 1.31 2005/05/24 20:59:01 dillon Exp $*/
+/*$DragonFly: src/sys/dev/netif/em/if_em.c,v 1.32 2005/05/25 01:44:21 dillon Exp $*/
 
 #include "if_em.h"
 #include <net/ifq_var.h>
@@ -117,9 +117,11 @@ static int em_detach(device_t);
 static int     em_shutdown(device_t);
 static void    em_intr(void *);
 static void    em_start(struct ifnet *);
+static void    em_start_serialized(struct ifnet *);
 static int     em_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
 static void    em_watchdog(struct ifnet *);
 static void    em_init(void *);
+static void    em_init_serialized(void *);
 static void    em_stop(void *);
 static void    em_media_status(struct ifnet *, struct ifmediareq *);
 static int     em_media_change(struct ifnet *);
@@ -157,6 +159,7 @@ static int  em_82547_fifo_workaround(struct adapter *, int);
 static void    em_82547_update_fifo_head(struct adapter *, int);
 static int     em_82547_tx_fifo_reset(struct adapter *);
 static void    em_82547_move_tail(void *arg);
+static void    em_82547_move_tail_serialized(void *arg);
 static int     em_dma_malloc(struct adapter *, bus_size_t,
                              struct em_dma_alloc *, int);
 static void    em_dma_free(struct adapter *, struct em_dma_alloc *);
@@ -514,9 +517,9 @@ em_attach(device_t dev)
         else
                adapter->pcix_82544 = FALSE;
 
-       error = bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_NET,
+       error = bus_setup_intr(dev, adapter->res_interrupt, INTR_TYPE_MISC,
                           (void (*)(void *)) em_intr, adapter,
-                          &adapter->int_handler_tag, NULL);
+                          &adapter->int_handler_tag, &adapter->serializer);
        if (error) {
                device_printf(dev, "Error registering interrupt handler!\n");
                ether_ifdetach(&adapter->interface_data.ac_if);
@@ -545,11 +548,10 @@ static int
 em_detach(device_t dev)
 {
        struct adapter * adapter = device_get_softc(dev);
-       int s;
 
        INIT_DEBUGOUT("em_detach: begin");
-       s = splimp();
 
+       lwkt_serialize_enter(&adapter->serializer);
        adapter->in_detach = 1;
 
        if (device_is_attached(dev)) {
@@ -590,7 +592,7 @@ em_detach(device_t dev)
        adapter->sysctl_tree = NULL;
        sysctl_ctx_free(&adapter->sysctl_ctx);
 
-       splx(s);
+       lwkt_serialize_exit(&adapter->serializer);
        return(0);
 }
 
@@ -621,14 +623,21 @@ em_shutdown(device_t dev)
 static void
 em_start(struct ifnet *ifp)
 {
-       int s;
+       struct adapter *adapter = ifp->if_softc;
+
+       lwkt_serialize_enter(&adapter->serializer);
+       em_start_serialized(ifp);
+       lwkt_serialize_exit(&adapter->serializer);
+}
+
+static void
+em_start_serialized(struct ifnet *ifp)
+{
        struct mbuf *m_head;
        struct adapter *adapter = ifp->if_softc;
 
        if (!adapter->link_active)
                return;
-
-       s = splimp();
        while (!ifq_is_empty(&ifp->if_snd)) {
                m_head = ifq_poll(&ifp->if_snd);
 
@@ -647,7 +656,6 @@ em_start(struct ifnet *ifp)
                /* Set timeout in case hardware has problems transmitting */
                ifp->if_timer = EM_TX_TIMEOUT;        
        }
-       splx(s);
 }
 
 /*********************************************************************
@@ -662,11 +670,11 @@ em_start(struct ifnet *ifp)
 static int
 em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
 {
-       int s, mask, error = 0;
+       int mask, error = 0;
        struct ifreq *ifr = (struct ifreq *) data;
        struct adapter *adapter = ifp->if_softc;
 
-       s = splimp();
+       lwkt_serialize_enter(&adapter->serializer);
 
        if (adapter->in_detach)
                goto out;
@@ -675,7 +683,9 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
        case SIOCSIFADDR:
        case SIOCGIFADDR:
                IOCTL_DEBUGOUT("ioctl rcv'd: SIOCxIFADDR (Get/Set Interface Addr)");
+               lwkt_serialize_exit(&adapter->serializer);
                ether_ioctl(ifp, command, data);
+               lwkt_serialize_enter(&adapter->serializer);
                break;
        case SIOCSIFMTU:
                IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
@@ -685,14 +695,14 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                        ifp->if_mtu = ifr->ifr_mtu;
                        adapter->hw.max_frame_size = 
                        ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
-                       em_init(adapter);
+                       em_init_serialized(adapter);
                }
                break;
        case SIOCSIFFLAGS:
                IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFFLAGS (Set Interface Flags)");
                if (ifp->if_flags & IFF_UP) {
                        if (!(ifp->if_flags & IFF_RUNNING))
-                               em_init(adapter);
+                               em_init_serialized(adapter);
                        em_disable_promisc(adapter);
                        em_set_promisc(adapter);
                } else {
@@ -708,10 +718,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                        em_set_multi(adapter);
                        if (adapter->hw.mac_type == em_82542_rev2_0)
                                em_initialize_receive_unit(adapter);
-#ifdef DEVICE_POLLING
-                       if (!(ifp->if_flags & IFF_POLLING))
-#endif
-                               em_enable_intr(adapter);
+                       em_enable_intr(adapter);
                }
                break;
        case SIOCSIFMEDIA:
@@ -728,7 +735,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                        else
                                ifp->if_capenable |= IFCAP_HWCSUM;
                        if (ifp->if_flags & IFF_RUNNING)
-                               em_init(adapter);
+                               em_init_serialized(adapter);
                }
                break;
        default:
@@ -737,7 +744,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
        }
 
 out:
-       splx(s);
+       lwkt_serialize_exit(&adapter->serializer);
        return(error);
 }
 
@@ -786,14 +793,21 @@ em_watchdog(struct ifnet *ifp)
 static void
 em_init(void *arg)
 {
-       int s;
+       struct adapter *adapter = arg;
+
+       lwkt_serialize_enter(&adapter->serializer);
+       em_init_serialized(arg);
+       lwkt_serialize_exit(&adapter->serializer);
+}
+
+static void
+em_init_serialized(void *arg)
+{
        struct adapter *adapter = arg;
        struct ifnet *ifp = &adapter->interface_data.ac_if;
 
        INIT_DEBUGOUT("em_init: begin");
 
-       s = splimp();
-
        em_stop(adapter);
 
        /* Get the latest mac address, User can use a LAA */
@@ -803,7 +817,6 @@ em_init(void *arg)
        /* Initialize the hardware */
        if (em_hardware_init(adapter)) {
                if_printf(ifp, "Unable to initialize the hardware\n");
-               splx(s);
                return;
        }
 
@@ -813,7 +826,6 @@ em_init(void *arg)
        if (em_setup_transmit_structures(adapter)) {
                if_printf(ifp, "Could not setup transmit structures\n");
                em_stop(adapter); 
-               splx(s);
                return;
        }
        em_initialize_transmit_unit(adapter);
@@ -825,7 +837,6 @@ em_init(void *arg)
        if (em_setup_receive_structures(adapter)) {
                if_printf(ifp, "Could not setup receive structures\n");
                em_stop(adapter);
-               splx(s);
                return;
        }
        em_initialize_receive_unit(adapter);
@@ -845,25 +856,13 @@ em_init(void *arg)
 
        callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter);
        em_clear_hw_cntrs(&adapter->hw);
-#ifdef DEVICE_POLLING
-       /*
-        * Only enable interrupts if we are not polling, make sure
-        * they are off otherwise.
-        */
-       if (ifp->if_flags & IFF_POLLING)
-               em_disable_intr(adapter);
-       else
-#endif /* DEVICE_POLLING */
-               em_enable_intr(adapter);
+       em_enable_intr(adapter);
 
        /* Don't reset the phy next time init gets called */
        adapter->hw.phy_reset_disable = TRUE;
-
-       splx(s);
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t em_poll;
 
 static void
 em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
@@ -871,11 +870,15 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
        struct adapter *adapter = ifp->if_softc;
        uint32_t reg_icr;
 
-       if (cmd == POLL_DEREGISTER) {       /* final call, enable interrupts */
+       lwkt_serialize_enter(&adapter->serializer);
+       switch(cmd) {
+       case POLL_REGISTER:
+               em_disable_intr(adapter);
+               break;
+       case POLL_DEREGISTER:
                em_enable_intr(adapter);
-               return;
-       }
-       if (cmd == POLL_AND_CHECK_STATUS) {
+               break;
+       case POLL_AND_CHECK_STATUS:
                reg_icr = E1000_READ_REG(&adapter->hw, ICR);
                if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
                        callout_stop(&adapter->timer);
@@ -885,15 +888,21 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
                        callout_reset(&adapter->timer, 2*hz, em_local_timer,
                                      adapter);
                }
+               /* fall through */
+       case POLL_ONLY:
+               if (ifp->if_flags & IFF_RUNNING) {
+                       em_process_receive_interrupts(adapter, count);
+                       em_clean_transmit_interrupts(adapter);
+               }
+               if (ifp->if_flags & IFF_RUNNING) {
+                       if (!ifq_is_empty(&ifp->if_snd))
+                               em_start_serialized(ifp);
+               }
+               break;
        }
-       if (ifp->if_flags & IFF_RUNNING) {
-               em_process_receive_interrupts(adapter, count);
-               em_clean_transmit_interrupts(adapter);
-       }
-
-       if ((ifp->if_flags & IFF_RUNNING) && !ifq_is_empty(&ifp->if_snd))
-               em_start(ifp);
+       lwkt_serialize_exit(&adapter->serializer);
 }
+
 #endif /* DEVICE_POLLING */
 
 /*********************************************************************
@@ -910,17 +919,6 @@ em_intr(void *arg)
 
        ifp = &adapter->interface_data.ac_if;  
 
-#ifdef DEVICE_POLLING
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-
-       if (ether_poll_register(em_poll, ifp)) {
-               em_disable_intr(adapter);
-               em_poll(ifp, 0, 1);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        reg_icr = E1000_READ_REG(&adapter->hw, ICR);
        if (!reg_icr)
                return;
@@ -945,7 +943,7 @@ em_intr(void *arg)
        }
 
        if ((ifp->if_flags & IFF_RUNNING) && !ifq_is_empty(&ifp->if_snd))
-               em_start(ifp);
+               em_start_serialized(ifp);
 }
 
 /*********************************************************************
@@ -1027,6 +1025,8 @@ em_media_change(struct ifnet *ifp)
        if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
                return(EINVAL);
 
+       lwkt_serialize_enter(&adapter->serializer);
+
        switch (IFM_SUBTYPE(ifm->ifm_media)) {
        case IFM_AUTO:
                adapter->hw.autoneg = DO_AUTO_NEG;
@@ -1062,8 +1062,9 @@ em_media_change(struct ifnet *ifp)
         */
        adapter->hw.phy_reset_disable = FALSE;
 
-       em_init(adapter);
+       em_init_serialized(adapter);
 
+       lwkt_serialize_exit(&adapter->serializer);
        return(0);
 }
 
@@ -1263,7 +1264,16 @@ em_encap(struct adapter *adapter, struct mbuf *m_head)
 static void
 em_82547_move_tail(void *arg)
 {
-       int s;
+       struct adapter *adapter = arg;
+
+       lwkt_serialize_enter(&adapter->serializer);
+       em_82547_move_tail_serialized(arg);
+       lwkt_serialize_exit(&adapter->serializer);
+}
+
+static void
+em_82547_move_tail_serialized(void *arg)
+{
        struct adapter *adapter = arg;
        uint16_t hw_tdt;
        uint16_t sw_tdt;
@@ -1271,7 +1281,6 @@ em_82547_move_tail(void *arg)
        uint16_t length = 0;
        boolean_t eop = 0;
 
-       s = splimp();
        hw_tdt = E1000_READ_REG(&adapter->hw, TDT);
        sw_tdt = adapter->next_avail_tx_desc;
 
@@ -1294,7 +1303,6 @@ em_82547_move_tail(void *arg)
                        length = 0;
                }
        }       
-       splx(s);
 }
 
 static int
@@ -1462,12 +1470,11 @@ em_set_multi(struct adapter *adapter)
 static void
 em_local_timer(void *arg)
 {
-       int s;
        struct ifnet *ifp;
        struct adapter *adapter = arg;
        ifp = &adapter->interface_data.ac_if;
 
-       s = splimp();
+       lwkt_serialize_enter(&adapter->serializer);
 
        em_check_for_link(&adapter->hw);
        em_print_link_status(adapter);
@@ -1478,7 +1485,7 @@ em_local_timer(void *arg)
 
        callout_reset(&adapter->timer, 2*hz, em_local_timer, adapter);
 
-       splx(s);
+       lwkt_serialize_exit(&adapter->serializer);
 }
 
 static void
@@ -1643,6 +1650,9 @@ em_setup_interface(device_t dev, struct adapter *adapter)
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = em_ioctl;
        ifp->if_start = em_start;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = em_poll;
+#endif
        ifp->if_watchdog = em_watchdog;
        ifq_set_maxlen(&ifp->if_snd, adapter->num_tx_desc - 1);
        ifq_set_ready(&ifp->if_snd);
@@ -2081,7 +2091,6 @@ em_transmit_checksum_setup(struct adapter * adapter,
 static void
 em_clean_transmit_interrupts(struct adapter *adapter)
 {
-       int s;
        int i, num_avail;
        struct em_buffer *tx_buffer;
        struct em_tx_desc *tx_desc;
@@ -2090,7 +2099,6 @@ em_clean_transmit_interrupts(struct adapter *adapter)
        if (adapter->num_tx_desc_avail == adapter->num_tx_desc)
                return;
 
-       s = splimp();
 #ifdef DBG_STATS
        adapter->clean_tx_interrupts++;
 #endif
@@ -2138,7 +2146,6 @@ em_clean_transmit_interrupts(struct adapter *adapter)
                        ifp->if_timer = EM_TX_TIMEOUT;
        }
        adapter->num_tx_desc_avail = num_avail;
-       splx(s);
 }
 
 /*********************************************************************
@@ -2616,8 +2623,12 @@ em_enable_vlans(struct adapter *adapter)
 static void
 em_enable_intr(struct adapter *adapter)
 {
-       bus_enable_intr(adapter->dev, adapter->int_handler_tag);
-       E1000_WRITE_REG(&adapter->hw, IMS, (IMS_ENABLE_MASK));
+       struct ifnet *ifp = &adapter->interface_data.ac_if;
+       
+       if ((ifp->if_flags & IFF_POLLING) == 0) {
+               lwkt_serialize_handler_enable(&adapter->serializer);
+               E1000_WRITE_REG(&adapter->hw, IMS, (IMS_ENABLE_MASK));
+       }
 }
 
 static void
@@ -2625,7 +2636,7 @@ em_disable_intr(struct adapter *adapter)
 {
        E1000_WRITE_REG(&adapter->hw, IMC, 
                        (0xffffffff & ~E1000_IMC_RXSEQ));
-       bus_disable_intr(adapter->dev, adapter->int_handler_tag);
+       lwkt_serialize_handler_disable(&adapter->serializer);
 }
 
 static int
@@ -2975,7 +2986,6 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
        int error;
        int usecs;
        int ticks;
-       int s;
 
        info = (struct em_int_delay_info *)arg1;
        adapter = info->adapter;
@@ -2988,7 +2998,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
        info->value = usecs;
        ticks = E1000_USECS_TO_TICKS(usecs);
 
-       s = splimp();
+       lwkt_serialize_enter(&adapter->serializer);
        regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
        regval = (regval & ~0xffff) | (ticks & 0xffff);
        /* Handle a few special cases. */
@@ -3008,7 +3018,7 @@ em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
                break;
        }
        E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
-       splx(s);
+       lwkt_serialize_exit(&adapter->serializer);
        return(0);
 }
 
@@ -3045,15 +3055,15 @@ em_sysctl_int_throttle(SYSCTL_HANDLER_ARGS)
                 * recalculate sysctl value assignment to get exact frequency.
                 */
                throttle = 1000000000 / 256 / throttle;
+               lwkt_serialize_enter(&adapter->serializer);
                em_int_throttle_ceil = 1000000000 / 256 / throttle;
-               crit_enter();
                E1000_WRITE_REG(&adapter->hw, ITR, throttle);
-               crit_exit();
+               lwkt_serialize_exit(&adapter->serializer);
        } else {
+               lwkt_serialize_enter(&adapter->serializer);
                em_int_throttle_ceil = 0;
-               crit_enter();
                E1000_WRITE_REG(&adapter->hw, ITR, 0);
-               crit_exit();
+               lwkt_serialize_exit(&adapter->serializer);
        }
        device_printf(adapter->dev, "Interrupt moderation set to %d/sec\n", 
                        em_int_throttle_ceil);
index 3e714a8..3077cbb 100644 (file)
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
 ***************************************************************************/
 
 /*$FreeBSD: src/sys/dev/em/if_em.h,v 1.1.2.13 2003/06/09 21:43:41 pdeuskar Exp $*/
-/*$DragonFly: src/sys/dev/netif/em/if_em.h,v 1.9 2005/05/24 20:59:01 dillon Exp $*/
+/*$DragonFly: src/sys/dev/netif/em/if_em.h,v 1.10 2005/05/25 01:44:21 dillon Exp $*/
 
 #ifndef _EM_H_DEFINED_
 #define _EM_H_DEFINED_
@@ -75,6 +75,7 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <sys/proc.h>
 #include <sys/sysctl.h>
 #include <sys/thread2.h>
+#include <sys/serialize.h>
 #include "opt_bdg.h"
 
 #include <dev/netif/em/if_em_hw.h>
@@ -333,6 +334,7 @@ struct adapter {
        struct em_hw    hw;
 
        /* FreeBSD operating-system-specific structures */
+       struct lwkt_serialize serializer;
        struct em_osdep osdep;
        struct device   *dev;
        struct resource *res_memory;
index 7031906..50ff9a9 100644 (file)
@@ -32,7 +32,7 @@
  * SUCH DAMAGE.
  * 
  * $FreeBSD: src/sys/dev/firewire/if_fwe.c,v 1.27 2004/01/08 14:58:09 simokawa Exp $
- * $DragonFly: src/sys/dev/netif/fwe/if_fwe.c,v 1.14 2005/02/18 23:10:27 joerg Exp $
+ * $DragonFly: src/sys/dev/netif/fwe/if_fwe.c,v 1.15 2005/05/25 01:44:23 dillon Exp $
  */
 
 #include "opt_inet.h"
@@ -102,20 +102,6 @@ TUNABLE_INT("hw.firewire.fwe.tx_speed", &tx_speed);
 TUNABLE_INT("hw.firewire.fwe.rx_queue_len", &rx_queue_len);
 
 #ifdef DEVICE_POLLING
-#define FWE_POLL_REGISTER(func, fwe, ifp)                      \
-       if (ether_poll_register(func, ifp)) {                   \
-               struct firewire_comm *fc = (fwe)->fd.fc;        \
-               fc->set_intr(fc, 0);                            \
-       }
-
-#define FWE_POLL_DEREGISTER(fwe, ifp)                          \
-       do {                                                    \
-               struct firewire_comm *fc = (fwe)->fd.fc;        \
-               ether_poll_deregister(ifp);                     \
-               fc->set_intr(fc, 1);                            \
-       } while(0)                                              \
-
-static poll_handler_t fwe_poll;
 
 static void
 fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
@@ -125,17 +111,23 @@ fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 
        fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe;
        fc = fwe->fd.fc;
-       if (cmd == POLL_DEREGISTER) {
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               fc->set_intr(fc, 0);
+               break;
+       case POLL_DEREGISTER:
                /* enable interrupts */
                fc->set_intr(fc, 1);
-               return;
+               break;
+       default:
+               fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
+               break;
        }
-       fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count);
 }
-#else
-#define FWE_POLL_REGISTER(func, fwe, ifp)
-#define FWE_POLL_DEREGISTER(fwe, ifp)
+
 #endif
+
 static void
 fwe_identify(driver_t *driver, device_t parent)
 {
@@ -214,6 +206,9 @@ fwe_attach(device_t dev)
        ifp->if_init = fwe_init;
        ifp->if_start = fwe_start;
        ifp->if_ioctl = fwe_ioctl;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = fwe_poll;
+#endif
        ifp->if_mtu = ETHERMTU;
        ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
        ifq_set_maxlen(&ifp->if_snd, TX_MAX_QUEUE);
@@ -245,7 +240,7 @@ fwe_stop(struct fwe_softc *fwe)
 
        fc = fwe->fd.fc;
 
-       FWE_POLL_DEREGISTER(fwe, ifp);
+       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 
        if (fwe->dma_ch >= 0) {
                xferq = fc->ir[fwe->dma_ch];
@@ -271,8 +266,6 @@ fwe_stop(struct fwe_softc *fwe)
                xferq->bulkxfer =  NULL;
                fwe->dma_ch = -1;
        }
-
-       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 }
 
 static int
@@ -384,12 +377,6 @@ found:
 
        ifp->if_flags |= IFF_RUNNING;
        ifp->if_flags &= ~IFF_OACTIVE;
-
-       FWE_POLL_REGISTER(fwe_poll, fwe, ifp);
-#if 0
-       /* attempt to start output */
-       fwe_start(ifp);
-#endif
 }
 
 
@@ -570,9 +557,6 @@ fwe_as_input(struct fw_xferq *xferq)
 
        fwe = (struct fwe_softc *)xferq->sc;
        ifp = &fwe->fwe_if;
-#if 0
-       FWE_POLL_REGISTER(fwe_poll, fwe, ifp);
-#endif
        while ((sxfer = STAILQ_FIRST(&xferq->stvalid)) != NULL) {
                STAILQ_REMOVE_HEAD(&xferq->stvalid, link);
                fp = mtod(sxfer->mbuf, struct fw_pkt *);
index 5bb3aca..583f364 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.110.2.30 2003/06/12 16:47:05 mux Exp $
- * $DragonFly: src/sys/dev/netif/fxp/if_fxp.c,v 1.26 2005/05/24 20:59:01 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/fxp/if_fxp.c,v 1.27 2005/05/25 01:44:24 dillon Exp $
  */
 
 /*
@@ -234,6 +234,10 @@ static int         sysctl_int_range(SYSCTL_HANDLER_ARGS,
                            int low, int high);
 static int             sysctl_hw_fxp_bundle_max(SYSCTL_HANDLER_ARGS);
 static int             sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS);
+#ifdef DEVICE_POLLING
+static poll_handler_t fxp_poll;
+#endif
+
 static __inline void   fxp_lwcopy(volatile u_int32_t *src,
                            volatile u_int32_t *dst);
 static __inline void   fxp_scb_wait(struct fxp_softc *sc);
@@ -656,6 +660,9 @@ fxp_attach(device_t dev)
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = fxp_ioctl;
        ifp->if_start = fxp_start;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = fxp_poll;
+#endif
        ifp->if_watchdog = fxp_watchdog;
 
        /*
@@ -1157,7 +1164,6 @@ tbdinit:
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t fxp_poll;
 
 static void
 fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
@@ -1165,26 +1171,35 @@ fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
        struct fxp_softc *sc = ifp->if_softc;
        u_int8_t statack;
 
-       if (cmd == POLL_DEREGISTER) {   /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0);
-               return;
-       }
-       statack = FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA |
-           FXP_SCB_STATACK_FR;
-       if (cmd == POLL_AND_CHECK_STATUS) {
-               u_int8_t tmp;
-
-               tmp = CSR_READ_1(sc, FXP_CSR_SCB_STATACK);
-               if (tmp == 0xff || tmp == 0)
-                       return; /* nothing to do */
-               tmp &= ~statack;
-               /* ack what we can */
-               if (tmp != 0)
-                       CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, tmp);
-               statack |= tmp;
+               break;
+       default:
+               statack = FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA |
+                         FXP_SCB_STATACK_FR;
+               if (cmd == POLL_AND_CHECK_STATUS) {
+                       u_int8_t tmp;
+
+                       tmp = CSR_READ_1(sc, FXP_CSR_SCB_STATACK);
+                       if (tmp == 0xff || tmp == 0)
+                               return; /* nothing to do */
+                       tmp &= ~statack;
+                       /* ack what we can */
+                       if (tmp != 0)
+                               CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, tmp);
+                       statack |= tmp;
+               }
+               fxp_intr_body(sc, statack, count);
+               break;
        }
-       fxp_intr_body(sc, statack, count);
 }
+
 #endif /* DEVICE_POLLING */
 
 /*
@@ -1196,19 +1211,6 @@ fxp_intr(void *xsc)
        struct fxp_softc *sc = xsc;
        u_int8_t statack;
 
-#ifdef DEVICE_POLLING
-       struct ifnet *ifp = &sc->arpcom.ac_if;
-
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-       if (ether_poll_register(fxp_poll, ifp)) {
-               /* disable interrupts */
-               CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
-               fxp_poll(ifp, 0, 1);
-               return;
-       }
-#endif
-
        if (sc->suspended) {
                return;
        }
@@ -1495,9 +1497,6 @@ fxp_stop(struct fxp_softc *sc)
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
        ifp->if_timer = 0;
 
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif
        /*
         * Cancel stats updater.
         */
index b517942..6d8e289 100644 (file)
@@ -31,7 +31,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/nge/if_nge.c,v 1.13.2.13 2003/02/05 22:03:57 mbr Exp $
- * $DragonFly: src/sys/dev/netif/nge/if_nge.c,v 1.23 2005/05/24 20:59:02 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/nge/if_nge.c,v 1.24 2005/05/25 01:44:26 dillon Exp $
  */
 
 /*
@@ -186,6 +186,9 @@ static void nge_setmulti(struct nge_softc *);
 static void    nge_reset(struct nge_softc *);
 static int     nge_list_rx_init(struct nge_softc *);
 static int     nge_list_tx_init(struct nge_softc *);
+#ifdef DEVICE_POLLING
+static void    nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+#endif
 
 #ifdef NGE_USEIOSPACE
 #define NGE_RES                        SYS_RES_IOPORT
@@ -863,6 +866,9 @@ nge_attach(device_t dev)
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = nge_ioctl;
        ifp->if_start = nge_start;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = nge_poll;
+#endif
        ifp->if_watchdog = nge_watchdog;
        ifp->if_init = nge_init;
        ifp->if_baudrate = 1000000000;
@@ -1464,49 +1470,56 @@ nge_tick(void *xsc)
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t nge_poll;
 
 static void
 nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct nge_softc *sc = ifp->if_softc;
 
-       if (cmd == POLL_DEREGISTER) {   /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               CSR_WRITE_4(sc, NGE_IER, 0);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_4(sc, NGE_IER, 1);
-               return;
-       }
-
-       /*
-        * On the nge, reading the status register also clears it.
-        * So before returning to intr mode we must make sure that all
-        * possible pending sources of interrupts have been served.
-        * In practice this means run to completion the *eof routines,
-        * and then call the interrupt routine
-        */
-       sc->rxcycles = count;
-       nge_rxeof(sc);
-       nge_txeof(sc);
-       if (!ifq_is_empty(&ifp->if_snd))
-               nge_start(ifp);
+               break;
+       default:
+               /*
+                * On the nge, reading the status register also clears it.
+                * So before returning to intr mode we must make sure that all
+                * possible pending sources of interrupts have been served.
+                * In practice this means run to completion the *eof routines,
+                * and then call the interrupt routine
+                */
+               sc->rxcycles = count;
+               nge_rxeof(sc);
+               nge_txeof(sc);
+               if (!ifq_is_empty(&ifp->if_snd))
+                       nge_start(ifp);
 
-       if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
-               uint32_t status;
+               if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
+                       uint32_t status;
 
-               /* Reading the ISR register clears all interrupts. */
-               status = CSR_READ_4(sc, NGE_ISR);
+                       /* Reading the ISR register clears all interrupts. */
+                       status = CSR_READ_4(sc, NGE_ISR);
 
-               if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW))
-                       nge_rxeof(sc);
+                       if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW))
+                               nge_rxeof(sc);
 
-               if (status & (NGE_ISR_RX_IDLE))
-                       NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
+                       if (status & (NGE_ISR_RX_IDLE))
+                               NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE);
 
-               if (status & NGE_ISR_SYSERR) {
-                       nge_reset(sc);
-                       nge_init(sc);
+                       if (status & NGE_ISR_SYSERR) {
+                               nge_reset(sc);
+                               nge_init(sc);
+                       }
                }
+               break;
        }
 }
+
 #endif /* DEVICE_POLLING */
 
 static void
@@ -1516,16 +1529,6 @@ nge_intr(void *arg)
        struct ifnet *ifp = &sc->arpcom.ac_if;
        uint32_t status;
 
-#ifdef DEVICE_POLLING
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-       if (ether_poll_register(nge_poll, ifp)) { /* ok, disable interrupts */
-               CSR_WRITE_4(sc, NGE_IER, 0);
-               nge_poll(ifp, 0, 1);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        /* Supress unwanted interrupts */
        if (!(ifp->if_flags & IFF_UP)) {
                nge_stop(sc);
@@ -2115,9 +2118,6 @@ nge_stop(struct nge_softc *sc)
                mii = device_get_softc(sc->nge_miibus);
 
        callout_stop(&sc->nge_stat_timer);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif
        CSR_WRITE_4(sc, NGE_IER, 0);
        CSR_WRITE_4(sc, NGE_IMR, 0);
        NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE);
index 7b5a7c1..f061cf5 100644 (file)
@@ -33,7 +33,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/re/if_re.c,v 1.25 2004/06/09 14:34:01 naddy Exp $
- * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.11 2005/05/24 20:59:02 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/re/if_re.c,v 1.12 2005/05/25 01:44:27 dillon Exp $
  */
 
 /*
@@ -222,6 +222,9 @@ static void re_setmulti(struct re_softc *);
 static void    re_reset(struct re_softc *);
 
 static int     re_diag(struct re_softc *);
+#ifdef DEVICE_POLLING
+static void    re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+#endif
 
 static device_method_t re_methods[] = {
        /* Device interface */
@@ -1132,7 +1135,7 @@ re_attach(device_t dev)
        ifp->if_start = re_start;
        ifp->if_capabilities |= IFCAP_HWCSUM|IFCAP_VLAN_HWTAGGING;
 #ifdef DEVICE_POLLING
-       ifp->if_capabilities |= IFCAP_POLLING;
+       ifp->if_poll = re_poll;
 #endif
        ifp->if_watchdog = re_watchdog;
        ifp->if_init = re_init;
@@ -1590,44 +1593,48 @@ re_tick(void *xsc)
 }
 
 #ifdef DEVICE_POLLING
+
 static void
 re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct re_softc *sc = ifp->if_softc;
 
-       if ((ifp->if_capenable & IFCAP_POLLING) == 0) {
-               ether_poll_deregister(ifp);
-               cmd = POLL_DEREGISTER;
-       }
-       if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               CSR_WRITE_2(sc, RE_IMR, 0x0000);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_2(sc, RE_IMR, RE_INTRS_CPLUS);
-               return;
-       }
-
-       sc->rxcycles = count;
-       re_rxeof(sc);
-       re_txeof(sc);
+               break;
+       default:
+               sc->rxcycles = count;
+               re_rxeof(sc);
+               re_txeof(sc);
 
-       if (!ifq_is_empty(&ifp->if_snd))
-               (*ifp->if_start)(ifp);
+               if (!ifq_is_empty(&ifp->if_snd))
+                       (*ifp->if_start)(ifp);
 
-       if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
-               uint16_t       status;
+               if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
+                       uint16_t       status;
 
-               status = CSR_READ_2(sc, RE_ISR);
-               if (status == 0xffff)
-                       return;
-               if (status)
-                       CSR_WRITE_2(sc, RE_ISR, status);
+                       status = CSR_READ_2(sc, RE_ISR);
+                       if (status == 0xffff)
+                               return;
+                       if (status)
+                               CSR_WRITE_2(sc, RE_ISR, status);
 
-               /*
-                * XXX check behaviour on receiver stalls.
-                */
+                       /*
+                        * XXX check behaviour on receiver stalls.
+                        */
 
-               if (status & RE_ISR_SYSTEM_ERR) {
-                       re_reset(sc);
-                       re_init(sc);
+                       if (status & RE_ISR_SYSTEM_ERR) {
+                               re_reset(sc);
+                               re_init(sc);
+                       }
                }
+               break;
        }
 }
 #endif /* DEVICE_POLLING */
@@ -1643,17 +1650,6 @@ re_intr(void *arg)
        if (sc->suspended || (ifp->if_flags & IFF_UP) == 0)
                return;
 
-#ifdef DEVICE_POLLING
-       if  (ifp->if_flags & IFF_POLLING)
-               return;
-       if ((ifp->if_capenable & IFCAP_POLLING) &&
-           ether_poll_register(re_poll, ifp)) { /* ok, disable interrupts */
-               CSR_WRITE_2(sc, RE_IMR, 0x0000);
-               re_poll(ifp, 0, 1);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        s = splimp();
 
        for (;;) {
@@ -2117,9 +2113,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
                break;
        case SIOCSIFCAP:
-               ifp->if_capenable &= ~(IFCAP_HWCSUM | IFCAP_POLLING);
+               ifp->if_capenable &= ~(IFCAP_HWCSUM);
                ifp->if_capenable |=
-                   ifr->ifr_reqcap & (IFCAP_HWCSUM | IFCAP_POLLING);
+                   ifr->ifr_reqcap & (IFCAP_HWCSUM);
                if (ifp->if_capenable & IFCAP_TXCSUM)
                        ifp->if_hwassist = RE_CSUM_FEATURES;
                else
@@ -2170,9 +2166,6 @@ re_stop(struct re_softc *sc)
        callout_stop(&sc->re_timer);
 
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif /* DEVICE_POLLING */
 
        CSR_WRITE_1(sc, RE_COMMAND, 0x00);
        CSR_WRITE_2(sc, RE_IMR, 0x0000);
index 2f2ac8c..2a02cf8 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_rl.c,v 1.38.2.16 2003/03/05 18:42:33 njl Exp $
- * $DragonFly: src/sys/dev/netif/rl/if_rl.c,v 1.21 2005/05/24 20:59:02 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/rl/if_rl.c,v 1.22 2005/05/25 01:44:28 dillon Exp $
  */
 
 /*
@@ -207,6 +207,9 @@ static void rl_list_tx_init(struct rl_softc *);
 
 static void    rl_dma_map_rxbuf(void *, bus_dma_segment_t *, int, int);
 static void    rl_dma_map_txbuf(void *, bus_dma_segment_t *, int, int);
+#ifdef DEVICE_POLLING
+static poll_handler_t rl_poll;
+#endif
 
 #ifdef RL_USEIOSPACE
 #define        RL_RES                  SYS_RES_IOPORT
@@ -926,7 +929,7 @@ rl_attach(device_t dev)
        ifp->if_baudrate = 10000000;
        ifp->if_capabilities = IFCAP_VLAN_MTU;
 #ifdef DEVICE_POLLING
-       ifp->if_capabilities |= IFCAP_POLLING;
+       ifp->if_poll = rl_poll;
 #endif
        ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
        ifq_set_ready(&ifp->if_snd);
@@ -1237,45 +1240,47 @@ rl_tick(void *xsc)
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t rl_poll;
 
 static void
 rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct rl_softc *sc = ifp->if_softc;
 
-       if ((ifp->if_capenable & IFCAP_POLLING) == 0) {
-               ether_poll_deregister(ifp);
-               cmd = POLL_DEREGISTER;
-       }
-       if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+                CSR_WRITE_2(sc, RL_IMR, 0x0000);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
-               return;
-       }
-
-       sc->rxcycles = count;
-       rl_rxeof(sc);
-       rl_txeof(sc);
-       if (!ifq_is_empty(&ifp->if_snd))
-               rl_start(ifp);
-
-       if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
-               uint16_t status;
-               status = CSR_READ_2(sc, RL_ISR);
-               if (status == 0xffff)
-                       return;
-               if (status)
-                       CSR_WRITE_2(sc, RL_ISR, status);
-                 
-               /*
-                * XXX check behaviour on receiver stalls.
-                */
+               break;
+       default:
+               sc->rxcycles = count;
+               rl_rxeof(sc);
+               rl_txeof(sc);
+               if (!ifq_is_empty(&ifp->if_snd))
+                       rl_start(ifp);
+
+               if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
+                       uint16_t status;
+        
+                       status = CSR_READ_2(sc, RL_ISR);
+                       if (status == 0xffff)
+                               return;
+                       if (status)
+                               CSR_WRITE_2(sc, RL_ISR, status);
+                        
+                       /*
+                        * XXX check behaviour on receiver stalls.
+                        */
 
-               if (status & RL_ISR_SYSTEM_ERR) {
-                       rl_reset(sc);
-                       rl_init(sc);
+                       if (status & RL_ISR_SYSTEM_ERR) {
+                               rl_reset(sc);
+                               rl_init(sc);
+                       }
                }
+               break;
        }
 }
 #endif /* DEVICE_POLLING */
@@ -1293,16 +1298,6 @@ rl_intr(void *arg)
                return;
 
        ifp = &sc->arpcom.ac_if;
-#ifdef DEVICE_POLLING
-        if  (ifp->if_flags & IFF_POLLING)
-                return;
-        if ((ifp->if_capenable & IFCAP_POLLING) &&
-           ether_poll_register(rl_poll, ifp)) { /* ok, disable interrupts */
-                CSR_WRITE_2(sc, RL_IMR, 0x0000);
-                rl_poll(ifp, 0, 1);
-                return;
-        }
-#endif /* DEVICE_POLLING */
 
        for (;;) {
                status = CSR_READ_2(sc, RL_ISR);
@@ -1610,8 +1605,6 @@ rl_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
                error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
                break;
        case SIOCSIFCAP:
-               ifp->if_capenable &= ~IFCAP_POLLING;
-               ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
                break;
        default:
                error = ether_ioctl(ifp, command, data);
@@ -1655,9 +1648,6 @@ rl_stop(struct rl_softc *sc)
 
        callout_stop(&sc->rl_stat_timer);
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif /* DEVICE_POLLING */
 
        CSR_WRITE_1(sc, RL_COMMAND, 0x00);
        CSR_WRITE_2(sc, RL_IMR, 0x0000);
index 654b8ae..986a840 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_sis.c,v 1.13.4.24 2003/03/05 18:42:33 njl Exp $
- * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.22 2005/05/24 20:59:02 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/sis/if_sis.c,v 1.23 2005/05/25 01:44:29 dillon Exp $
  */
 
 /*
@@ -159,6 +159,9 @@ static int  sis_list_tx_init(struct sis_softc *);
 static void    sis_dma_map_desc_ptr(void *, bus_dma_segment_t *, int, int);
 static void    sis_dma_map_desc_next(void *, bus_dma_segment_t *, int, int);
 static void    sis_dma_map_ring(void *, bus_dma_segment_t *, int, int);
+#ifdef DEVICE_POLLING
+static poll_handler_t sis_poll;
+#endif
 #ifdef SIS_USEIOSPACE
 #define SIS_RES                        SYS_RES_IOPORT
 #define SIS_RID                        SIS_PCI_LOIO
@@ -1281,7 +1284,7 @@ sis_attach(device_t dev)
        ifq_set_maxlen(&ifp->if_snd, SIS_TX_LIST_CNT - 1);
        ifq_set_ready(&ifp->if_snd);
 #ifdef DEVICE_POLLING
-       ifp->if_capabilities |= IFCAP_POLLING;
+       ifp->if_poll = sis_poll;
 #endif
        ifp->if_capenable = ifp->if_capabilities;
 
@@ -1658,51 +1661,53 @@ sis_tick(void *xsc)
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t sis_poll;
 
 static void
 sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct  sis_softc *sc = ifp->if_softc;
 
-       if ((ifp->if_capenable & IFCAP_POLLING) == 0) {
-               ether_poll_deregister(ifp);
-               cmd = POLL_DEREGISTER;
-       }
-       if (cmd == POLL_DEREGISTER) {   /* final call, enable interrupts */
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               CSR_WRITE_4(sc, SIS_IER, 0);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_4(sc, SIS_IER, 1);
-               return;
-       }
+               break;
+       default:
+               /*
+                * On the sis, reading the status register also clears it.
+                * So before returning to intr mode we must make sure that all
+                * possible pending sources of interrupts have been served.
+                * In practice this means run to completion the *eof routines,
+                * and then call the interrupt routine
+                */
+               sc->rxcycles = count;
+               sis_rxeof(sc);
+               sis_txeof(sc);
+               if (!ifq_is_empty(&ifp->if_snd))
+                       sis_start(ifp);
 
-       /*
-        * On the sis, reading the status register also clears it.
-        * So before returning to intr mode we must make sure that all
-        * possible pending sources of interrupts have been served.
-        * In practice this means run to completion the *eof routines,
-        * and then call the interrupt routine
-        */
-       sc->rxcycles = count;
-       sis_rxeof(sc);
-       sis_txeof(sc);
-       if (!ifq_is_empty(&ifp->if_snd))
-               sis_start(ifp);
+               if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
+                       uint32_t status;
 
-       if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) {
-               uint32_t status;
+                       /* Reading the ISR register clears all interrupts. */
+                       status = CSR_READ_4(sc, SIS_ISR);
 
-               /* Reading the ISR register clears all interrupts. */
-               status = CSR_READ_4(sc, SIS_ISR);
-
-               if (status & (SIS_ISR_RX_ERR|SIS_ISR_RX_OFLOW))
-                       sis_rxeoc(sc);
+                       if (status & (SIS_ISR_RX_ERR|SIS_ISR_RX_OFLOW))
+                               sis_rxeoc(sc);
 
-               if (status & (SIS_ISR_RX_IDLE))
-                       SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
+                       if (status & (SIS_ISR_RX_IDLE))
+                               SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
 
-               if (status & SIS_ISR_SYSERR) {
-                       sis_reset(sc);
-                       sis_init(sc);
+                       if (status & SIS_ISR_SYSERR) {
+                               sis_reset(sc);
+                               sis_init(sc);
+                       }
                }
+               break;
        }
 }
 #endif /* DEVICE_POLLING */
@@ -1717,17 +1722,6 @@ sis_intr(void *arg)
        sc = arg;
        ifp = &sc->arpcom.ac_if;
 
-#ifdef DEVICE_POLLING
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-       if ((ifp->if_capenable & IFCAP_POLLING) &&
-           ether_poll_register(sis_poll, ifp)) { /* ok, disable interrupts */
-               CSR_WRITE_4(sc, SIS_IER, 0);
-               sis_poll(ifp, 0, 1);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        /* Supress unwanted interrupts */
        if (!(ifp->if_flags & IFF_UP)) {
                sis_stop(sc);
@@ -2170,9 +2164,6 @@ sis_stop(struct sis_softc *sc)
        callout_stop(&sc->sis_timer);
 
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif
        CSR_WRITE_4(sc, SIS_IER, 0);
        CSR_WRITE_4(sc, SIS_IMR, 0);
        SIS_SETBIT(sc, SIS_CSR, SIS_CSR_TX_DISABLE|SIS_CSR_RX_DISABLE);
index 85bb403..3ae3cbd 100644 (file)
@@ -30,7 +30,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/if_vr.c,v 1.26.2.13 2003/02/06 04:46:20 silby Exp $
- * $DragonFly: src/sys/dev/netif/vr/if_vr.c,v 1.22 2005/05/24 20:59:03 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/vr/if_vr.c,v 1.23 2005/05/25 01:44:31 dillon Exp $
  */
 
 /*
@@ -161,6 +161,9 @@ static void vr_setmulti(struct vr_softc *);
 static void    vr_reset(struct vr_softc *);
 static int     vr_list_rx_init(struct vr_softc *);
 static int     vr_list_tx_init(struct vr_softc *);
+#ifdef DEVICE_POLLING
+static void    vr_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+#endif
 
 #ifdef VR_USEIOSPACE
 #define VR_RES                 SYS_RES_IOPORT
@@ -835,6 +838,9 @@ vr_attach(device_t dev)
        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
        ifp->if_ioctl = vr_ioctl;
        ifp->if_start = vr_start;
+#ifdef DEVICE_POLLING
+       ifp->if_poll = vr_poll;
+#endif
        ifp->if_watchdog = vr_watchdog;
        ifp->if_init = vr_init;
        ifp->if_baudrate = 10000000;
@@ -1604,15 +1610,25 @@ vr_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
 }
 
 #ifdef DEVICE_POLLING
+
 static void
 vr_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct vr_softc *sc = ifp->if_softc;
 
-       if (cmd == POLL_DEREGISTER)
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interrupts */
+               CSR_WRITE_2(sc, VR_IMR, 0x0000);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_2(sc, VR_IMR, VR_INTRS);
-       else
+               break;
+       default:
                vr_intr(sc);
+               break;
+       }
 }
 #endif
 
@@ -1631,8 +1647,7 @@ vr_watchdog(struct ifnet *ifp)
                if_printf(ifp, "ints don't seem to be working, "
                        "emergency switch to polling\n");
                emergency_poll_enable("if_vr");
-               if (ether_poll_register(vr_poll, ifp))
-                       CSR_WRITE_2(sc, VR_IMR, 0x0000);
+               ether_poll_register(ifp);       /* XXX illegal */
        } else 
 #endif
        {
index d21f94c..31c472c 100644 (file)
@@ -32,7 +32,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/wi/if_wi.c,v 1.166 2004/04/01 00:38:45 sam Exp $
- * $DragonFly: src/sys/dev/netif/wi/if_wi.c,v 1.21 2005/05/24 20:59:03 dillon Exp $
+ * $DragonFly: src/sys/dev/netif/wi/if_wi.c,v 1.22 2005/05/25 01:44:32 dillon Exp $
  */
 
 /*
@@ -154,6 +154,9 @@ static int wi_set_debug(struct wi_softc *, struct wi_req *);
 static int wi_symbol_write_firm(struct wi_softc *, const void *, int,
                const void *, int);
 static int wi_symbol_set_hcr(struct wi_softc *, int);
+#ifdef DEVICE_POLLING
+static void wi_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+#endif
 
 static __inline int
 wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
@@ -295,7 +298,7 @@ wi_attach(device_t dev)
        ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
        ifq_set_ready(&ifp->if_snd);
 #ifdef DEVICE_POLLING
-       ifp->if_capabilities |= IFCAP_POLLING;
+       ifp->if_poll = wi_poll;
 #endif
        ifp->if_capenable = ifp->if_capabilities;
 
@@ -520,38 +523,43 @@ wi_shutdown(device_t dev)
 }
 
 #ifdef DEVICE_POLLING
+
 static void
 wi_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
        struct wi_softc *sc = ifp->if_softc;
        uint16_t status;
 
-       if ((ifp->if_capenable & IFCAP_POLLING) == 0) {
-               ether_poll_deregister(ifp);
-               cmd = POLL_DEREGISTER;
-       }
-       if (cmd == POLL_DEREGISTER) {
+       switch(cmd) {
+       case POLL_REGISTER:
+               /* disable interruptds */
+               CSR_WRITE_2(sc, WI_INT_EN, 0);
+               break;
+       case POLL_DEREGISTER:
+               /* enable interrupts */
                CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
-               return;
-       }
-
-       status = CSR_READ_2(sc, WI_EVENT_STAT);
-
-       if (status & WI_EV_RX)
-               wi_rx_intr(sc);
-       if (status & WI_EV_ALLOC)
-               wi_tx_intr(sc);
-       if (status & WI_EV_INFO)
-               wi_info_intr(sc);
+               break;
+       default:
+               status = CSR_READ_2(sc, WI_EVENT_STAT);
 
-       if (cmd == POLL_AND_CHECK_STATUS) {
+               if (status & WI_EV_RX)
+                       wi_rx_intr(sc);
+               if (status & WI_EV_ALLOC)
+                       wi_tx_intr(sc);
                if (status & WI_EV_INFO)
                        wi_info_intr(sc);
-       }
 
-       if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
-           (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 && !ifq_is_empty(&ifp->if_snd))
-               wi_start(ifp);
+               if (cmd == POLL_AND_CHECK_STATUS) {
+                       if (status & WI_EV_INFO)
+                               wi_info_intr(sc);
+               }
+
+               if ((ifp->if_flags & IFF_OACTIVE) == 0 &&
+                   (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 && !ifq_is_empty(&ifp->if_snd)) {
+                       wi_start(ifp);
+               }
+               break;
+       }
 }
 #endif /* DEVICE_POLLING */
 
@@ -563,17 +571,6 @@ wi_intr(void *arg)
        u_int16_t status;
        WI_LOCK_DECL();
 
-#ifdef DEVICE_POLLING
-       if (ifp->if_flags & IFF_POLLING)
-               return;
-       if ((ifp->if_capenable & IFCAP_POLLING) && 
-           (ether_poll_register(wi_poll, ifp))) {
-               CSR_WRITE_2(sc, WI_INT_EN, 0);
-               wi_poll(ifp, 0, 1);
-               return;
-       }
-#endif /* DEVICE_POLLING */
-
        if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) {
                CSR_WRITE_2(sc, WI_INT_EN, 0);
                CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
@@ -812,6 +809,7 @@ wi_stop(struct ifnet *ifp, int disable)
 
        DELAY(100000);
 
+       ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
        if (sc->sc_enabled && !sc->wi_gone) {
                CSR_WRITE_2(sc, WI_INT_EN, 0);
@@ -831,10 +829,6 @@ wi_stop(struct ifnet *ifp, int disable)
        sc->sc_syn_timer = 0;
        sc->sc_false_syns = 0;
        sc->sc_naps = 0;
-       ifp->if_flags &= ~(IFF_OACTIVE | IFF_RUNNING);
-#ifdef DEVICE_POLLING
-       ether_poll_deregister(ifp);
-#endif
        ifp->if_timer = 0;
 
        WI_UNLOCK(sc);
@@ -1184,8 +1178,6 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
                }
                break;
        case SIOCSIFCAP:
-               ifp->if_capenable &= ~(IFCAP_POLLING);
-               ifp->if_capenable |= ifr->ifr_reqcap & (IFCAP_POLLING);
                if (ifp->if_flags & IFF_RUNNING)
                        wi_init(sc);
                break;
index d780c6b..0fecbb7 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.14 2005/05/24 20:59:05 dillon Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/nexus.c,v 1.15 2005/05/25 01:44:04 dillon Exp $
  */
 
 /*
@@ -538,15 +538,19 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
                mask = &cam_imask;
                break;
        case INTR_TYPE_CLK:
-               mask = 0;
+               mask = NULL;
                printf("nexus: Warning: do not know what imask to use for INTR_TYPE_CLK\n");
                break;
        case INTR_TYPE_MISC:
-               mask = 0;
+               mask = NULL;
                break;
        default:
                panic("still using grody create_intr interface");
        }
+       if (serializer && mask != NULL) {
+               device_printf(child, "nexus_setup_intr: Warning, driver must set interrupt type to INTR_TYPE_MISC when using a serializer.\n");
+               mask = NULL;
+       }
        if (flags & INTR_FAST)
                icflags |= INTR_FAST;
 
index c0b4416..fd8892b 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/i386/include/Attic/atomic.h,v 1.10 2005/05/24 20:58:38 dillon Exp $
+ * $DragonFly: src/sys/i386/include/Attic/atomic.h,v 1.11 2005/05/25 01:44:12 dillon Exp $
  */
 #ifndef _MACHINE_ATOMIC_H_
 #define _MACHINE_ATOMIC_H_
@@ -243,7 +243,7 @@ static __inline
 void
 atomic_intr_handler_enable(atomic_intr_t *p)
 {
-       __asm __volatile(MPLOCKED "andl $0xB0000000,%0" : "+m" (*p));
+       __asm __volatile(MPLOCKED "andl $0xBFFFFFFF,%0" : "+m" (*p));
 }
 
 static __inline
index eb3fc65..5da715a 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_poll.c,v 1.2.2.4 2002/06/27 23:26:33 luigi Exp $
- * $DragonFly: src/sys/kern/kern_poll.c,v 1.14 2005/05/24 21:18:27 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_poll.c,v 1.15 2005/05/25 01:44:14 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -65,6 +65,7 @@ void hardclock_device_poll(void);     /* hook from hardclock          */
  *     other more expensive operations. This command is issued periodically
  *     but less frequently than POLL_ONLY.
  *  POLL_DEREGISTER: deregister and return to interrupt mode.
+ *  POLL_REGISTER: register and disable interrupts
  *
  * The first two commands are only issued if the interface is marked as
  * 'IFF_UP and IFF_RUNNING', the last one only if IFF_RUNNING is set.
@@ -159,7 +160,6 @@ SYSCTL_UINT(_kern_polling, OID_AUTO, stalled, CTLFLAG_RW,
 
 #define POLL_LIST_LEN  128
 struct pollrec {
-       poll_handler_t  *handler;
        struct ifnet    *ifp;
 };
 
@@ -353,18 +353,24 @@ netisr_poll(struct netmsg *msg)
 
        if (polling) {
                for (i = 0 ; i < poll_handlers ; i++) {
-                       if (pr[i].handler && (IFF_UP|IFF_RUNNING) ==
-                           (pr[i].ifp->if_flags & (IFF_UP|IFF_RUNNING)) )
-                               pr[i].handler(pr[i].ifp, arg, cycles);
+                       struct pollrec *p = &pr[i];
+                       if ((p->ifp->if_flags & (IFF_UP|IFF_RUNNING|IFF_POLLING)) == (IFF_UP|IFF_RUNNING|IFF_POLLING)) {
+                               p->ifp->if_poll(p->ifp, arg, cycles);
+                       }
                }
        } else {        /* unregister */
                for (i = 0 ; i < poll_handlers ; i++) {
-                       if (pr[i].handler &&
-                           pr[i].ifp->if_flags & IFF_RUNNING) {
-                               pr[i].ifp->if_flags &= ~IFF_POLLING;
-                               pr[i].handler(pr[i].ifp, POLL_DEREGISTER, 1);
+                       struct pollrec *p = &pr[i];
+                       if (p->ifp->if_flags & IFF_POLLING) {
+                               p->ifp->if_flags &= ~IFF_POLLING;
+                               /*
+                                * Only call the interface deregistration
+                                * function if the interface is still 
+                                * running.
+                                */
+                               if (p->ifp->if_flags & IFF_RUNNING)
+                                       p->ifp->if_poll(p->ifp, POLL_DEREGISTER, 1);
                        }
-                       pr[i].handler=NULL;
                }
                residual_burst = 0;
                poll_handlers = 0;
@@ -378,26 +384,37 @@ netisr_poll(struct netmsg *msg)
 /*
  * Try to register routine for polling. Returns 1 if successful
  * (and polling should be enabled), 0 otherwise.
- * A device is not supposed to register itself multiple times.
  *
- * This is called from within the *_intr() functions, so we do not need
- * further locking.
+ * Called from mainline code only, not called from an interrupt.
  */
 int
-ether_poll_register(poll_handler_t *h, struct ifnet *ifp)
+ether_poll_register(struct ifnet *ifp)
 {
-       int s;
+       int rc;
 
        if (polling == 0) /* polling disabled, cannot register */
                return 0;
-       if (h == NULL || ifp == NULL)           /* bad arguments        */
-               return 0;
-       if ( !(ifp->if_flags & IFF_UP) )        /* must be up           */
+       if ((ifp->if_flags & IFF_UP) == 0)      /* must be up           */
                return 0;
        if (ifp->if_flags & IFF_POLLING)        /* already polling      */
                return 0;
+       if (ifp->if_poll == NULL)               /* no polling support   */
+               return 0;
+
+       /*
+        * Attempt to register.  Interlock with IFF_POLLING.
+        */
+       crit_enter();   /* XXX MP - not mp safe */
+       ifp->if_flags |= IFF_POLLING;
+       ifp->if_poll(ifp, POLL_REGISTER, 0);
+       if ((ifp->if_flags & IFF_POLLING) == 0) {
+               crit_exit();
+               return 0;
+       }
 
-       s = splhigh();
+       /*
+        * Check if there is room.  If there isn't, deregister.
+        */
        if (poll_handlers >= POLL_LIST_LEN) {
                /*
                 * List full, cannot register more entries.
@@ -407,55 +424,60 @@ ether_poll_register(poll_handler_t *h, struct ifnet *ifp)
                 * anyways, so just report a few times and then give up.
                 */
                static int verbose = 10 ;
-               splx(s);
                if (verbose >0) {
                        printf("poll handlers list full, "
                                "maybe a broken driver ?\n");
                        verbose--;
                }
-               return 0; /* no polling for you */
+               ifp->if_flags &= ~IFF_POLLING;
+               ifp->if_poll(ifp, POLL_DEREGISTER, 0);
+               rc = 0;
+       } else {
+               pr[poll_handlers].ifp = ifp;
+               poll_handlers++;
+               rc = 1;
        }
-
-       pr[poll_handlers].handler = h;
-       pr[poll_handlers].ifp = ifp;
-       poll_handlers++;
-       ifp->if_flags |= IFF_POLLING;
-       splx(s);
-       return 1; /* polling enabled in next call */
+       crit_exit();
+       return (rc);
 }
 
 /*
- * Remove interface from the polling list. Normally called by *_stop().
- * It is not an error to call it with IFF_POLLING clear, the call is
- * sufficiently rare to be preferable to save the space for the extra
- * test in each driver in exchange of one additional function call.
+ * Remove interface from the polling list.  Occurs when polling is turned
+ * off.  Called from mainline code only, not called from an interrupt.
  */
 int
 ether_poll_deregister(struct ifnet *ifp)
 {
        int i;
-       int s = splimp();
-       
-       if ( !ifp || !(ifp->if_flags & IFF_POLLING) ) {
-               splx(s);
+
+       crit_enter();
+       if (ifp == NULL || (ifp->if_flags & IFF_POLLING) == 0) {
+               crit_exit();
                return 0;
        }
-       for (i = 0 ; i < poll_handlers ; i++)
+       for (i = 0 ; i < poll_handlers ; i++) {
                if (pr[i].ifp == ifp) /* found it */
                        break;
+       }
        ifp->if_flags &= ~IFF_POLLING; /* found or not... */
        if (i == poll_handlers) {
-               splx(s);
+               crit_exit();
                printf("ether_poll_deregister: ifp not found!!!\n");
                return 0;
        }
        poll_handlers--;
        if (i < poll_handlers) { /* Last entry replaces this one. */
-               pr[i].handler = pr[poll_handlers].handler;
                pr[i].ifp = pr[poll_handlers].ifp;
        }
-       splx(s);
-       return 1;
+       crit_exit();
+
+       /*
+        * Only call the deregistration function if the interface is still
+        * in a run state.
+        */
+       if (ifp->if_flags & IFF_RUNNING)
+               ifp->if_poll(ifp, POLL_DEREGISTER, 1);
+       return (1);
 }
 
 void
index 1ae4bc4..e8014e4 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/lwkt_serialize.c,v 1.1 2005/05/24 21:22:05 dillon Exp $
+ * $DragonFly: src/sys/kern/lwkt_serialize.c,v 1.2 2005/05/25 01:44:14 dillon Exp $
  */
 /*
  * This API provides a fast locked-bus-cycle-based serializer.  It's
@@ -110,7 +110,11 @@ lwkt_serialize_handler_enable(lwkt_serialize_t s)
 void
 lwkt_serialize_handler_call(lwkt_serialize_t s, void (*func)(void *), void *arg)
 {
-    if (atomic_intr_handler_is_enabled(&s->interlock)) {
+    /*
+     * note: a return value of 0 indicates that the interrupt handler is 
+     * enabled.
+     */
+    if (atomic_intr_handler_is_enabled(&s->interlock) == 0) {
        atomic_intr_cond_enter(&s->interlock, lwkt_serialize_sleep, s);
        if (atomic_intr_handler_is_enabled(&s->interlock) == 0)
            func(arg);
index f800618..5c22e76 100644 (file)
@@ -1,5 +1,5 @@
 /*     $KAME: altq_rmclass.c,v 1.18 2003/11/06 06:32:53 kjc Exp $      */
-/*     $DragonFly: src/sys/net/altq/altq_rmclass.c,v 1.1 2005/02/11 22:25:57 joerg Exp $ */
+/*     $DragonFly: src/sys/net/altq/altq_rmclass.c,v 1.2 2005/05/25 01:44:33 dillon Exp $ */
 
 /*
  * Copyright (c) 1991-1997 Regents of the University of California.
@@ -53,6 +53,7 @@
 #include <sys/callout.h>
 #include <sys/errno.h>
 #include <sys/time.h>
+#include <sys/thread.h>
 
 #include <net/if.h>
 
@@ -62,6 +63,8 @@
 #include <net/altq/altq_red.h>
 #include <net/altq/altq_rio.h>
 
+#include <sys/thread2.h>
+
 #ifdef CBQ_TRACE
 static struct cbqtrace cbqtrace_buffer[NCBQTRACE+1];
 static struct cbqtrace *cbqtrace_ptr = NULL;
@@ -1509,9 +1512,8 @@ rmc_restart(void *arg)
 {
        struct rm_class *cl = arg;
        struct rm_ifdat *ifd = cl->ifdat_;
-       int s;
 
-       s = splimp();
+       crit_enter();
        if (cl->sleeping_) {
                cl->sleeping_ = 0;
                cl->undertime_.tv_sec = 0;
@@ -1521,7 +1523,7 @@ rmc_restart(void *arg)
                        (ifd->restart)(ifd->ifq_);
                }
        }
-       splx(s);
+       crit_exit();
 }
 
 /*
index 9dae7ca..6aedf8d 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)if.c        8.3 (Berkeley) 1/4/94
  * $FreeBSD: src/sys/net/if.c,v 1.185 2004/03/13 02:35:03 brooks Exp $
- * $DragonFly: src/sys/net/if.c,v 1.34 2005/05/24 20:58:43 dillon Exp $
+ * $DragonFly: src/sys/net/if.c,v 1.35 2005/05/25 01:44:16 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -318,6 +318,8 @@ if_detach(struct ifnet *ifp)
         * Remove routes and flush queues.
         */
        s = splnet();
+       if (ifp->if_flags & IFF_POLLING)
+               ether_poll_deregister(ifp);
        if_down(ifp);
 
        if (ifq_is_enabled(&ifp->if_snd))
@@ -938,7 +940,6 @@ if_route(struct ifnet *ifp, int flag, int fam)
 void
 if_down(struct ifnet *ifp)
 {
-
        if_unroute(ifp, IFF_UP, AF_UNSPEC);
        netmsg_service_sync();
 }
@@ -1108,6 +1109,17 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct thread *td)
                        if_up(ifp);
                        splx(s);
                }
+
+#ifdef DEVICE_POLLING
+               if ((new_flags ^ ifp->if_flags) & IFF_POLLING) {
+                       if (new_flags & IFF_POLLING) {
+                               ether_poll_register(ifp);
+                       } else {
+                               ether_poll_deregister(ifp);
+                       }
+               }
+#endif
+
                ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
                        (new_flags &~ IFF_CANTCHANGE);
                if (new_flags & IFF_PPROMISC) {
index 1a5add4..982f591 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     From: @(#)if.h  8.1 (Berkeley) 6/10/93
  * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.16 2003/04/15 18:11:19 fjoe Exp $
- * $DragonFly: src/sys/net/if_var.h,v 1.24 2005/02/11 22:25:57 joerg Exp $
+ * $DragonFly: src/sys/net/if_var.h,v 1.25 2005/05/25 01:44:16 dillon Exp $
  */
 
 #ifndef        _NET_IF_VAR_H_
@@ -106,6 +106,11 @@ struct     ifqueue {
        int     ifq_drops;
 };
 
+#ifdef DEVICE_POLLING
+enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER,
+               POLL_REGISTER };
+#endif
+
 /*
  * Structure defining a network interface.
  *
@@ -173,6 +178,12 @@ struct ifnet {
                (void *);
        int     (*if_resolvemulti)      /* validate/resolve multicast */
                (struct ifnet *, struct sockaddr **, struct sockaddr *);
+#ifdef DEVICE_POLLING
+       void    (*if_poll)              /* IFF_POLLING support */
+               (struct ifnet *, enum poll_cmd, int);
+#else
+       void    (*if_poll_unused)(void); /* placeholder */
+#endif
        struct  ifaltq if_snd;          /* output queue (includes altq) */
        struct  ifprefixhead if_prefixhead; /* list of prefixes per if */
        const uint8_t   *if_broadcastaddr;
@@ -443,11 +454,9 @@ int        if_clone_destroy(const char *);
     LLADDR((struct sockaddr_dl *) ifnet_addrs[ifp->if_index - 1]->ifa_addr)
 
 #ifdef DEVICE_POLLING
-enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER };
-
 typedef        void poll_handler_t (struct ifnet *ifp,
                enum poll_cmd cmd, int count);
-int    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
+int    ether_poll_register(struct ifnet *ifp);
 int    ether_poll_deregister(struct ifnet *ifp);
 void   emergency_poll_enable(const char *name);
 #endif /* DEVICE_POLLING */
index af70f6f..254792e 100644 (file)
@@ -82,7 +82,7 @@
  *
  *     @(#)rtsock.c    8.7 (Berkeley) 10/12/95
  * $FreeBSD: src/sys/net/rtsock.c,v 1.44.2.11 2002/12/04 14:05:41 ru Exp $
- * $DragonFly: src/sys/net/rtsock.c,v 1.25 2005/04/18 23:50:30 hsu Exp $
+ * $DragonFly: src/sys/net/rtsock.c,v 1.26 2005/05/25 01:44:16 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -867,7 +867,7 @@ rt_ifmsg(struct ifnet *ifp)
                return;
        ifm = mtod(m, struct if_msghdr *);
        ifm->ifm_index = ifp->if_index;
-       ifm->ifm_flags = (u_short)ifp->if_flags;
+       ifm->ifm_flags = ifp->if_flags;
        ifm->ifm_data = ifp->if_data;
        ifm->ifm_addrs = 0;
        rts_input(m, 0);
@@ -1104,7 +1104,7 @@ sysctl_iflist(int af, struct walkarg *w)
                        struct if_msghdr *ifm = w->w_tmem;
 
                        ifm->ifm_index = ifp->if_index;
-                       ifm->ifm_flags = (u_short)ifp->if_flags;
+                       ifm->ifm_flags = ifp->if_flags;
                        ifm->ifm_data = ifp->if_data;
                        ifm->ifm_addrs = rtinfo.rti_addrs;
                        error = SYSCTL_OUT(w->w_req, ifm, msglen);
index 53e456d..71a14b8 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/i386/nexus.c,v 1.26.2.10 2003/02/22 13:16:45 imp Exp $
- * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.14 2005/05/24 20:59:05 dillon Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/nexus.c,v 1.15 2005/05/25 01:44:04 dillon Exp $
  */
 
 /*
@@ -538,15 +538,19 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
                mask = &cam_imask;
                break;
        case INTR_TYPE_CLK:
-               mask = 0;
+               mask = NULL;
                printf("nexus: Warning: do not know what imask to use for INTR_TYPE_CLK\n");
                break;
        case INTR_TYPE_MISC:
-               mask = 0;
+               mask = NULL;
                break;
        default:
                panic("still using grody create_intr interface");
        }
+       if (serializer && mask != NULL) {
+               device_printf(child, "nexus_setup_intr: Warning, driver must set interrupt type to INTR_TYPE_MISC when using a serializer.\n");
+               mask = NULL;
+       }
        if (flags & INTR_FAST)
                icflags |= INTR_FAST;