Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Oct 2011 01:13:47 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r226921 - in stable/8/sys/dev: cm ep fatm malo mwl sn ti vx
Message-ID:  <201110300113.p9U1DlFX041217@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Sun Oct 30 01:13:47 2011
New Revision: 226921
URL: http://svn.freebsd.org/changeset/base/226921

Log:
  MFC: r199559
  
  - Add a private timer to drive the transmit watchdog instead of using
    if_watchdog and if_timer.
  - Fix some issues in detach for sn(4), ste(4), and ti(4).  Primarily this
    means calling ether_ifdetach() before anything else.

Modified:
  stable/8/sys/dev/cm/smc90cx6.c
  stable/8/sys/dev/cm/smc90cx6var.h
  stable/8/sys/dev/ep/if_ep.c
  stable/8/sys/dev/ep/if_epvar.h
  stable/8/sys/dev/fatm/if_fatm.c
  stable/8/sys/dev/fatm/if_fatmvar.h
  stable/8/sys/dev/malo/if_malo.c
  stable/8/sys/dev/malo/if_malo.h
  stable/8/sys/dev/mwl/if_mwl.c
  stable/8/sys/dev/mwl/if_mwlvar.h
  stable/8/sys/dev/sn/if_sn.c
  stable/8/sys/dev/sn/if_snvar.h
  stable/8/sys/dev/ti/if_ti.c
  stable/8/sys/dev/ti/if_tireg.h
  stable/8/sys/dev/vx/if_vx.c
  stable/8/sys/dev/vx/if_vxvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/cm/smc90cx6.c
==============================================================================
--- stable/8/sys/dev/cm/smc90cx6.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/cm/smc90cx6.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -124,7 +124,7 @@ static void cm_reset_locked(struct cm_so
 void	cm_start(struct ifnet *);
 void	cm_start_locked(struct ifnet *);
 int	cm_ioctl(struct ifnet *, unsigned long, caddr_t);
-void	cm_watchdog(struct ifnet *);
+void	cm_watchdog(void *);
 void	cm_srint_locked(void *vsc);
 static	void cm_tint_locked(struct cm_softc *, int);
 void	cm_reconwatch_locked(void *);
@@ -194,11 +194,9 @@ cm_attach(dev)
 	ifp->if_output = arc_output;
 	ifp->if_start = cm_start;
 	ifp->if_ioctl = cm_ioctl;
-	ifp->if_watchdog  = cm_watchdog;
 	ifp->if_init = cm_init;
 	/* XXX IFQ_SET_READY(&ifp->if_snd); */
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
-	ifp->if_timer = 0;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
 
 	arc_ifattach(ifp, linkaddress);
@@ -210,6 +208,7 @@ cm_attach(dev)
 #endif
 
 	callout_init_mtx(&sc->sc_recon_ch, &sc->sc_mtx, 0);
+	callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
 
 	if_printf(ifp, "link addr 0x%02x (%d)\n", linkaddress, linkaddress);
 	return 0;
@@ -315,6 +314,7 @@ cm_reset_locked(sc)
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 
+	callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
 	cm_start_locked(ifp);
 }
 
@@ -332,7 +332,8 @@ cm_stop_locked(sc)
 	GETREG(CMRESET);
 
 	/* Stop watchdog timer */
-	sc->sc_ifp->if_timer = 0;
+	callout_stop(&sc->sc_watchdog_timer);
+	sc->sc_timer = 0;
 }
 
 void
@@ -464,7 +465,7 @@ cm_start_locked(ifp)
 		PUTREG(CMCMD, CM_TX(buffer));
 		PUTREG(CMSTAT, sc->sc_intmask);
 
-		ifp->if_timer = ARCTIMEOUT;
+		sc->sc_timer = ARCTIMEOUT;
 	}
 	m_freem(m);
 
@@ -627,7 +628,7 @@ cm_tint_locked(sc, isr)
 	if (isr & CM_TMA || sc->sc_broadcast[buffer])
 		ifp->if_opackets++;
 #ifdef CMRETRANSMIT
