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>