Skip site navigation (1)Skip section navigation (2)
Date:      Fri,  6 Jan 2006 02:29:22 +0000 (GMT)
From:      Nate Nielsen <nielsen-list@memberwebs.com>
To:        freebsd-hackers@freebsd.org
Subject:   Polling for devices other than NICs [patch]
Message-ID:  <20060106022920.BF7DADCA990@mail.npubs.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------070408040903010200010209
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

I've recently been optimizing the hifn driver for low performance
systems like the Soekris. I've implemented polling (rather than using
interrupts for everything) in the driver, which speeds things up
considerably.

The polling functionality in FreeBSD is currently a bit NIC centric.
With a few changes other types devices can use the polling subsystem.
Attached is my first whack at this.

This is some of my first hacking on the FreeBSD kernel. It'd be great if
there was someone who could take a look and help me get it right.

Cheers,
Nate

Note: The patch applies to RELENG_6_0. When necessary I can prepare a
patch against HEAD.


--------------070408040903010200010209
Content-Type: text/x-patch;
 name="device-polling.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="device-polling.patch"

? device-polling.patch
Index: dev/em/if_em.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v
retrieving revision 1.65.2.5.2.1
diff -p -U5 -r1.65.2.5.2.1 if_em.c
--- dev/em/if_em.c	22 Oct 2005 22:07:20 -0000	1.65.2.5.2.1
+++ dev/em/if_em.c	6 Jan 2006 01:37:28 -0000
@@ -716,19 +716,19 @@ em_ioctl(struct ifnet *ifp, u_long comma
 		reinit = 0;
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
-				error = ether_poll_register(em_poll, ifp);
+				error = device_poll_register(em_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				EM_LOCK(adapter);
 				em_disable_intr(adapter);
 				ifp->if_capenable |= IFCAP_POLLING;
 				EM_UNLOCK(adapter);
 			} else {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupt even in error case */
 				EM_LOCK(adapter);
 				em_enable_intr(adapter);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				EM_UNLOCK(adapter);
@@ -946,12 +946,13 @@ em_poll_locked(struct ifnet *ifp, enum p
         if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
                 em_start_locked(ifp);
 }
         
 static void     
-em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+em_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
         struct adapter *adapter = ifp->if_softc;
 
 	EM_LOCK(adapter);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		em_poll_locked(ifp, cmd, count);
Index: dev/firewire/if_fwe.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/firewire/if_fwe.c,v
retrieving revision 1.37.2.2
diff -p -U5 -r1.37.2.2 if_fwe.c
--- dev/firewire/if_fwe.c	7 Oct 2005 14:00:03 -0000	1.37.2.2
+++ dev/firewire/if_fwe.c	6 Jan 2006 01:37:28 -0000
@@ -104,12 +104,13 @@ TUNABLE_INT("hw.firewire.fwe.rx_queue_le
 
 #ifdef DEVICE_POLLING
 static poll_handler_t fwe_poll;
 
 static void
-fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+fwe_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct fwe_softc *fwe;
 	struct firewire_comm *fc;
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 		return;
@@ -290,11 +291,11 @@ fwe_detach(device_t dev)
 	fwe = device_get_softc(dev);
 	ifp = fwe->eth_softc.ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 	s = splimp();
 
 	fwe_stop(fwe);
 #if defined(__DragonFly__) || __FreeBSD_version < 500000
@@ -462,22 +463,22 @@ fwe_ioctl(struct ifnet *ifp, u_long cmd,
 			struct ifreq *ifr = (struct ifreq *) data;
 			struct firewire_comm *fc = fc = fwe->fd.fc;
 
 			if (ifr->ifr_reqcap & IFCAP_POLLING &&
 			    !(ifp->if_capenable & IFCAP_POLLING)) {
-				error = ether_poll_register(fwe_poll, ifp);
+				error = device_poll_register(fwe_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				/* Disable interrupts */
 				fc->set_intr(fc, 0);
 				ifp->if_capenable |= IFCAP_POLLING;
 				return (error);
 				
 			}
 			if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 			    ifp->if_capenable & IFCAP_POLLING) {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupts. */
 				fc->set_intr(fc, 1);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				return (error);
 			}
Index: dev/firewire/if_fwip.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/firewire/if_fwip.c,v
retrieving revision 1.7.2.3
diff -p -U5 -r1.7.2.3 if_fwip.c
--- dev/firewire/if_fwip.c	7 Oct 2005 14:00:03 -0000	1.7.2.3
+++ dev/firewire/if_fwip.c	6 Jan 2006 01:37:28 -0000
@@ -111,12 +111,13 @@ TUNABLE_INT("hw.firewire.fwip.rx_queue_l
 
 #ifdef DEVICE_POLLING
 static poll_handler_t fwip_poll;
 
 static void
-fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+fwip_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct fwip_softc *fwip;
 	struct firewire_comm *fc;
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 		return;
@@ -272,11 +273,11 @@ fwip_detach(device_t dev)
 	fwip = (struct fwip_softc *)device_get_softc(dev);
 	ifp = fwip->fw_softc.fwip_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	s = splimp();
 
 	fwip_stop(fwip);
@@ -444,22 +445,22 @@ fwip_ioctl(struct ifnet *ifp, u_long cmd
 		struct ifreq *ifr = (struct ifreq *) data;
 		struct firewire_comm *fc = fc = fwip->fd.fc;
 
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(fwip_poll, ifp);
+			error = device_poll_register(fwip_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			/* Disable interrupts */
 			fc->set_intr(fc, 0);
 			ifp->if_capenable |= IFCAP_POLLING;
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			fc->set_intr(fc, 1);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			return (error);
 		}
Index: dev/fxp/if_fxp.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/fxp/if_fxp.c,v
retrieving revision 1.240.2.5
diff -p -U5 -r1.240.2.5 if_fxp.c
--- dev/fxp/if_fxp.c	7 Oct 2005 14:00:03 -0000	1.240.2.5
+++ dev/fxp/if_fxp.c	6 Jan 2006 01:37:29 -0000
@@ -45,10 +45,11 @@ __FBSDID("$FreeBSD: src/sys/dev/fxp/if_f
 		/* #include <sys/mutex.h> */
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+#include <sys/bus.h>
 
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
 
@@ -896,11 +897,11 @@ fxp_detach(device_t dev)
 {
 	struct fxp_softc *sc = device_get_softc(dev);
 
 #ifdef DEVICE_POLLING
 	if (sc->ifp->if_capenable & IFCAP_POLLING)   
-		ether_poll_deregister(sc->ifp);
+		device_poll_deregister(sc->ifp, sc->ifp->if_xname);
 #endif
 
 	FXP_LOCK(sc);
 	sc->suspended = 1;	/* Do same thing as we do for suspend */
 	/*
@@ -1450,12 +1451,13 @@ fxp_encap(struct fxp_softc *sc, struct m
 
 #ifdef DEVICE_POLLING
 static poll_handler_t fxp_poll;
 
 static void
-fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+fxp_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct fxp_softc *sc = ifp->if_softc;
 	uint8_t statack;
 
 	FXP_LOCK(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
@@ -2415,20 +2417,20 @@ fxp_ioctl(struct ifnet *ifp, u_long comm
 	case SIOCSIFCAP:
 		mask = ifp->if_capenable ^ ifr->ifr_reqcap;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
-				error = ether_poll_register(fxp_poll, ifp);
+				error = device_poll_register(fxp_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				FXP_LOCK(sc);
 				CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,
 				    FXP_SCB_INTR_DISABLE);
 				ifp->if_capenable |= IFCAP_POLLING;
 				FXP_UNLOCK(sc);
 			} else {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupts in any case */
 				FXP_LOCK(sc);
 				CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				FXP_UNLOCK(sc);
Index: dev/ixgb/if_ixgb.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ixgb/if_ixgb.c,v
retrieving revision 1.10.2.4
diff -p -U5 -r1.10.2.4 if_ixgb.c
--- dev/ixgb/if_ixgb.c	7 Oct 2005 14:00:04 -0000	1.10.2.4
+++ dev/ixgb/if_ixgb.c	6 Jan 2006 01:37:29 -0000
@@ -375,11 +375,11 @@ ixgb_detach(device_t dev)
 
 	INIT_DEBUGOUT("ixgb_detach: begin");
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	IXGB_LOCK(adapter);
 	adapter->in_detach = 1;
 
@@ -569,19 +569,19 @@ ixgb_ioctl(struct ifnet * ifp, IOCTL_CMD
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
-				error = ether_poll_register(ixgb_poll, ifp);
+				error = device_poll_register(ixgb_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				IXGB_LOCK(adapter);
 				ixgb_disable_intr(adapter);
 				ifp->if_capenable |= IFCAP_POLLING;
 				IXGB_UNLOCK(adapter);
 			} else {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupt even in error case */
 				IXGB_LOCK(adapter);
 				ixgb_enable_intr(adapter);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				IXGB_UNLOCK(adapter);
@@ -771,12 +771,13 @@ ixgb_poll_locked(struct ifnet * ifp, enu
 	if (ifp->if_snd.ifq_head != NULL)
 		ixgb_start_locked(ifp);
 }
 
 static void
-ixgb_poll(struct ifnet * ifp, enum poll_cmd cmd, int count)
+ixgb_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct adapter *adapter = ifp->if_softc;
 
 	IXGB_LOCK(adapter);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		ixgb_poll_locked(ifp, cmd, count);
Index: dev/nge/if_nge.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/nge/if_nge.c,v
retrieving revision 1.75.2.3
diff -p -U5 -r1.75.2.3 if_nge.c
--- dev/nge/if_nge.c	7 Oct 2005 14:00:04 -0000	1.75.2.3
+++ dev/nge/if_nge.c	6 Jan 2006 01:37:29 -0000
@@ -959,11 +959,11 @@ nge_detach(dev)
 	sc = device_get_softc(dev);
 	ifp = sc->nge_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 	NGE_LOCK(sc);
 	nge_reset(sc);
 	nge_stop(sc);
 	NGE_UNLOCK(sc);
@@ -1374,12 +1374,13 @@ nge_tick_locked(sc)
 
 #ifdef DEVICE_POLLING
 static poll_handler_t nge_poll;
 
 static void
-nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+nge_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct  nge_softc *sc = ifp->if_softc;
 
 	NGE_LOCK(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		NGE_UNLOCK(sc);
@@ -2041,11 +2042,11 @@ nge_ioctl(ifp, command, data)
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(nge_poll, ifp);
+			error = device_poll_register(nge_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			NGE_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_4(sc, NGE_IER, 0);
@@ -2054,11 +2055,11 @@ nge_ioctl(ifp, command, data)
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			NGE_LOCK(sc);
 			CSR_WRITE_4(sc, NGE_IER, 1);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			NGE_UNLOCK(sc);
Index: dev/re/if_re.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/re/if_re.c,v
retrieving revision 1.46.2.7
diff -p -U5 -r1.46.2.7 if_re.c
--- dev/re/if_re.c	8 Oct 2005 07:35:10 -0000	1.46.2.7
+++ dev/re/if_re.c	6 Jan 2006 01:37:30 -0000
@@ -216,11 +216,11 @@ static __inline void re_fixup_rx
 				(struct mbuf *);
 #endif
 static void re_rxeof		(struct rl_softc *);
 static void re_txeof		(struct rl_softc *);
 #ifdef DEVICE_POLLING
-static void re_poll		(struct ifnet *, enum poll_cmd, int);
+static void re_poll		(void *arg, enum poll_cmd, int);
 static void re_poll_locked	(struct ifnet *, enum poll_cmd, int);
 #endif
 static void re_intr		(void *);
 static void re_tick		(void *);
 static void re_start		(struct ifnet *);
@@ -1268,11 +1268,11 @@ re_detach(dev)
 	ifp = sc->rl_ifp;
 	KASSERT(mtx_initialized(&sc->rl_mtx), ("re mutex not initialized"));
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		RL_LOCK(sc);
 #if 0
@@ -1757,12 +1757,13 @@ re_tick(xsc)
 	callout_reset(&sc->rl_stat_callout, hz, re_tick, sc);
 }
 
 #ifdef DEVICE_POLLING
 static void
-re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+re_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct rl_softc *sc = ifp->if_softc;
 
 	RL_LOCK(sc);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		re_poll_locked(ifp, cmd, count);
@@ -2316,21 +2317,21 @@ re_ioctl(ifp, command, data)
 	    {
 		int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
-				error = ether_poll_register(re_poll, ifp);
+				error = device_poll_register(re_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				RL_LOCK(sc);
 				/* Disable interrupts */
 				CSR_WRITE_2(sc, RL_IMR, 0x0000);
 				ifp->if_capenable |= IFCAP_POLLING;
 				RL_UNLOCK(sc);
 				
 			} else {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupts. */
 				RL_LOCK(sc);
 				CSR_WRITE_2(sc, RL_IMR, RL_INTRS_CPLUS);
 				ifp->if_capenable &= ~IFCAP_POLLING;
 				RL_UNLOCK(sc);
Index: dev/vge/if_vge.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/vge/if_vge.c,v
retrieving revision 1.14.2.4
diff -p -U5 -r1.14.2.4 if_vge.c
--- dev/vge/if_vge.c	9 Oct 2005 04:15:12 -0000	1.14.2.4
+++ dev/vge/if_vge.c	6 Jan 2006 01:37:30 -0000
@@ -1107,11 +1107,11 @@ vge_detach(dev)
 	KASSERT(mtx_initialized(&sc->vge_mtx), ("vge mutex not initialized"));
 	ifp = sc->vge_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		vge_stop(sc);
@@ -1617,12 +1617,13 @@ vge_tick(xsc)
 	return;
 }
 
 #ifdef DEVICE_POLLING
 static void
-vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count)
+vge_poll (void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct vge_softc *sc = ifp->if_softc;
 
 	VGE_LOCK(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 		goto done;
@@ -2256,21 +2257,21 @@ vge_ioctl(ifp, command, data)
 	    {
 		int mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 #ifdef DEVICE_POLLING
 		if (mask & IFCAP_POLLING) {
 			if (ifr->ifr_reqcap & IFCAP_POLLING) {
-				error = ether_poll_register(vge_poll, ifp);
+				error = device_poll_register(vge_poll, ifp, ifp->if_xname);
 				if (error)
 					return(error);
 				VGE_LOCK(sc);
 					/* Disable interrupts */
 				CSR_WRITE_4(sc, VGE_IMR, 0);
 				CSR_WRITE_1(sc, VGE_CRC3, VGE_CR3_INT_GMSK);
 				ifp->if_capenable |= IFCAP_POLLING;
 				VGE_UNLOCK(sc);
 			} else {
-				error = ether_poll_deregister(ifp);
+				error = device_poll_deregister(ifp, ifp->if_xname);
 				/* Enable interrupts. */
 				VGE_LOCK(sc);
 				CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS);
 				CSR_WRITE_4(sc, VGE_ISR, 0xFFFFFFFF);
 				CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK);
Index: kern/kern_poll.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_poll.c,v
retrieving revision 1.19.2.2
diff -p -U5 -r1.19.2.2 kern_poll.c
--- kern/kern_poll.c	7 Oct 2005 14:00:05 -0000	1.19.2.2
+++ kern/kern_poll.c	6 Jan 2006 01:37:30 -0000
@@ -35,10 +35,11 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_po
 #include <sys/kernel.h>
 #include <sys/socket.h>			/* needed by net/if.h		*/
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
+#include <sys/bus.h>
 
 #include <net/if.h>			/* for IFF_* flags		*/
 #include <net/netisr.h>			/* for NETISR_POLL		*/
 
 #include <sys/proc.h>
@@ -48,11 +49,11 @@ __FBSDID("$FreeBSD: src/sys/kern/kern_po
 static void netisr_poll(void);		/* the two netisr handlers      */
 static void netisr_pollmore(void);
 static int poll_switch(SYSCTL_HANDLER_ARGS);
 
 void hardclock_device_poll(void);	/* hook from hardclock		*/
-void ether_poll(int);			/* polling in idle loop		*/
+void device_poll(int);			/* polling in idle loop		*/
 
 static struct mtx	poll_mtx;
 
 /*
  * Polling support for [network] device drivers.
@@ -61,11 +62,12 @@ static struct mtx	poll_mtx;
  * polling code.
  *
  * If registration is successful, the driver must disable interrupts,
  * and further I/O is performed through the handler, which is invoked
  * (at least once per clock tick) with 3 arguments: the "arg" passed at
- * register time (a struct ifnet pointer), a command, and a "count" limit.
+ * register time (a softc, device, or ifnet pointer), a command, 
+ * and a "count" limit.
  *
  * The command can be one of the following:
  *  POLL_ONLY: quick move of "count" packets from input/output queues.
  *  POLL_AND_CHECK_STATUS: as above, plus check status registers or do
  *	other more expensive operations. This command is issued periodically
@@ -250,11 +252,11 @@ SYSCTL_UINT(_kern_polling, OID_AUTO, idl
 
 
 #define POLL_LIST_LEN  128
 struct pollrec {
 	poll_handler_t	*handler;
-	struct ifnet	*ifp;
+	void            *arg;
 };
 
 static struct pollrec pr[POLL_LIST_LEN];
 
 static void
@@ -320,25 +322,25 @@ hardclock_device_poll(void)
 	if (pending_polls++ > 0)
 		lost_polls++;
 }
 
 /*
- * ether_poll is called from the idle loop.
+ * device_poll is called from the idle loop.
  */
 void
-ether_poll(int count)
+device_poll(int count)
 {
 	int i;
 
 	NET_LOCK_GIANT();
 	mtx_lock(&poll_mtx);
 
 	if (count > poll_each_burst)
 		count = poll_each_burst;
 
 	for (i = 0 ; i < poll_handlers ; i++)
-		pr[i].handler(pr[i].ifp, POLL_ONLY, count);
+		pr[i].handler(pr[i].arg, POLL_ONLY, count);
 
 	mtx_unlock(&poll_mtx);
 	NET_UNLOCK_GIANT();
 }
 
@@ -433,30 +435,30 @@ netisr_poll(void)
 	cycles = (residual_burst < poll_each_burst) ?
 		residual_burst : poll_each_burst;
 	residual_burst -= cycles;
 
 	for (i = 0 ; i < poll_handlers ; i++)
-		pr[i].handler(pr[i].ifp, arg, cycles);
+		pr[i].handler(pr[i].arg, arg, cycles);
 
 	phase = 4;
 	mtx_unlock(&poll_mtx);
 }
 
 /*
  * Try to register routine for polling. Returns 0 if successful
  * (and polling should be enabled), error code otherwise.
  * A device is not supposed to register itself multiple times.
  *
- * This is called from within the *_ioctl() functions.
+ * This is called from within the interface *_ioctl() functions.
  */
 int
-ether_poll_register(poll_handler_t *h, struct ifnet *ifp)
+device_poll_register(poll_handler_t *h, void *arg, const char *devname)
 {
 	int i;
 
 	KASSERT(h != NULL, ("%s: handler is NULL", __func__));
-	KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+	KASSERT(arg != NULL, ("%s: arg is NULL", __func__));
 
 	NET_ASSERT_GIANT();
 
 	mtx_lock(&poll_mtx);
 	if (poll_handlers >= POLL_LIST_LEN) {
@@ -476,58 +478,73 @@ ether_poll_register(poll_handler_t *h, s
 		mtx_unlock(&poll_mtx);
 		return (ENOMEM); /* no polling for you */
 	}
 
 	for (i = 0 ; i < poll_handlers ; i++)
-		if (pr[i].ifp == ifp && pr[i].handler != NULL) {
+		if (pr[i].arg == arg && pr[i].handler != NULL) {
 			mtx_unlock(&poll_mtx);
-			log(LOG_DEBUG, "ether_poll_register: %s: handler"
-			    " already registered\n", ifp->if_xname);
+			log(LOG_DEBUG, "device_poll_register: %s: handler"
+			    " already registered\n", devname ? devname : "UNKNOWN");
 			return (EEXIST);
 		}
 
 	pr[poll_handlers].handler = h;
-	pr[poll_handlers].ifp = ifp;
+	pr[poll_handlers].arg = arg;
 	poll_handlers++;
 	mtx_unlock(&poll_mtx);
 	if (idlepoll_sleeping)
 		wakeup(&idlepoll_sleeping);
 	return (0);
 }
 
 /*
- * Remove interface from the polling list. Called from *_ioctl(), too.
+ * Remove device from the polling list. Called from *_ioctl(), too.
  */
 int
-ether_poll_deregister(struct ifnet *ifp)
+device_poll_deregister(void *arg, const char *devname)
 {
 	int i;
 
-	KASSERT(ifp != NULL, ("%s: ifp is NULL", __func__));
+	KASSERT(arg != NULL, ("%s: arg is NULL", __func__));
 
 	NET_ASSERT_GIANT();
 	mtx_lock(&poll_mtx);
 
 	for (i = 0 ; i < poll_handlers ; i++)
-		if (pr[i].ifp == ifp) /* found it */
+		if (pr[i].arg == arg) /* found it */
 			break;
 	if (i == poll_handlers) {
-		log(LOG_DEBUG, "ether_poll_deregister: %s: not found!\n",
-		    ifp->if_xname);
+		log(LOG_DEBUG, "device_poll_deregister: %s: not found!\n",
+		    devname ? devname : "UNKNOWN");
 		mtx_unlock(&poll_mtx);
 		return (ENOENT);
 	}
 	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;
+		pr[i].arg = pr[poll_handlers].arg;
 	}
 	mtx_unlock(&poll_mtx);
 	return (0);
 }
 
 /*
+ * Deprecated compatibility functions for external drivers.
+ */
+int
+ether_poll_register(void *h, struct ifnet *ifp)
+{
+        return device_poll_register((poll_handler_t*)h, ifp, ifp->if_xname);
+}
+
+int    
+ether_poll_deregister(struct ifnet *ifp)
+{
+        return device_poll_deregister(ifp, ifp->if_xname);
+}
+
+/*
  * Legacy interface for turning polling on all interfaces at one time.
  */
 static int
 poll_switch(SYSCTL_HANDLER_ARGS)
 {
@@ -565,11 +582,12 @@ poll_switch(SYSCTL_HANDLER_ARGS)
 		}
 	}
 	IFNET_RUNLOCK();
 	NET_UNLOCK_GIANT();
 
-	log(LOG_ERR, "kern.polling.enable is deprecated. Use ifconfig(8)");
+	log(LOG_ERR, "kern.polling.enable (which enables polling on all interfaces) "
+                        "is deprecated. Use ifconfig(8)");
 
 	return (0);
 }
 
 static void
@@ -587,11 +605,11 @@ poll_idle(void)
 	mtx_unlock_spin(&sched_lock);
 
 	for (;;) {
 		if (poll_in_idle_loop && poll_handlers > 0) {
 			idlepoll_sleeping = 0;
-			ether_poll(poll_each_burst);
+			device_poll(poll_each_burst);
 			mtx_lock_spin(&sched_lock);
 			mi_switch(SW_VOL, NULL);
 			mtx_unlock_spin(&sched_lock);
 		} else {
 			idlepoll_sleeping = 1;
Index: net/if_var.h
===================================================================
RCS file: /home/ncvs/src/sys/net/if_var.h,v
retrieving revision 1.98.2.5
diff -p -U5 -r1.98.2.5 if_var.h
--- net/if_var.h	7 Oct 2005 14:00:05 -0000	1.98.2.5
+++ net/if_var.h	6 Jan 2006 01:37:34 -0000
@@ -658,14 +658,12 @@ void	if_deregister_com_alloc(u_char type
 
 #define IF_LLADDR(ifp)							\
     LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
 
 #ifdef DEVICE_POLLING
-enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
-
-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);
+/* DEPRECATED: For compatibility only. Use device_poll_register/deregister */
+int    ether_poll_register(void*, struct ifnet *ifp);
 int    ether_poll_deregister(struct ifnet *ifp);
 #endif /* DEVICE_POLLING */
 
 #endif /* _KERNEL */
 
Index: pci/if_dc.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/Attic/if_dc.c,v
retrieving revision 1.160.2.6
diff -p -U5 -r1.160.2.6 if_dc.c
--- pci/if_dc.c	9 Oct 2005 04:11:19 -0000	1.160.2.6
+++ pci/if_dc.c	6 Jan 2006 01:37:34 -0000
@@ -2340,11 +2340,11 @@ dc_detach(device_t dev)
 
 	ifp = sc->dc_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		DC_LOCK(sc);
@@ -3038,12 +3038,13 @@ dc_tx_underrun(struct dc_softc *sc)
 
 #ifdef DEVICE_POLLING
 static poll_handler_t dc_poll;
 
 static void
-dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+dc_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct dc_softc *sc = ifp->if_softc;
 
 	DC_LOCK(sc);
 
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
@@ -3683,11 +3684,11 @@ dc_ioctl(struct ifnet *ifp, u_long comma
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(dc_poll, ifp);
+			error = device_poll_register(dc_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			DC_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_4(sc, DC_IMR, 0x00000000);
@@ -3696,11 +3697,11 @@ dc_ioctl(struct ifnet *ifp, u_long comma
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			DC_LOCK(sc);
 			CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			DC_UNLOCK(sc);
Index: pci/if_rl.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_rl.c,v
retrieving revision 1.152.2.4
diff -p -U5 -r1.152.2.4 if_rl.c
--- pci/if_rl.c	7 Oct 2005 14:00:06 -0000	1.152.2.4
+++ pci/if_rl.c	6 Jan 2006 01:37:34 -0000
@@ -197,11 +197,11 @@ static int rl_mii_readreg(struct rl_soft
 static int rl_mii_writereg(struct rl_softc *, struct rl_mii_frame *);
 static int rl_miibus_readreg(device_t, int, int);
 static void rl_miibus_statchg(device_t);
 static int rl_miibus_writereg(device_t, int, int, int);
 #ifdef DEVICE_POLLING
-static void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+static void rl_poll(void *arg, enum poll_cmd cmd, int count);
 static void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
 #endif
 static int rl_probe(device_t);
 static void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int);
 static void rl_reset(struct rl_softc *);
@@ -1003,11 +1003,11 @@ rl_detach(device_t dev)
 	ifp = sc->rl_ifp;
 
 	KASSERT(mtx_initialized(&sc->rl_mtx), ("rl mutex not initialized"));
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		RL_LOCK(sc);
 		rl_stop(sc);
@@ -1281,12 +1281,13 @@ rl_tick(void *xsc)
 	callout_reset(&sc->rl_stat_callout, hz, rl_tick, sc);
 }
 
 #ifdef DEVICE_POLLING
 static void
-rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+rl_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct rl_softc *sc = ifp->if_softc;
 
 	RL_LOCK(sc);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		rl_poll_locked(ifp, cmd, count);
@@ -1657,11 +1658,11 @@ rl_ioctl(struct ifnet *ifp, u_long comma
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(rl_poll, ifp);
+			error = device_poll_register(rl_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			RL_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_2(sc, RL_IMR, 0x0000);
@@ -1670,11 +1671,11 @@ rl_ioctl(struct ifnet *ifp, u_long comma
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			RL_LOCK(sc);
 			CSR_WRITE_2(sc, RL_IMR, RL_INTRS);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			RL_UNLOCK(sc);
Index: pci/if_sf.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_sf.c,v
retrieving revision 1.82.2.5
diff -p -U5 -r1.82.2.5 if_sf.c
--- pci/if_sf.c	9 Oct 2005 04:11:19 -0000	1.82.2.5
+++ pci/if_sf.c	6 Jan 2006 01:37:34 -0000
@@ -167,11 +167,11 @@ static u_int8_t sf_read_eeprom(struct sf
 
 static int sf_miibus_readreg(device_t, int, int);
 static int sf_miibus_writereg(device_t, int, int, int);
 static void sf_miibus_statchg(device_t);
 #ifdef DEVICE_POLLING
-static void sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+static void sf_poll(void *arg, enum poll_cmd cmd, int count);
 static void sf_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
 #endif
 
 static u_int32_t csr_read_4(struct sf_softc *, int);
 static void csr_write_4(struct sf_softc *, int, u_int32_t);
@@ -563,11 +563,11 @@ sf_ioctl(ifp, command, data)
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(sf_poll, ifp);
+			error = device_poll_register(sf_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			SF_LOCK(sc);
 			/* Disable interrupts */
 			csr_write_4(sc, SF_IMR, 0x00000000);
@@ -576,11 +576,11 @@ sf_ioctl(ifp, command, data)
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			SF_LOCK(sc);
 			csr_write_4(sc, SF_IMR, SF_INTRS);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			SF_UNLOCK(sc);
@@ -817,11 +817,11 @@ sf_detach(dev)
 	KASSERT(mtx_initialized(&sc->sf_mtx), ("sf mutex not initialized"));
 	ifp = sc->sf_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 	
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		SF_LOCK(sc);
@@ -1089,12 +1089,13 @@ sf_txthresh_adjust(sc)
 	}
 }
 
 #ifdef DEVICE_POLLING
 static void
-sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+sf_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct sf_softc *sc = ifp->if_softc;
 
 	SF_LOCK(sc);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		sf_poll_locked(ifp, cmd, count);
Index: pci/if_sis.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_sis.c,v
retrieving revision 1.132.2.6
diff -p -U5 -r1.132.2.6 if_sis.c
--- pci/if_sis.c	9 Oct 2005 04:11:19 -0000	1.132.2.6
+++ pci/if_sis.c	6 Jan 2006 01:37:34 -0000
@@ -1262,11 +1262,11 @@ sis_detach(device_t dev)
 	KASSERT(mtx_initialized(&sc->sis_mtx), ("sis mutex not initialized"));
 	ifp = sc->sis_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	/* These should only be active if attach succeeded. */
 	if (device_is_attached(dev)) {
 		SIS_LOCK(sc);
@@ -1580,12 +1580,13 @@ 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)
+sis_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct	sis_softc *sc = ifp->if_softc;
 
 	SIS_LOCK(sc);
 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 		SIS_UNLOCK(sc);
@@ -2138,11 +2139,11 @@ sis_ioctl(struct ifnet *ifp, u_long comm
 	case SIOCSIFCAP:
 		/* ok, disable interrupts */
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(sis_poll, ifp);
+			error = device_poll_register(sis_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			SIS_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_4(sc, SIS_IER, 0);
@@ -2151,11 +2152,11 @@ sis_ioctl(struct ifnet *ifp, u_long comm
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			SIS_LOCK(sc);
 			CSR_WRITE_4(sc, SIS_IER, 1);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			SIS_UNLOCK(sc);
Index: pci/if_ste.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_ste.c,v
retrieving revision 1.84.2.6
diff -p -U5 -r1.84.2.6 if_ste.c
--- pci/if_ste.c	9 Oct 2005 04:11:19 -0000	1.84.2.6
+++ pci/if_ste.c	6 Jan 2006 01:37:34 -0000
@@ -615,22 +615,11 @@ ste_setmulti(sc)
 
 	return;
 }
 
 #ifdef DEVICE_POLLING
-static poll_handler_t ste_poll, ste_poll_locked;
-
-static void
-ste_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
-	struct ste_softc *sc = ifp->if_softc;
-
-	STE_LOCK(sc);
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-		ste_poll_locked(ifp, cmd, count);
-	STE_UNLOCK(sc);
-}
+static poll_handler_t ste_poll;
 
 static void
 ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct ste_softc *sc = ifp->if_softc;
@@ -665,10 +654,23 @@ ste_poll_locked(struct ifnet *ifp, enum 
 			ste_reset(sc);
 			ste_init_locked(sc);
 		}
 	}
 }
+
+static void
+ste_poll(void *arg, enum poll_cmd cmd, int count)
+{
+	struct ifnet *ifp = arg;
+	struct ste_softc *sc = ifp->if_softc;
+
+	STE_LOCK(sc);
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+		ste_poll_locked(ifp, cmd, count);
+	STE_UNLOCK(sc);
+}
+
 #endif /* DEVICE_POLLING */
 
 static void
 ste_intr(xsc)
 	void			*xsc;
@@ -1145,11 +1147,11 @@ ste_detach(dev)
 	KASSERT(mtx_initialized(&sc->ste_mtx), ("ste mutex not initialized"));
 	ifp = sc->ste_ifp;
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	/* These should only be active if attach succeeded */
 	if (device_is_attached(dev)) {
 		STE_LOCK(sc);
@@ -1532,11 +1534,11 @@ ste_ioctl(ifp, command, data)
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(ste_poll, ifp);
+			error = device_poll_register(ste_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			STE_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_2(sc, STE_IMR, 0);
@@ -1545,11 +1547,11 @@ ste_ioctl(ifp, command, data)
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			STE_LOCK(sc);
 			CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			STE_UNLOCK(sc);
Index: pci/if_vr.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_vr.c,v
retrieving revision 1.104.2.4
diff -p -U5 -r1.104.2.4 if_vr.c
--- pci/if_vr.c	9 Oct 2005 04:11:20 -0000	1.104.2.4
+++ pci/if_vr.c	6 Jan 2006 01:37:34 -0000
@@ -798,11 +798,11 @@ vr_detach(device_t dev)
 
 	KASSERT(mtx_initialized(&sc->vr_mtx), ("vr mutex not initialized"));
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	VR_LOCK(sc);
 
 	sc->suspended = 1;
@@ -1150,22 +1150,10 @@ vr_tick(void *xsc)
 	VR_UNLOCK(sc);
 }
 
 #ifdef DEVICE_POLLING
 static poll_handler_t vr_poll;
-static poll_handler_t vr_poll_locked;
-
-static void
-vr_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
-	struct vr_softc *sc = ifp->if_softc;
-
-	VR_LOCK(sc);
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-		vr_poll_locked(ifp, cmd, count);
-	VR_UNLOCK(sc);
-}
 
 static void
 vr_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 {
 	struct vr_softc *sc = ifp->if_softc;
@@ -1224,10 +1212,23 @@ vr_poll_locked(struct ifnet *ifp, enum p
 				VR_SETBIT16(sc, VR_COMMAND, VR_CMD_TX_GO);
 			}
 		}
 	}
 }
+
+static void
+vr_poll(void *arg, enum poll_cmd cmd, int count)
+{
+	struct ifnet *ifp = arg;
+	struct vr_softc *sc = ifp->if_softc;
+
+	VR_LOCK(sc);
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+		vr_poll_locked(ifp, cmd, count);
+	VR_UNLOCK(sc);
+}
+
 #endif /* DEVICE_POLLING */
 
 static void
 vr_intr(void *arg)
 {
@@ -1607,11 +1608,11 @@ vr_ioctl(struct ifnet *ifp, u_long comma
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(vr_poll, ifp);
+			error = device_poll_register(vr_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			VR_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_2(sc, VR_IMR, 0x0000);
@@ -1620,11 +1621,11 @@ vr_ioctl(struct ifnet *ifp, u_long comma
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			VR_LOCK(sc);
 			CSR_WRITE_2(sc, VR_IMR, VR_INTRS);
 			ifp->if_capenable &= ~IFCAP_POLLING;
 			VR_UNLOCK(sc);
Index: pci/if_xl.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_xl.c,v
retrieving revision 1.190.2.6
diff -p -U5 -r1.190.2.6 if_xl.c
--- pci/if_xl.c	9 Oct 2005 04:11:20 -0000	1.190.2.6
+++ pci/if_xl.c	6 Jan 2006 01:37:34 -0000
@@ -249,11 +249,11 @@ static void xl_watchdog(struct ifnet *);
 static void xl_shutdown(device_t);
 static int xl_suspend(device_t);
 static int xl_resume(device_t);
 
 #ifdef DEVICE_POLLING
-static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
+static void xl_poll(void *arg, enum poll_cmd cmd, int count);
 static void xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
 #endif
 
 static int xl_ifmedia_upd(struct ifnet *);
 static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -1689,11 +1689,11 @@ xl_detach(device_t dev)
 
 	KASSERT(mtx_initialized(&sc->xl_mtx), ("xl mutex not initialized"));
 
 #ifdef DEVICE_POLLING
 	if (ifp->if_capenable & IFCAP_POLLING)
-		ether_poll_deregister(ifp);
+		device_poll_deregister(ifp, ifp->if_xname);
 #endif
 
 	if (sc->xl_flags & XL_FLAG_USE_MMIO) {
 		rid = XL_PCI_LOMEM;
 		res = SYS_RES_MEMORY;
@@ -2335,12 +2335,13 @@ xl_intr(void *arg)
 	XL_UNLOCK(sc);
 }
 
 #ifdef DEVICE_POLLING
 static void
-xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+xl_poll(void *arg, enum poll_cmd cmd, int count)
 {
+	struct ifnet *ifp = arg;
 	struct xl_softc *sc = ifp->if_softc;
 
 	XL_LOCK(sc);
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 		xl_poll_locked(ifp, cmd, count);
@@ -3182,11 +3183,11 @@ xl_ioctl(struct ifnet *ifp, u_long comma
 		break;
 	case SIOCSIFCAP:
 #ifdef DEVICE_POLLING
 		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 		    !(ifp->if_capenable & IFCAP_POLLING)) {
-			error = ether_poll_register(xl_poll, ifp);
+			error = device_poll_register(xl_poll, ifp, ifp->if_xname);
 			if (error)
 				return(error);
 			XL_LOCK(sc);
 			/* Disable interrupts */
 			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
@@ -3195,11 +3196,11 @@ xl_ioctl(struct ifnet *ifp, u_long comma
 			return (error);
 			
 		}
 		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 		    ifp->if_capenable & IFCAP_POLLING) {
-			error = ether_poll_deregister(ifp);
+			error = device_poll_deregister(ifp, ifp->if_xname);
 			/* Enable interrupts. */
 			XL_LOCK(sc);
 			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
 			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
 			if (sc->xl_flags & XL_FLAG_FUNCREG)
Index: sys/bus.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/bus.h,v
retrieving revision 1.70
diff -p -U5 -r1.70 bus.h
--- sys/bus.h	12 Apr 2005 15:20:36 -0000	1.70
+++ sys/bus.h	6 Jan 2006 01:37:34 -0000
@@ -453,10 +453,20 @@ void	bus_data_generation_update(void);
 /**
  * Shorthand for constructing method tables.
  */
 #define	DEVMETHOD	KOBJMETHOD
 
+/* Device polling functionality */
+#ifdef DEVICE_POLLING
+
+enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
+typedef	void poll_handler_t(void *arg, enum poll_cmd cmd, int count);
+int    device_poll_register(poll_handler_t *h, void *arg, const char *devname);
+int    device_poll_deregister(void *arg, const char *devname);
+
+#endif /* DEVICE_POLLING */
+
 /*
  * Some common device interfaces.
  */
 #include "device_if.h"
 #include "bus_if.h"

--------------070408040903010200010209--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060106022920.BF7DADCA990>