-	else if (ifp->if_flags & IFF_LINK2 && ifp->if_timer > 0
+	else if (ifp->if_flags & IFF_LINK2 && sc->sc_timer > 0
 	    && --sc->sc_retransmits[buffer] > 0) {
 		/* retransmit same buffer */
 		PUTREG(CMCMD, CM_TX(buffer));
@@ -657,7 +658,7 @@ cm_tint_locked(sc, isr)
 		 */
 		PUTREG(CMCMD, CM_TX(buffer));
 		/* init watchdog timer */
-		ifp->if_timer = ARCTIMEOUT;
+		sc->sc_timer = ARCTIMEOUT;
 
 #if defined(CM_DEBUG) && (CM_DEBUG > 1)
 		if_printf(ifp,
@@ -669,7 +670,7 @@ cm_tint_locked(sc, isr)
 		sc->sc_intmask &= ~CM_TA;
 		PUTREG(CMSTAT, sc->sc_intmask);
 		/* ... and watchdog timer */
-		ifp->if_timer = 0;
+		sc->sc_timer = 0;
 
 #ifdef CM_DEBUG
 		if_printf(ifp, "tint: no more buffers to send, status 0x%02x\n",
@@ -920,12 +921,13 @@ cm_ioctl(ifp, command, data)
  * retransmission is implemented).
  */
 void
-cm_watchdog(ifp)
-	struct ifnet *ifp;
+cm_watchdog(void *arg)
 {
-	struct cm_softc *sc = ifp->if_softc;
+	struct cm_softc *sc;
 
-	CM_LOCK(sc);
+	sc = arg;
+	callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
+	if (sc->sc_timer == 0 || --sc->sc_timer > 0)
+		return;
 	PUTREG(CMCMD, CM_TXDIS);
-	CM_UNLOCK(sc);
 }

Modified: stable/8/sys/dev/cm/smc90cx6var.h
==============================================================================
--- stable/8/sys/dev/cm/smc90cx6var.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/cm/smc90cx6var.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -77,6 +77,8 @@ struct cm_softc {
 	u_long	sc_reconcount_excessive; /* for the above */
 #define ARC_EXCESSIVE_RECONS 20
 #define ARC_EXCESSIVE_RECONS_REWARN 400
+	struct callout sc_watchdog_timer;
+	int	sc_timer;
 	u_char	sc_intmask;
 	u_char	sc_rx_act;		/* 2..3 */
 	u_char	sc_tx_act;		/* 0..1 */

Modified: stable/8/sys/dev/ep/if_ep.c
==============================================================================
--- stable/8/sys/dev/ep/if_ep.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/ep/if_ep.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/kernel.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
@@ -91,10 +92,12 @@ static int ep_media2if_media[] =
 static void epinit(void *);
 static int epioctl(struct ifnet *, u_long, caddr_t);
 static void epstart(struct ifnet *);
-static void epwatchdog(struct ifnet *);
 
+static void ep_intr_locked(struct ep_softc *);
 static void epstart_locked(struct ifnet *);
 static void epinit_locked(struct ep_softc *);
+static void eptick(void *);
+static void epwatchdog(struct ep_softc *);
 
 /* if_media functions */
 static int ep_ifmedia_upd(struct ifnet *);
@@ -302,12 +305,12 @@ ep_attach(struct ep_softc *sc)
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_start = epstart;
 	ifp->if_ioctl = epioctl;
-	ifp->if_watchdog = epwatchdog;
 	ifp->if_init = epinit;
 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
 	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
 	IFQ_SET_READY(&ifp->if_snd);
 
+	callout_init_mtx(&sc->watchdog_timer, &sc->sc_mtx, 0);
 	if (!sc->epb.mii_trans) {
 		ifmedia_init(&sc->ifmedia, 0, ep_ifmedia_upd, ep_ifmedia_sts);
 
@@ -361,6 +364,7 @@ ep_detach(device_t dev)
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	EP_UNLOCK(sc);
 	ether_ifdetach(ifp);
+	callout_drain(&sc->watchdog_timer);
 	ep_free(dev);
 
 	if_free(ifp);
@@ -457,6 +461,7 @@ epinit_locked(struct ep_softc *sc)
 
 	GO_WINDOW(sc, 1);
 	epstart_locked(ifp);
+	callout_reset(&sc->watchdog_timer, hz, eptick, sc);
 }
 
 static void
@@ -556,7 +561,7 @@ startagain:
 
 	BPF_MTAP(ifp, m0);
 
-	ifp->if_timer = 2;
+	sc->tx_timer = 2;
 	ifp->if_opackets++;
 	m_freem(m0);
 
@@ -583,20 +588,26 @@ void
 ep_intr(void *arg)
 {
 	struct ep_softc *sc;
-	int status;
-	struct ifnet *ifp;
 
 	sc = (struct ep_softc *) arg;
 	EP_LOCK(sc);
+	ep_intr_locked(sc);
+	EP_UNLOCK(sc);
+}
+
+static void
+ep_intr_locked(struct ep_softc *sc)
+{
+	int status;
+	struct ifnet *ifp;
+
 	/* XXX 4.x splbio'd here to reduce interruptability */
 
 	/*
 	 * quick fix: Try to detect an interrupt when the card goes away.
 	 */
-	if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff) {
-		EP_UNLOCK(sc);
+	if (sc->gone || CSR_READ_2(sc, EP_STATUS) == 0xffff)
 		return;
-	}
 	ifp = sc->ifp;
 
 	CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);	/* disable all Ints */
@@ -612,14 +623,14 @@ rescan:
 			epread(sc);
 		if (status & S_TX_AVAIL) {
 			/* we need ACK */
-			ifp->if_timer = 0;
+			sc->tx_timer = 0;
 			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 			GO_WINDOW(sc, 1);
 			CSR_READ_2(sc, EP_W1_FREE_TX);
 			epstart_locked(ifp);
 		}
 		if (status & S_CARD_FAILURE) {
-			ifp->if_timer = 0;
+			sc->tx_timer = 0;
 #ifdef EP_LOCAL_STATS
 			device_printf(sc->dev, "\n\tStatus: %x\n", status);
 			GO_WINDOW(sc, 4);
@@ -642,11 +653,10 @@ rescan:
 
 #endif
 			epinit_locked(sc);
-			EP_UNLOCK(sc);
 			return;
 		}
 		if (status & S_TX_COMPLETE) {
-			ifp->if_timer = 0;
+			sc->tx_timer = 0;
 			/*
 			 * We need ACK. We do it at the end.
 			 *
@@ -701,7 +711,6 @@ rescan:
 
 	/* re-enable Ints */
 	CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS);
-	EP_UNLOCK(sc);
 }
 
 static void
@@ -934,7 +943,6 @@ epioctl(struct ifnet *ifp, u_long cmd, c
 		EP_LOCK(sc);
 		if (((ifp->if_flags & IFF_UP) == 0) &&
 		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			epstop(sc);
 		} else
 			/* reinitialize card on any parameter change */
@@ -967,15 +975,27 @@ epioctl(struct ifnet *ifp, u_long cmd, c
 }
 
 static void
-epwatchdog(struct ifnet *ifp)
+eptick(void *arg)
 {
-	struct ep_softc *sc = ifp->if_softc;
+	struct ep_softc *sc;
+
+	sc = arg;
+	if (sc->tx_timer != 0 && --sc->tx_timer == 0)
+		epwatchdog(sc);
+	callout_reset(&sc->watchdog_timer, hz, eptick, sc);
+}
+
+static void
+epwatchdog(struct ep_softc *sc)
+{
+	struct ifnet *ifp;
 
+	ifp = sc->ifp;
 	if (sc->gone)
 		return;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	epstart(ifp);
-	ep_intr(ifp->if_softc);
+	epstart_locked(ifp);
+	ep_intr_locked(sc);
 }
 
 static void
@@ -998,4 +1018,7 @@ epstop(struct ep_softc *sc)
 	CSR_WRITE_2(sc, EP_COMMAND, SET_RD_0_MASK);
 	CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK);
 	CSR_WRITE_2(sc, EP_COMMAND, SET_RX_FILTER);
+
+	sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	callout_stop(&sc->watchdog_timer);
 }

Modified: stable/8/sys/dev/ep/if_epvar.h
==============================================================================
--- stable/8/sys/dev/ep/if_epvar.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/ep/if_epvar.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -45,6 +45,9 @@ struct ep_softc {
 	bus_space_tag_t bst;
 	void *ep_intrhand;
 
+	struct callout watchdog_timer;
+	int tx_timer;
+
 	u_short ep_connectors;	/* Connectors on this card. */
 	u_char ep_connector;	/* Configured connector. */
 

Modified: stable/8/sys/dev/fatm/if_fatm.c
==============================================================================
--- stable/8/sys/dev/fatm/if_fatm.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/fatm/if_fatm.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -391,16 +391,14 @@ fatm_check_heartbeat(struct fatm_softc *
  * Ensure that the heart is still beating.
  */
 static void
-fatm_watchdog(struct ifnet *ifp)
+fatm_watchdog(void *arg)
 {
-	struct fatm_softc *sc = ifp->if_softc;
+	struct fatm_softc *sc;
 
-	FATM_LOCK(sc);
-	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-		fatm_check_heartbeat(sc);
-		ifp->if_timer = 5;
-	}
-	FATM_UNLOCK(sc);
+	sc = arg;
+	FATM_CHECKLOCK(sc);
+	fatm_check_heartbeat(sc);
+	callout_reset(&sc->watchdog_timer, hz * 5, fatm_watchdog, sc);
 }
 
 /*
@@ -474,7 +472,7 @@ fatm_stop(struct fatm_softc *sc)
 	(void)fatm_reset(sc);
 
 	/* stop watchdog */
-	sc->ifp->if_timer = 0;
+	callout_stop(&sc->watchdog_timer);
 
 	if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		sc->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
@@ -1341,7 +1339,7 @@ fatm_init_locked(struct fatm_softc *sc)
 	/*
 	 * Start the watchdog timer
 	 */
-	sc->ifp->if_timer = 5;
+	callout_reset(&sc->watchdog_timer, hz * 5, fatm_watchdog, sc);
 
 	/* start SUNI */
 	utopia_start(&sc->utopia);
@@ -2543,6 +2541,7 @@ fatm_detach(device_t dev)
 		FATM_UNLOCK(sc);
 		atm_ifdetach(sc->ifp);		/* XXX race */
 	}
+	callout_drain(&sc->watchdog_timer);
 
 	if (sc->ih != NULL)
 		bus_teardown_intr(dev, sc->irqres, sc->ih);
@@ -2784,6 +2783,7 @@ fatm_attach(device_t dev)
 	cv_init(&sc->cv_regs, "fatm_regs");
 
 	sysctl_ctx_init(&sc->sysctl_ctx);
+	callout_init_mtx(&sc->watchdog_timer, &sc->mtx, 0);
 
 	/*
 	 * Make the sysctl tree
@@ -2824,7 +2824,6 @@ fatm_attach(device_t dev)
 	ifp->if_flags = IFF_SIMPLEX;
 	ifp->if_ioctl = fatm_ioctl;
 	ifp->if_start = fatm_start;
-	ifp->if_watchdog = fatm_watchdog;
 	ifp->if_init = fatm_init;
 	ifp->if_linkmib = &IFP2IFATM(sc->ifp)->mib;
 	ifp->if_linkmiblen = sizeof(IFP2IFATM(sc->ifp)->mib);

Modified: stable/8/sys/dev/fatm/if_fatmvar.h
==============================================================================
--- stable/8/sys/dev/fatm/if_fatmvar.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/fatm/if_fatmvar.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -188,6 +188,7 @@ struct fatm_softc {
 	struct ifnet	*ifp;		/* common part */
 	struct mtx	mtx;		/* lock this structure */
 	struct ifmedia	media;		/* media */
+	struct callout	watchdog_timer;
 
 	int		init_state;	/* initialisation step */
 	int		memid;		/* resource id for card memory */

Modified: stable/8/sys/dev/malo/if_malo.c
==============================================================================
--- stable/8/sys/dev/malo/if_malo.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/malo/if_malo.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -135,7 +135,7 @@ static	int	malo_setup_hwdma(struct malo_
 static	void	malo_txq_init(struct malo_softc *, struct malo_txq *, int);
 static	void	malo_tx_cleanupq(struct malo_softc *, struct malo_txq *);
 static	void	malo_start(struct ifnet *);
-static	void	malo_watchdog(struct ifnet *);
+static	void	malo_watchdog(void *);
 static	int	malo_ioctl(struct ifnet *, u_long, caddr_t);
 static	void	malo_updateslot(struct ifnet *);
 static	int	malo_newstate(struct ieee80211vap *, enum ieee80211_state, int);
@@ -191,6 +191,7 @@ malo_attach(uint16_t devid, struct malo_
 	ic = ifp->if_l2com;
 
 	MALO_LOCK_INIT(sc);
+	callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0);
 
 	/* set these up early for if_printf use */
 	if_initname(ifp, device_get_name(sc->malo_dev),
@@ -272,7 +273,6 @@ malo_attach(uint16_t devid, struct malo_
 	ifp->if_softc = sc;
 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
 	ifp->if_start = malo_start;
-	ifp->if_watchdog = malo_watchdog;
 	ifp->if_ioctl = malo_ioctl;
 	ifp->if_init = malo_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
@@ -1076,7 +1076,7 @@ malo_tx_proc(void *arg, int npending)
 
 	if (nreaped != 0) {
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		ifp->if_timer = 0;
+		sc->malo_timer = 0;
 		malo_start(ifp);
 	}
 }
@@ -1260,7 +1260,7 @@ malo_tx_start(struct malo_softc *sc, str
 	MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	ifp->if_opackets++;
-	ifp->if_timer = 5;
+	sc->malo_timer = 5;
 	MALO_TXQ_UNLOCK(txq);
 	return 0;
 #undef IEEE80211_DIR_DSTODS
@@ -1339,10 +1339,17 @@ malo_start(struct ifnet *ifp)
 }
 
 static void
-malo_watchdog(struct ifnet *ifp)
+malo_watchdog(void *arg)
 {
-	struct malo_softc *sc = ifp->if_softc;
+	struct malo_softc *sc;
+	struct ifnet *ifp;
+
+	sc = arg;
+	callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
+	if (sc->malo_timer == 0 || --sc->malo_timer > 0)
+		return;
 
+	ifp = sc->malo_ifp;
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) {
 		if_printf(ifp, "watchdog timeout\n");
 
@@ -1536,6 +1543,7 @@ malo_init_locked(struct malo_softc *sc)
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	malo_hal_intrset(mh, sc->malo_imask);
+	callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc);
 }
 
 static void
@@ -1699,7 +1707,8 @@ malo_stop_locked(struct ifnet *ifp, int 
 	 * is gone (invalid).
 	 */
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-	ifp->if_timer = 0;
+	callout_stop(&sc->malo_watchdog_timer);
+	sc->malo_timer = 0;
 	/* diable interrupt.  */
 	malo_hal_intrset(mh, 0);
 	/* turn off the radio.  */
@@ -2241,6 +2250,7 @@ malo_detach(struct malo_softc *sc)
 	 * Other than that, it's straightforward...
 	 */
 	ieee80211_ifdetach(ic);
+	callout_drain(&sc->malo_watchdog_timer);
 	malo_dma_cleanup(sc);
 	malo_tx_cleanup(sc);
 	malo_hal_detach(sc->malo_mh);

Modified: stable/8/sys/dev/malo/if_malo.h
==============================================================================
--- stable/8/sys/dev/malo/if_malo.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/malo/if_malo.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -550,6 +550,8 @@ struct malo_softc {
 
 	struct malo_txq		malo_txq[MALO_NUM_TX_QUEUES];
 	struct task		malo_txtask;	/* tx int processing */
+	struct callout	malo_watchdog_timer;
+	int			malo_timer;
 
 	struct malo_tx_radiotap_header malo_tx_th;
 	struct malo_rx_radiotap_header malo_rx_th;

Modified: stable/8/sys/dev/mwl/if_mwl.c
==============================================================================
--- stable/8/sys/dev/mwl/if_mwl.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/mwl/if_mwl.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -98,7 +98,7 @@ static void	mwl_start(struct ifnet *);
 static int	mwl_raw_xmit(struct ieee80211_node *, struct mbuf *,
 			const struct ieee80211_bpf_params *);
 static int	mwl_media_change(struct ifnet *);
-static void	mwl_watchdog(struct ifnet *);
+static void	mwl_watchdog(void *);
 static int	mwl_ioctl(struct ifnet *, u_long, caddr_t);
 static void	mwl_radar_proc(void *, int);
 static void	mwl_chanswitch_proc(void *, int);
@@ -360,6 +360,7 @@ mwl_attach(uint16_t devid, struct mwl_so
 		goto bad1;
 
 	callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
+	callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
 
 	sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT,
 		taskqueue_thread_enqueue, &sc->sc_tq);
@@ -401,7 +402,6 @@ mwl_attach(uint16_t devid, struct mwl_so
 	ifp->if_softc = sc;
 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
 	ifp->if_start = mwl_start;
-	ifp->if_watchdog = mwl_watchdog;
 	ifp->if_ioctl = mwl_ioctl;
 	ifp->if_init = mwl_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
@@ -558,6 +558,7 @@ mwl_detach(struct mwl_softc *sc)
 	 * Other than that, it's straightforward...
 	 */
 	ieee80211_ifdetach(ic);
+	callout_drain(&sc->sc_watchdog);
 	mwl_dma_cleanup(sc);
 	mwl_tx_cleanup(sc);
 	mwl_hal_detach(sc->sc_mh);
@@ -1214,6 +1215,7 @@ mwl_init_locked(struct mwl_softc *sc)
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	mwl_hal_intrset(mh, sc->sc_imask);
+	callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
 
 	return 0;
 }
@@ -1251,7 +1253,8 @@ mwl_stop_locked(struct ifnet *ifp, int d
 		 * Shutdown the hardware and driver.
 		 */
 		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-		ifp->if_timer = 0;
+		callout_stop(&sc->sc_watchdog);
+		sc->sc_tx_timer = 0;
 		mwl_draintxq(sc);
 	}
 }
@@ -3405,7 +3408,7 @@ mwl_tx_start(struct mwl_softc *sc, struc
 	MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 	ifp->if_opackets++;
-	ifp->if_timer = 5;
+	sc->sc_tx_timer = 5;
 	MWL_TXQ_UNLOCK(txq);
 
 	return 0;
@@ -3552,7 +3555,7 @@ mwl_tx_proc(void *arg, int npending)
 
 	if (nreaped != 0) {
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-		ifp->if_timer = 0;
+		sc->sc_tx_timer = 0;
 		if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
 			/* NB: kick fw; the tx thread may have been preempted */
 			mwl_hal_txstart(sc->sc_mh, 0);
@@ -3618,7 +3621,7 @@ mwl_draintxq(struct mwl_softc *sc)
 	for (i = 0; i < MWL_NUM_TX_QUEUES; i++)
 		mwl_tx_draintxq(sc, &sc->sc_txq[i]);
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	ifp->if_timer = 0;
+	sc->sc_tx_timer = 0;
 }
 
 #ifdef MWL_DIAGAPI
@@ -4764,10 +4767,17 @@ mwl_txq_dump(struct mwl_txq *txq)
 #endif
 
 static void
-mwl_watchdog(struct ifnet *ifp)
+mwl_watchdog(void *arg)
 {
-	struct mwl_softc *sc = ifp->if_softc;
+	struct mwl_softc *sc;
+	struct ifnet *ifp;
+
+	sc = arg;
+	callout_reset(&sc->sc_watchdog, hz, mwl_watchdog, sc);
+	if (sc->sc_tx_timer == 0 || --sc->sc_tx_timer > 0)
+		return;
 
+	ifp = sc->sc_ifp;
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) {
 		if (mwl_hal_setkeepalive(sc->sc_mh))
 			if_printf(ifp, "transmit timeout (firmware hung?)\n");

Modified: stable/8/sys/dev/mwl/if_mwlvar.h
==============================================================================
--- stable/8/sys/dev/mwl/if_mwlvar.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/mwl/if_mwlvar.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -255,6 +255,8 @@ struct mwl_softc {
 	bus_space_tag_t		sc_io1t;
 	struct mtx		sc_mtx;		/* master lock (recursive) */
 	struct taskqueue	*sc_tq;		/* private task queue */
+	struct callout	sc_watchdog;
+	int			sc_tx_timer;
 	unsigned int		sc_invalid : 1,	/* disable hardware accesses */
 				sc_recvsetup:1,	/* recv setup */
 				sc_csapending:1,/* 11h channel switch pending */

Modified: stable/8/sys/dev/sn/if_sn.c
==============================================================================
--- stable/8/sys/dev/sn/if_sn.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/sn/if_sn.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/errno.h>
+#include <sys/kernel.h>
 #include <sys/sockio.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
@@ -121,6 +122,7 @@ static int snioctl(struct ifnet * ifp, u
 
 static void snresume(struct ifnet *);
 
+static void snintr_locked(struct sn_softc *);
 static void sninit_locked(void *);
 static void snstart_locked(struct ifnet *);
 
@@ -128,7 +130,7 @@ static void sninit(void *);
 static void snread(struct ifnet *);
 static void snstart(struct ifnet *);
 static void snstop(struct sn_softc *);
-static void snwatchdog(struct ifnet *);
+static void snwatchdog(void *);
 
 static void sn_setmcast(struct sn_softc *);
 static int sn_getmcf(struct ifnet *ifp, u_char *mcf);
@@ -170,6 +172,7 @@ sn_attach(device_t dev)
 	}
 
 	SN_LOCK_INIT(sc);
+	callout_init_mtx(&sc->watchdog, &sc->sc_mtx, 0);
 	snstop(sc);
 	sc->pages_wanted = -1;
 
@@ -202,13 +205,11 @@ sn_attach(device_t dev)
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_start = snstart;
 	ifp->if_ioctl = snioctl;
-	ifp->if_watchdog = snwatchdog;
 	ifp->if_init = sninit;
 	ifp->if_baudrate = 10000000;
 	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 	IFQ_SET_READY(&ifp->if_snd);
-	ifp->if_timer = 0;
 
 	ether_ifattach(ifp, eaddr);
 
@@ -233,9 +234,11 @@ sn_detach(device_t dev)
 	struct sn_softc	*sc = device_get_softc(dev);
 	struct ifnet	*ifp = sc->ifp;
 
-	snstop(sc);
-	ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 
 	ether_ifdetach(ifp);
+	SN_LOCK(sc);
+	snstop(sc);
+	SN_UNLOCK(sc);
+	callout_drain(&sc->watchdog);
 	sn_deactivate(dev);
 	if_free(ifp);
 	SN_LOCK_DESTROY(sc);
@@ -342,6 +345,7 @@ sninit_locked(void *xsc)
 	 */
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	callout_reset(&sc->watchdog, hz, snwatchdog, sc);
 
 	/*
 	 * Attempt to push out any waiting packets.
@@ -463,7 +467,7 @@ startagain:
 		CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
 		sc->intr_mask = mask;
 
-		ifp->if_timer = 1;
+		sc->timer = 1;
 		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 		sc->pages_wanted = numPages;
 		return;
@@ -548,7 +552,7 @@ startagain:
 	CSR_WRITE_2(sc, MMU_CMD_REG_W, MMUCR_ENQUEUE);
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-	ifp->if_timer = 1;
+	sc->timer = 1;
 
 	BPF_MTAP(ifp, top);
 
@@ -657,7 +661,7 @@ snresume(struct ifnet *ifp)
 	packet_no = CSR_READ_1(sc, ALLOC_RESULT_REG_B);
 	if (packet_no & ARR_FAILED) {
 		if_printf(ifp, "Memory allocation failed.  Weird.\n");
-		ifp->if_timer = 1;
+		sc->timer = 1;
 		goto try_start;
 	}
 	/*
@@ -755,24 +759,32 @@ try_start:
 	 * Now pass control to snstart() to queue any additional packets
 	 */
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-	snstart(ifp);
+	snstart_locked(ifp);
 
 	/*
 	 * We've sent something, so we're active.  Set a watchdog in case the
 	 * TX_EMPTY interrupt is lost.
 	 */
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-	ifp->if_timer = 1;
+	sc->timer = 1;
 
 	return;
 }
 
-
 void
 sn_intr(void *arg)
 {
-	int             status, interrupts;
 	struct sn_softc *sc = (struct sn_softc *) arg;
+
+	SN_LOCK(sc);
+	snintr_locked(sc);
+	SN_UNLOCK(sc);
+}
+
+static void
+snintr_locked(struct sn_softc *sc)
+{
+	int             status, interrupts;
 	struct ifnet   *ifp = sc->ifp;
 
 	/*
@@ -783,12 +795,10 @@ sn_intr(void *arg)
 	uint16_t        tx_status;
 	uint16_t        card_stats;
 
-	SN_LOCK(sc);
-
 	/*
 	 * Clear the watchdog.
 	 */
-	ifp->if_timer = 0;
+	sc->timer = 0;
 
 	SMC_SELECT_BANK(sc, 2);
 
@@ -981,7 +991,6 @@ out:
 	mask |= CSR_READ_1(sc, INTR_MASK_REG_B);
 	CSR_WRITE_1(sc, INTR_MASK_REG_B, mask);
 	sc->intr_mask = mask;
-	SN_UNLOCK(sc);
 }
 
 static void
@@ -1136,7 +1145,6 @@ snioctl(struct ifnet *ifp, u_long cmd, c
 		SN_LOCK(sc);
 		if ((ifp->if_flags & IFF_UP) == 0 &&
 		    ifp->if_drv_flags & IFF_DRV_RUNNING) {
-			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 			snstop(sc);
 		} else {
 			/* reinitialize card on any parameter change */
@@ -1161,9 +1169,16 @@ snioctl(struct ifnet *ifp, u_long cmd, c
 }
 
 static void
-snwatchdog(struct ifnet *ifp)
+snwatchdog(void *arg)
 {
-	sn_intr(ifp->if_softc);
+	struct sn_softc *sc;
+
+	sc = arg;
+	SN_ASSERT_LOCKED(sc);
+	callout_reset(&sc->watchdog, hz, snwatchdog, sc);
+	if (sc->timer == 0 || --sc->timer > 0)
+		return;
+	snintr_locked(sc);
 }
 
 
@@ -1193,7 +1208,9 @@ snstop(struct sn_softc *sc)
 	/*
 	 * Cancel watchdog.
 	 */
-	ifp->if_timer = 0;
+	sc->timer = 0;
+	callout_stop(&sc->watchdog);
+	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 }
 
 

Modified: stable/8/sys/dev/sn/if_snvar.h
==============================================================================
--- stable/8/sys/dev/sn/if_snvar.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/sn/if_snvar.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -35,6 +35,8 @@ struct sn_softc {
 	bus_space_tag_t	bst;
 	bus_space_handle_t bsh;
 	struct mtx sc_mtx;
+	struct callout watchdog;
+	int		timer;
 	int             pages_wanted;	/* Size of outstanding MMU ALLOC */
 	int             intr_mask;	/* Most recently set interrupt mask */
 	device_t	dev;

Modified: stable/8/sys/dev/ti/if_ti.c
==============================================================================
--- stable/8/sys/dev/ti/if_ti.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/ti/if_ti.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -194,7 +194,7 @@ static void ti_init(void *);
 static void ti_init_locked(void *);
 static void ti_init2(struct ti_softc *);
 static void ti_stop(struct ti_softc *);
-static void ti_watchdog(struct ifnet *);
+static void ti_watchdog(void *);
 static int ti_shutdown(device_t);
 static int ti_ifmedia_upd(struct ifnet *);
 static void ti_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -2286,6 +2286,7 @@ ti_attach(dev)
 
 	mtx_init(&sc->ti_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
+	callout_init_mtx(&sc->ti_watchdog, &sc->ti_mtx, 0);
 	ifmedia_init(&sc->ifmedia, IFM_IMASK, ti_ifmedia_upd, ti_ifmedia_sts);
 	ifp = sc->ti_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
@@ -2488,7 +2489,6 @@ ti_attach(dev)
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = ti_ioctl;
 	ifp->if_start = ti_start;
-	ifp->if_watchdog = ti_watchdog;
 	ifp->if_init = ti_init;
 	ifp->if_baudrate = 1000000000;
 	ifp->if_snd.ifq_maxlen = TI_TX_RING_CNT - 1;
@@ -2566,24 +2566,22 @@ ti_detach(dev)
 {
 	struct ti_softc		*sc;
 	struct ifnet		*ifp;
-	int			attached;
 
 	sc = device_get_softc(dev);
 	if (sc->dev)
 		destroy_dev(sc->dev);
 	KASSERT(mtx_initialized(&sc->ti_mtx), ("ti mutex not initialized"));
-	attached = device_is_attached(dev);
-	TI_LOCK(sc);
 	ifp = sc->ti_ifp;
-	if (attached)
-		ti_stop(sc);
-	TI_UNLOCK(sc);
-	if (attached)
+	if (device_is_attached(dev)) {
 		ether_ifdetach(ifp);
+		TI_LOCK(sc);
+		ti_stop(sc);
+		TI_UNLOCK(sc);
+	}
 
 	/* These should only be active if attach succeeded */
-	if (attached)
-		bus_generic_detach(dev);
+	callout_drain(&sc->ti_watchdog);
+	bus_generic_detach(dev);
 	ti_free_dmamaps(sc);
 	ifmedia_removeall(&sc->ifmedia);
 
@@ -2867,7 +2865,7 @@ ti_txeof(sc)
 	}
 	sc->ti_tx_saved_considx = idx;
 
-	ifp->if_timer = sc->ti_txcnt > 0 ? 5 : 0;
+	sc->ti_timer = sc->ti_txcnt > 0 ? 5 : 0;
 }
 
 static void
@@ -3122,7 +3120,7 @@ ti_start_locked(ifp)
 		/*
 		 * Set a timeout in case the chip goes out to lunch.
 		 */
-		ifp->if_timer = 5;
+		sc->ti_timer = 5;
 	}
 }
 
@@ -3226,6 +3224,7 @@ static void ti_init2(sc)
 
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	callout_reset(&sc->ti_watchdog, hz, ti_watchdog, sc);
 
 	/*
 	 * Make sure to set media properly. We have to do this
@@ -3787,30 +3786,31 @@ ti_ioctl2(struct cdev *dev, u_long cmd, 
 }
 
 static void
-ti_watchdog(ifp)
-	struct ifnet		*ifp;
+ti_watchdog(void *arg)
 {
 	struct ti_softc		*sc;
+	struct ifnet		*ifp;
 
-	sc = ifp->if_softc;
-	TI_LOCK(sc);
+	sc = arg;
+	TI_LOCK_ASSERT(sc);
+	callout_reset(&sc->ti_watchdog, hz, ti_watchdog, sc);
+	if (sc->ti_timer == 0 || --sc->ti_timer > 0)
+		return;
 
 	/*
 	 * When we're debugging, the chip is often stopped for long periods
 	 * of time, and that would normally cause the watchdog timer to fire.
 	 * Since that impedes debugging, we don't want to do that.
 	 */
-	if (sc->ti_flags & TI_FLAG_DEBUGING) {
-		TI_UNLOCK(sc);
+	if (sc->ti_flags & TI_FLAG_DEBUGING)
 		return;
-	}
 
+	ifp = sc->ti_ifp;
 	if_printf(ifp, "watchdog timeout -- resetting\n");
 	ti_stop(sc);
 	ti_init_locked(sc);
 
 	ifp->if_oerrors++;
-	TI_UNLOCK(sc);
 }
 
 /*
@@ -3860,6 +3860,7 @@ ti_stop(sc)
 	sc->ti_tx_saved_considx = TI_TXCONS_UNSET;
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+	callout_stop(&sc->ti_watchdog);
 }
 
 /*

Modified: stable/8/sys/dev/ti/if_tireg.h
==============================================================================
--- stable/8/sys/dev/ti/if_tireg.h	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/ti/if_tireg.h	Sun Oct 30 01:13:47 2011	(r226921)
@@ -1038,6 +1038,8 @@ struct ti_softc {
 	int			ti_if_flags;
 	int			ti_txcnt;
 	struct mtx		ti_mtx;
+	struct callout		ti_watchdog;
+	int			ti_timer;
 	ti_flag_vals		ti_flags;
 	struct cdev		 *dev;
 };

Modified: stable/8/sys/dev/vx/if_vx.c
==============================================================================
--- stable/8/sys/dev/vx/if_vx.c	Sun Oct 30 00:57:56 2011	(r226920)
+++ stable/8/sys/dev/vx/if_vx.c	Sun Oct 30 01:13:47 2011	(r226921)
@@ -129,7 +129,7 @@ static void vx_init_locked(struct vx_sof
 static int vx_ioctl(struct ifnet *, u_long, caddr_t);
 static void vx_start(struct ifnet *);
 static void vx_start_locked(struct ifnet *);
-static void vx_watchdog(struct ifnet *);
+static void vx_watchdog(void *);
 static void vx_reset(struct vx_softc *);
 static void vx_read(struct vx_softc *);
 static struct mbuf *vx_get(struct vx_softc *, u_int);
@@ -157,6 +157,7 @@ vx_attach(device_t dev)
 	mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
 	    MTX_DEF);
 	callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0);
+	callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0);
 	GO_WINDOW(0);
 	CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET);
 	VX_BUSY_WAIT;
@@ -193,7 +194,6 @@ vx_attach(device_t dev)
 	ifp->if_start = vx_start;
 	ifp->if_ioctl = vx_ioctl;
 	ifp->if_init = vx_init;
-	ifp->if_watchdog = vx_watchdog;
 	ifp->if_softc = sc;
 
 	ether_ifattach(ifp, eaddr);
@@ -269,6 +269,7 @@ vx_init_locked(struct vx_softc *sc)
 	/* Interface is now `running', with no output active. */
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
 
 	/* Attempt to start output, if any. */
 	vx_start_locked(ifp);
@@ -474,7 +475,7 @@ startagain:
 		/* not enough room in FIFO - make sure */
 		if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
-			ifp->if_timer = 1;
+			sc->vx_timer = 1;
 			return;
 		}
 	}
@@ -513,7 +514,7 @@ startagain:
 		CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0);	/* Padding */
 
 	++ifp->if_opackets;
-	ifp->if_timer = 1;
+	sc->vx_timer = 1;
 
 readcheck:

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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