--- //depot/vendor/freebsd/src/sys/dev/ce/if_ce.c 2009/06/09 07:15:13 +++ //depot/user/jhb/cleanup/sys/dev/ce/if_ce.c 2009/10/05 17:37:22 @@ -171,11 +171,11 @@ node_p node; struct ifqueue queue; struct ifqueue hi_queue; - short timeout; - struct callout timeout_handle; #else struct ifnet *ifp; #endif + short timeout; + struct callout timeout_handle; #if __FreeBSD_version >= 500000 struct cdev *devt; #else /* __FreeBSD_version < 500000 */ @@ -211,13 +211,13 @@ static void ce_start (drv_t *d); static void ce_down (drv_t *d); static void ce_watchdog (drv_t *d); +static void ce_watchdog_timer (void *arg); #ifdef NETGRAPH extern struct ng_type typestruct; #else static void ce_ifstart (struct ifnet *ifp); static void ce_tlf (struct sppp *sp); static void ce_tls (struct sppp *sp); -static void ce_ifwatchdog (struct ifnet *ifp); static int ce_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); static void ce_initialize (void *softc); #endif @@ -677,6 +677,7 @@ continue; d = c->sys; + callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { printf ("%s: cannot make common node\n", d->name); @@ -685,7 +686,6 @@ } #if __FreeBSD_version >= 500000 NG_NODE_SET_PRIVATE (d->node, d); - callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #else d->node->private = d; #endif @@ -731,7 +731,6 @@ d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; d->ifp->if_ioctl = ce_sioctl; d->ifp->if_start = ce_ifstart; - d->ifp->if_watchdog = ce_ifwatchdog; d->ifp->if_init = ce_initialize; d->rqueue.ifq_maxlen = IFQ_MAXLEN; #if __FreeBSD_version >= 500000 @@ -806,6 +805,7 @@ if (! d || ! d->chan) continue; + callout_stop (&d->timeout_handle); #ifndef NETGRAPH /* Detach from the packet filter list of interfaces. */ bpfdetach (d->ifp); @@ -855,13 +855,12 @@ TAU32_DestructiveHalt (b->ddk.pControllerObject, 0); bus_release_resource (dev, SYS_RES_MEMORY, PCIR_BAR(0), bd->ce_res); - s = splimp (); - CE_LOCK (bd); for (c = b->chan; c < b->chan + NCHAN; ++c) { drv_t *d = (drv_t*) c->sys; if (! d || ! d->chan) continue; + callout_drain (&d->timeout_handle); channel [b->num * NCHAN + c->num] = 0; /* Deallocate buffers. */ ce_bus_dma_mem_free (&d->dmamem); @@ -869,8 +868,6 @@ adapter [b->num] = 0; ce_bus_dma_mem_free (&bd->dmamem); free (b, M_DEVBUF); - CE_UNLOCK (bd); - splx (s); #if __FreeBSD_version >= 504000 mtx_destroy (&bd->ce_mtx); #endif @@ -888,13 +885,6 @@ CE_UNLOCK (bd); } -static void ce_ifwatchdog (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - - ce_watchdog (d); -} - static void ce_tlf (struct sppp *sp) { drv_t *d = SP2IFP(sp)->if_softc; @@ -989,6 +979,7 @@ ce_set_rts (d->chan, 0); d->running = 0; + callout_stop (&d->timeout_handle); } /* @@ -1055,11 +1046,7 @@ } m_freem (m); /* Set up transmit timeout, if the transmit ring is not empty.*/ -#ifdef NETGRAPH d->timeout = 10; -#else - d->ifp->if_timer = 10; -#endif } #ifndef NETGRAPH #if __FreeBSD_version >= 600034 @@ -1082,6 +1069,7 @@ if (! d->chan->rts) ce_set_rts (d->chan, 1); ce_send (d); + callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); } } @@ -1092,11 +1080,8 @@ */ static void ce_watchdog (drv_t *d) { - bdrv_t *bd = d->board->sys; CE_DEBUG (d, ("device timeout\n")); if (d->running) { - int s = splimp (); - CE_LOCK (bd); ce_set_dtr (d->chan, 0); ce_set_rts (d->chan, 0); /* ce_stop_chan (d->chan);*/ @@ -1104,25 +1089,35 @@ ce_set_dtr (d->chan, 1); ce_set_rts (d->chan, 1); ce_start (d); - CE_UNLOCK (bd); - splx (s); } } +static void ce_watchdog_timer (void *arg) +{ + drv_t *d = arg; + bdrv_t *bd = d->board->sys; + + CE_LOCK(bd); + if (d->timeout == 1) + ce_watchdog (d); + if (d->timeout) + d->timeout--; + callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); + CE_UNLOCK(bd); +} + static void ce_transmit (ce_chan_t *c, void *attachment, int len) { drv_t *d = c->sys; -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_opackets; #if __FreeBSD_version >= 600034 d->ifp->if_flags &= ~IFF_DRV_OACTIVE; #else d->ifp->if_flags &= ~IFF_OACTIVE; #endif - d->ifp->if_timer = 0; #endif ce_start (d); } @@ -1195,16 +1190,14 @@ break; case CE_UNDERRUN: CE_DEBUG (d, ("underrun error\n")); -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_oerrors; #if __FreeBSD_version >= 600034 d->ifp->if_flags &= ~IFF_DRV_OACTIVE; #else d->ifp->if_flags &= ~IFF_OACTIVE; #endif - d->ifp->if_timer = 0; #endif ce_start (d); break; @@ -2507,19 +2500,6 @@ return 0; } -static void ng_ce_watchdog (void *arg) -{ - drv_t *d = arg; - - if (d) { - if (d->timeout == 1) - ce_watchdog (d); - if (d->timeout) - d->timeout--; - callout_reset (&d->timeout_handle, hz, ng_ce_watchdog, d); - } -} - static int ng_ce_connect (hook_p hook) { #if __FreeBSD_version >= 500000 @@ -2530,7 +2510,7 @@ if (d) { CE_DEBUG (d, ("Connect\n")); - callout_reset (&d->timeout_handle, hz, ng_ce_watchdog, d); + callout_reset (&d->timeout_handle, hz, ce_watchdog_timer, d); } return 0; --- //depot/vendor/freebsd/src/sys/dev/cm/smc90cx6.c 2009/02/13 00:04:14 +++ //depot/user/jhb/cleanup/sys/dev/cm/smc90cx6.c 2009/11/06 15:35:53 @@ -124,7 +124,7 @@ 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 @@ 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 = IFQ_MAXLEN; - ifp->if_timer = 0; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; arc_ifattach(ifp, linkaddress); @@ -210,6 +208,7 @@ #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 @@ 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 @@ 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 @@ 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 @@ 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 @@ */ 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 @@ 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 @@ * 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); } --- //depot/vendor/freebsd/src/sys/dev/cm/smc90cx6var.h 2006/06/11 22:25:42 +++ //depot/user/jhb/cleanup/sys/dev/cm/smc90cx6var.h 2009/10/03 16:13:53 @@ -77,6 +77,8 @@ 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 */ --- //depot/vendor/freebsd/src/sys/dev/cp/if_cp.c 2009/06/09 07:15:13 +++ //depot/user/jhb/cleanup/sys/dev/cp/if_cp.c 2009/10/05 17:41:26 @@ -117,12 +117,12 @@ node_p node; struct ifqueue queue; struct ifqueue hi_queue; - short timeout; - struct callout timeout_handle; #else struct ifqueue queue; struct ifnet *ifp; #endif + short timeout; + struct callout timeout_handle; struct cdev *devt; } drv_t; @@ -151,13 +151,13 @@ static void cp_start (drv_t *d); static void cp_down (drv_t *d); static void cp_watchdog (drv_t *d); +static void cp_watchdog_timer (void *arg); #ifdef NETGRAPH extern struct ng_type typestruct; #else static void cp_ifstart (struct ifnet *ifp); static void cp_tlf (struct sppp *sp); static void cp_tls (struct sppp *sp); -static void cp_ifwatchdog (struct ifnet *ifp); static int cp_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); static void cp_initialize (void *softc); #endif @@ -490,6 +490,7 @@ d->board = b; d->chan = c; c->sys = d; + callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { printf ("%s: cannot make common node\n", d->name); @@ -508,7 +509,6 @@ d->hi_queue.ifq_maxlen = IFQ_MAXLEN; mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF); mtx_init (&d->hi_queue.ifq_mtx, "cp_queue_hi", NULL, MTX_DEF); - callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #else /*NETGRAPH*/ d->ifp = if_alloc(IFT_PPP); if (d->ifp == NULL) { @@ -521,7 +521,6 @@ d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; d->ifp->if_ioctl = cp_sioctl; d->ifp->if_start = cp_ifstart; - d->ifp->if_watchdog = cp_ifwatchdog; d->ifp->if_init = cp_initialize; d->queue.ifq_maxlen = NRBUF; mtx_init (&d->queue.ifq_mtx, "cp_queue", NULL, MTX_DEF); @@ -603,6 +602,7 @@ if (! d || ! d->chan->type) continue; + callout_stop (&d->timeout_handle); #ifndef NETGRAPH /* Detach from the packet filter list of interfaces. */ bpfdetach (d->ifp); @@ -639,12 +639,12 @@ callout_drain (&led_timo[b->num]); splx (s); - s = splimp (); for (c = b->chan; c < b->chan + NCHAN; ++c) { drv_t *d = (drv_t*) c->sys; if (! d || ! d->chan->type) continue; + callout_drain (&d->timeout_handle); channel [b->num*NCHAN + c->num] = 0; /* Deallocate buffers. */ cp_bus_dma_mem_free (&d->dmamem); @@ -652,7 +652,6 @@ adapter [b->num] = 0; cp_bus_dma_mem_free (&bd->dmamem); free (b, M_DEVBUF); - splx (s); mtx_destroy (&bd->cp_mtx); return 0; } @@ -668,13 +667,6 @@ CP_UNLOCK (bd); } -static void cp_ifwatchdog (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - - cp_watchdog (d); -} - static void cp_tlf (struct sppp *sp) { drv_t *d = SP2IFP(sp)->if_softc; @@ -766,6 +758,7 @@ cp_set_rts (d->chan, 0); d->running = 0; + callout_stop (&d->timeout_handle); } /* @@ -827,11 +820,7 @@ } m_freem (m); /* Set up transmit timeout, if the transmit ring is not empty.*/ -#ifdef NETGRAPH d->timeout = 10; -#else - d->ifp->if_timer = 10; -#endif } #ifndef NETGRAPH d->ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -850,6 +839,7 @@ if (! d->chan->rts) cp_set_rts (d->chan, 1); cp_send (d); + callout_reset (&d->timeout_handle, hz, cp_watchdog_timer, d); } } @@ -860,12 +850,8 @@ */ static void cp_watchdog (drv_t *d) { - bdrv_t *bd = d->board->sys; CP_DEBUG (d, ("device timeout\n")); if (d->running) { - int s = splimp (); - - CP_LOCK (bd); cp_stop_chan (d->chan); cp_stop_e1 (d->chan); cp_start_e1 (d->chan); @@ -873,21 +859,31 @@ cp_set_dtr (d->chan, 1); cp_set_rts (d->chan, 1); cp_start (d); - CP_UNLOCK (bd); - splx (s); } } +static void cp_watchdog_timer (void *arg) +{ + drv_t *d = arg; + bdrv_t *bd = d->board->sys; + + CP_LOCK (bd); + if (d->timeout == 1) + cp_watchdog (d); + if (d->timeout) + d->timeout--; + callout_reset (&d->timeout_handle, hz, cp_watchdog_timer, d); + CP_UNLOCK (bd); +} + static void cp_transmit (cp_chan_t *c, void *attachment, int len) { drv_t *d = c->sys; -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_opackets; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; #endif cp_start (d); } @@ -958,12 +954,10 @@ break; case CP_UNDERRUN: CP_DEBUG (d, ("underrun error\n")); -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_oerrors; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; #endif cp_start (d); break; @@ -2198,26 +2192,13 @@ return 0; } -static void ng_cp_watchdog (void *arg) -{ - drv_t *d = arg; - - if (d) { - if (d->timeout == 1) - cp_watchdog (d); - if (d->timeout) - d->timeout--; - callout_reset (&d->timeout_handle, hz, ng_cp_watchdog, d); - } -} - static int ng_cp_connect (hook_p hook) { drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); if (d) { CP_DEBUG (d, ("Connect\n")); - callout_reset (&d->timeout_handle, hz, ng_cp_watchdog, d); + callout_reset (&d->timeout_handle, hz, cp_watchdog_timer, d); } return 0; --- //depot/vendor/freebsd/src/sys/dev/ctau/if_ct.c 2009/06/09 07:15:13 +++ //depot/user/jhb/cleanup/sys/dev/ctau/if_ct.c 2009/10/05 17:45:42 @@ -118,12 +118,12 @@ node_p node; struct ifqueue queue; struct ifqueue hi_queue; - short timeout; - struct callout timeout_handle; #else struct ifqueue queue; struct ifnet *ifp; #endif + short timeout; + struct callout timeout_handle; struct cdev *devt; } drv_t; @@ -155,13 +155,13 @@ static void ct_start (drv_t *d); static void ct_down (drv_t *d); static void ct_watchdog (drv_t *d); +static void ct_watchdog_timer (void *arg); #ifdef NETGRAPH extern struct ng_type typestruct; #else static void ct_ifstart (struct ifnet *ifp); static void ct_tlf (struct sppp *sp); static void ct_tls (struct sppp *sp); -static void ct_ifwatchdog (struct ifnet *ifp); static int ct_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); static void ct_initialize (void *softc); #endif @@ -701,6 +701,7 @@ c->sys = d; channel [b->num*NCHAN + c->num] = d; sprintf (d->name, "ct%d.%d", b->num, c->num); + callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { @@ -724,8 +725,7 @@ d->queue.ifq_maxlen = IFQ_MAXLEN; d->hi_queue.ifq_maxlen = IFQ_MAXLEN; mtx_init (&d->queue.ifq_mtx, "ct_queue", NULL, MTX_DEF); - mtx_init (&d->hi_queue.ifq_mtx, "ct_queue_hi", NULL, MTX_DEF); - callout_init (&d->timeout_handle, CALLOUT_MPSAFE); + mtx_init (&d->hi_queue.ifq_mtx, "ct_queue_hi", NULL, MTX_DEF); #else /*NETGRAPH*/ d->ifp = if_alloc(IFT_PPP); if (d->ifp == NULL) { @@ -742,7 +742,6 @@ d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; d->ifp->if_ioctl = ct_sioctl; d->ifp->if_start = ct_ifstart; - d->ifp->if_watchdog = ct_ifwatchdog; d->ifp->if_init = ct_initialize; d->queue.ifq_maxlen = NBUF; mtx_init (&d->queue.ifq_mtx, "ct_queue", NULL, MTX_DEF); @@ -816,6 +815,7 @@ if (!d || !d->chan->type) continue; + callout_stop (&d->timeout_handle); #ifdef NETGRAPH if (d->node) { ng_rmnode_self (d->node); @@ -845,12 +845,12 @@ callout_drain (&led_timo[b->num]); splx (s); - s = splimp (); for (c = b->chan; c < b->chan + NCHAN; ++c) { drv_t *d = (drv_t*) c->sys; if (!d || !d->chan->type) continue; + callout_drain(&d->timeout_handle); /* Deallocate buffers. */ ct_bus_dma_mem_free (&d->dmamem); @@ -858,7 +858,6 @@ bd->board = 0; adapter [b->num] = 0; free (b, M_DEVBUF); - splx (s); mtx_destroy (&bd->ct_mtx); @@ -876,13 +875,6 @@ CT_UNLOCK (bd); } -static void ct_ifwatchdog (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - - ct_watchdog (d); -} - static void ct_tlf (struct sppp *sp) { drv_t *d = SP2IFP(sp)->if_softc; @@ -970,6 +962,7 @@ ct_set_dtr (d->chan, 0); ct_set_rts (d->chan, 0); d->running = 0; + callout_stop (&d->timeout_handle); splx (s); } @@ -1033,11 +1026,7 @@ /* Set up transmit timeout, if the transmit ring is not empty. * Transmit timeout is 10 seconds. */ -#ifdef NETGRAPH d->timeout = 10; -#else - d->ifp->if_timer = 10; -#endif } #ifndef NETGRAPH d->ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -1058,6 +1047,7 @@ if (! d->chan->rts) ct_set_rts (d->chan, 1); ct_send (d); + callout_reset (&d->timeout_handle, hz, ct_watchdog_timer, d); } splx (s); @@ -1070,11 +1060,7 @@ */ static void ct_watchdog (drv_t *d) { - bdrv_t *bd = d->bd; - int s; - s = splimp (); - CT_LOCK (bd); CT_DEBUG (d, ("device timeout\n")); if (d->running) { ct_setup_chan (d->chan); @@ -1083,8 +1069,20 @@ ct_set_rts (d->chan, 1); ct_start (d); } +} + +static void ct_watchdog_timer (void *arg) +{ + drv_t *d = arg; + bdrv_t *bd = d->bd; + + CT_LOCK (bd); + if (d->timeout == 1) + ct_watchdog (d); + if (d->timeout) + d->timeout--; + callout_reset (&d->timeout_handle, hz, ct_watchdog_timer, d); CT_UNLOCK (bd); - splx (s); } /* @@ -1096,12 +1094,10 @@ if (!d) return; -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_opackets; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; #endif ct_start (d); } @@ -1181,12 +1177,10 @@ break; case CT_UNDERRUN: CT_DEBUG (d, ("underrun error\n")); -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_oerrors; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; #endif ct_start (d); break; @@ -2142,20 +2136,6 @@ return 0; } -static void ng_ct_watchdog (void *arg) -{ - drv_t *d = arg; - - if (!d) - return; - - if (d->timeout == 1) - ct_watchdog (d); - if (d->timeout) - d->timeout--; - callout_reset (&d->timeout_handle, hz, ng_ct_watchdog, d); -} - static int ng_ct_connect (hook_p hook) { drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); @@ -2163,7 +2143,7 @@ if (!d) return 0; - callout_reset (&d->timeout_handle, hz, ng_ct_watchdog, d); + callout_reset (&d->timeout_handle, hz, ct_watchdog_timer, d); return 0; } --- //depot/vendor/freebsd/src/sys/dev/cx/if_cx.c 2009/06/09 07:15:13 +++ //depot/user/jhb/cleanup/sys/dev/cx/if_cx.c 2009/10/05 17:41:26 @@ -143,12 +143,12 @@ node_p node; struct ifqueue lo_queue; struct ifqueue hi_queue; - short timeout; - struct callout timeout_handle; #else struct ifqueue queue; struct ifnet *ifp; #endif + short timeout; + struct callout timeout_handle; struct cdev *devt; async_q aqueue; #define CX_READ 1 @@ -197,6 +197,7 @@ static void *cx_fast_ih; static void cx_down (drv_t *d); static void cx_watchdog (drv_t *d); +static void cx_watchdog_timer (void *arg); static void cx_carrier (void *arg); #ifdef NETGRAPH @@ -205,7 +206,6 @@ static void cx_ifstart (struct ifnet *ifp); static void cx_tlf (struct sppp *sp); static void cx_tls (struct sppp *sp); -static void cx_ifwatchdog (struct ifnet *ifp); static int cx_sioctl (struct ifnet *ifp, u_long cmd, caddr_t data); static void cx_initialize (void *softc); #endif @@ -811,6 +811,7 @@ case T_UNIV_RS232: case T_UNIV_RS449: case T_UNIV_V35: + callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #ifdef NETGRAPH if (ng_make_node_common (&typestruct, &d->node) != 0) { printf ("%s: cannot make common node\n", d->name); @@ -834,7 +835,6 @@ d->hi_queue.ifq_maxlen = IFQ_MAXLEN; mtx_init (&d->lo_queue.ifq_mtx, "cx_queue_lo", NULL, MTX_DEF); mtx_init (&d->hi_queue.ifq_mtx, "cx_queue_hi", NULL, MTX_DEF); - callout_init (&d->timeout_handle, CALLOUT_MPSAFE); #else /*NETGRAPH*/ d->ifp = if_alloc(IFT_PPP); if (d->ifp == NULL) { @@ -851,7 +851,6 @@ d->ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; d->ifp->if_ioctl = cx_sioctl; d->ifp->if_start = cx_ifstart; - d->ifp->if_watchdog = cx_ifwatchdog; d->ifp->if_init = cx_initialize; d->queue.ifq_maxlen = 2; mtx_init (&d->queue.ifq_mtx, "cx_queue", NULL, MTX_DEF); @@ -959,6 +958,7 @@ d->tty = NULL; } + callout_stop (&d->timeout_handle); #ifdef NETGRAPH if (d->node) { ng_rmnode_self (d->node); @@ -992,6 +992,7 @@ continue; callout_drain (&d->dcd_timeout_handle); + callout_drain (&d->timeout_handle); } splx (s); @@ -1026,13 +1027,6 @@ CX_UNLOCK (bd); } -static void cx_ifwatchdog (struct ifnet *ifp) -{ - drv_t *d = ifp->if_softc; - - cx_watchdog (d); -} - static void cx_tlf (struct sppp *sp) { drv_t *d = SP2IFP(sp)->if_softc; @@ -1129,6 +1123,7 @@ cx_set_dtr (d->chan, 0); cx_set_rts (d->chan, 0); d->running = 0; + callout_stop (&d->timeout_handle); splx (s); } @@ -1191,11 +1186,7 @@ m_freem (m); /* Set up transmit timeout, 10 seconds. */ -#ifdef NETGRAPH d->timeout = 10; -#else - d->ifp->if_timer = 10; -#endif } #ifndef NETGRAPH d->ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -1215,6 +1206,7 @@ if (! d->chan->rts) cx_set_rts (d->chan, 1); cx_send (d); + callout_reset (&d->timeout_handle, hz, cx_watchdog_timer, d); } splx (s); } @@ -1226,10 +1218,7 @@ */ static void cx_watchdog (drv_t *d) { - bdrv_t *bd = d->board->sys; - int s = splhigh (); - CX_LOCK (bd); CX_DEBUG (d, ("device timeout\n")); if (d->running) { cx_setup_chan (d->chan); @@ -1238,8 +1227,20 @@ cx_set_rts (d->chan, 1); cx_start (d); } +} + +static void cx_watchdog_timer (void *arg) +{ + drv_t *d = arg; + bdrv_t *bd = d->board->sys; + + CX_LOCK (bd); + if (d->timeout == 1) + cx_watchdog (d); + if (d->timeout) + d->timeout--; + callout_reset (&d->timeout_handle, hz, cx_watchdog_timer, d); CX_UNLOCK (bd); - splx (s); } /* @@ -1262,12 +1263,10 @@ } return; } -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_opackets; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; #endif cx_start (d); } @@ -1421,14 +1420,12 @@ case CX_UNDERRUN: CX_DEBUG (d, ("underrun error\n")); if (c->mode != M_ASYNC) { -#ifdef NETGRAPH d->timeout = 0; -#else +#ifndef NETGRAPH ++d->ifp->if_oerrors; d->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - d->ifp->if_timer = 0; +#endif cx_start (d); -#endif } break; case CX_BREAK: @@ -2477,22 +2474,11 @@ return 0; } -static void ng_cx_watchdog (void *arg) -{ - drv_t *d = arg; - - if (d->timeout == 1) - cx_watchdog (d); - if (d->timeout) - d->timeout--; - callout_reset (&d->timeout_handle, hz, ng_cx_watchdog, d); -} - static int ng_cx_connect (hook_p hook) { drv_t *d = NG_NODE_PRIVATE (NG_HOOK_NODE (hook)); - callout_reset (&d->timeout_handle, hz, ng_cx_watchdog, d); + callout_reset (&d->timeout_handle, hz, cx_watchdog_timer, d); return 0; } --- //depot/vendor/freebsd/src/sys/dev/de/if_de.c 2009/09/24 17:55:45 +++ //depot/user/jhb/cleanup/sys/dev/de/if_de.c 2009/10/03 21:38:36 @@ -151,6 +151,7 @@ static struct mbuf * tulip_txput(tulip_softc_t * const sc, struct mbuf *m); static void tulip_txput_setup(tulip_softc_t * const sc); +static void tulip_watchdog(void *arg); struct mbuf * tulip_dequeue_mbuf(tulip_ringinfo_t *ri, tulip_descinfo_t *di, int sync); static void tulip_dma_map_addr(void *, bus_dma_segment_t *, int, int); @@ -3302,11 +3303,13 @@ TULIP_CSR_READ(sc, csr_status)); if ((sc->tulip_flags & (TULIP_WANTSETUP|TULIP_TXPROBE_ACTIVE)) == TULIP_WANTSETUP) tulip_txput_setup(sc); + callout_reset(&sc->tulip_stat_timer, hz, tulip_watchdog, sc); } else { CTR0(KTR_TULIP, "tulip_init_locked: not up, reset chip"); sc->tulip_ifp->if_drv_flags &= ~IFF_DRV_RUNNING; tulip_reset(sc); tulip_addr_filter(sc); + callout_stop(&sc->tulip_stat_timer); } } @@ -4319,23 +4322,17 @@ } } -/* - * Even though this routine runs at device spl, it does not break - * our use of splnet (splsoftnet under NetBSD) for the majority - * of this driver since - * if_watcbog is called from if_watchdog which is called from - * splsoftclock which is below spl[soft]net. - */ static void -tulip_ifwatchdog(struct ifnet *ifp) +tulip_watchdog(void *arg) { - TULIP_PERFSTART(ifwatchdog) - tulip_softc_t * const sc = (tulip_softc_t *)ifp->if_softc; + TULIP_PERFSTART(stat) + tulip_softc_t *sc = arg; #if defined(TULIP_DEBUG) u_int32_t rxintrs; #endif - TULIP_LOCK(sc); + TULIP_LOCK_ASSERT(sc); + callout_reset(&sc->tulip_stat_timer, hz, tulip_watchdog, sc); #if defined(TULIP_DEBUG) rxintrs = sc->tulip_dbg.dbg_rxintrs - sc->tulip_dbg.dbg_last_rxintrs; if (rxintrs > sc->tulip_dbg.dbg_high_rxintrs_hz) @@ -4343,7 +4340,6 @@ sc->tulip_dbg.dbg_last_rxintrs = sc->tulip_dbg.dbg_rxintrs; #endif /* TULIP_DEBUG */ - sc->tulip_ifp->if_timer = 1; /* * These should be rare so do a bulk test up front so we can just skip * them if needed. @@ -4381,11 +4377,11 @@ tulip_init_locked(sc); } - TULIP_PERFEND(ifwatchdog); + TULIP_PERFEND(stat); TULIP_PERFMERGE(sc, perf_intr_cycles); TULIP_PERFMERGE(sc, perf_ifstart_cycles); TULIP_PERFMERGE(sc, perf_ifioctl_cycles); - TULIP_PERFMERGE(sc, perf_ifwatchdog_cycles); + TULIP_PERFMERGE(sc, perf_stat_cycles); TULIP_PERFMERGE(sc, perf_timeout_cycles); TULIP_PERFMERGE(sc, perf_ifstart_one_cycles); TULIP_PERFMERGE(sc, perf_txput_cycles); @@ -4395,14 +4391,13 @@ TULIP_PERFMERGE(sc, perf_intr); TULIP_PERFMERGE(sc, perf_ifstart); TULIP_PERFMERGE(sc, perf_ifioctl); - TULIP_PERFMERGE(sc, perf_ifwatchdog); + TULIP_PERFMERGE(sc, perf_stat); TULIP_PERFMERGE(sc, perf_timeout); TULIP_PERFMERGE(sc, perf_ifstart_one); TULIP_PERFMERGE(sc, perf_txput); TULIP_PERFMERGE(sc, perf_txintr); TULIP_PERFMERGE(sc, perf_rxintr); TULIP_PERFMERGE(sc, perf_rxget); - TULIP_UNLOCK(sc); } static void @@ -4418,8 +4413,6 @@ ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST; ifp->if_ioctl = tulip_ifioctl; ifp->if_start = tulip_start; - ifp->if_watchdog = tulip_ifwatchdog; - ifp->if_timer = 1; ifp->if_init = tulip_init; IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; @@ -4839,6 +4832,7 @@ mtx_init(TULIP_MUTEX(sc), MTX_NETWORK_LOCK, device_get_nameunit(dev), MTX_DEF); callout_init_mtx(&sc->tulip_callout, TULIP_MUTEX(sc), 0); + callout_init_mtx(&sc->tulip_stat_timer, TULIP_MUTEX(sc), 0); tulips[unit] = sc; tulip_initcsrs(sc, csr_base + csroffset, csrsize); --- //depot/vendor/freebsd/src/sys/dev/de/if_devar.h 2009/09/24 17:55:45 +++ //depot/user/jhb/cleanup/sys/dev/de/if_devar.h 2009/10/03 16:13:53 @@ -477,7 +477,7 @@ u_quad_t perf_ifstart_cycles; u_quad_t perf_ifstart_one_cycles; u_quad_t perf_ifioctl_cycles; - u_quad_t perf_ifwatchdog_cycles; + u_quad_t perf_stat_cycles; u_quad_t perf_timeout_cycles; u_quad_t perf_txput_cycles; u_quad_t perf_txintr_cycles; @@ -487,7 +487,7 @@ unsigned int perf_ifstart; unsigned int perf_ifstart_one; unsigned int perf_ifioctl; - unsigned int perf_ifwatchdog; + unsigned int perf_stat; unsigned int perf_timeout; unsigned int perf_txput; unsigned int perf_txintr; @@ -570,6 +570,7 @@ tulip_srom_connection_t tulip_conntype; struct callout tulip_callout; struct mtx tulip_mutex; + struct callout tulip_stat_timer; }; #define tulip_curperfstats tulip_perfstats[TULIP_PERF_CURRENT] --- //depot/vendor/freebsd/src/sys/dev/ed/if_ed.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/ed/if_ed.c 2009/11/06 15:35:53 @@ -77,7 +77,8 @@ static void ed_start(struct ifnet *); static void ed_start_locked(struct ifnet *); static void ed_reset(struct ifnet *); -static void ed_watchdog(struct ifnet *); +static void ed_tick(void *); +static void ed_watchdog(struct ed_softc *); static void ed_ds_getmcaf(struct ed_softc *, uint32_t *); @@ -281,7 +282,6 @@ if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_start = ed_start; ifp->if_ioctl = ed_ioctl; - ifp->if_watchdog = ed_watchdog; ifp->if_init = ed_init; IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; @@ -381,8 +381,8 @@ ed_stop(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ED_UNLOCK(sc); + ether_ifdetach(ifp); callout_drain(&sc->tick_ch); - ether_ifdetach(ifp); } if (sc->irq_res != NULL && sc->irq_handle) bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); @@ -447,9 +447,26 @@ ed_stop(struct ed_softc *sc) { ED_ASSERT_LOCKED(sc); + callout_stop(&sc->tick_ch); + ed_stop_hw(sc); +} + +/* + * Periodic timer used to drive the watchdog and attachment-specific + * tick handler. + */ +static void +ed_tick(void *arg) +{ + struct ed_softc *sc; + + sc = arg; + ED_ASSERT_LOCKED(sc); if (sc->sc_tick) - callout_stop(&sc->tick_ch); - ed_stop_hw(sc); + sc->sc_tick(sc); + if (sc->tx_timer != 0 && --sc->tx_timer == 0) + ed_watchdog(sc); + callout_reset(&sc->tick_ch, hz, ed_tick, sc); } /* @@ -457,16 +474,15 @@ * generate an interrupt after a transmit has been started on it. */ static void -ed_watchdog(struct ifnet *ifp) +ed_watchdog(struct ed_softc *sc) { - struct ed_softc *sc = ifp->if_softc; + struct ifnet *ifp; + ifp = sc->ifp; log(LOG_ERR, "%s: device timeout\n", ifp->if_xname); ifp->if_oerrors++; - ED_LOCK(sc); ed_reset(ifp); - ED_UNLOCK(sc); } /* @@ -499,7 +515,7 @@ /* reset transmitter flags */ sc->xmit_busy = 0; - ifp->if_timer = 0; + sc->tx_timer = 0; sc->txb_inuse = 0; sc->txb_new = 0; @@ -612,8 +628,7 @@ */ ed_start_locked(ifp); - if (sc->sc_tick) - callout_reset(&sc->tick_ch, hz, sc->sc_tick, sc); + callout_reset(&sc->tick_ch, hz, ed_tick, sc); } /* @@ -622,7 +637,6 @@ static __inline void ed_xmit(struct ed_softc *sc) { - struct ifnet *ifp = sc->ifp; unsigned short len; len = sc->txb_len[sc->txb_next_tx]; @@ -660,7 +674,7 @@ /* * Set a timer just in case we never hear from the board again */ - ifp->if_timer = 2; + sc->tx_timer = 2; } /* @@ -1023,7 +1037,7 @@ /* * clear watchdog timer */ - ifp->if_timer = 0; + sc->tx_timer = 0; /* * Add in total number of collisions on last --- //depot/vendor/freebsd/src/sys/dev/ed/if_ed_pccard.c 2009/04/24 17:30:15 +++ //depot/user/jhb/cleanup/sys/dev/ed/if_ed_pccard.c 2009/10/03 16:13:53 @@ -250,7 +250,7 @@ */ static int ed_pccard_probe(device_t); static int ed_pccard_attach(device_t); -static void ed_pccard_tick(void *); +static void ed_pccard_tick(struct ed_softc *); static int ed_pccard_dl100xx(device_t dev, const struct ed_product *); static void ed_pccard_dl100xx_mii_reset(struct ed_softc *sc); @@ -1196,9 +1196,8 @@ } static void -ed_pccard_tick(void *arg) +ed_pccard_tick(struct ed_softc *sc) { - struct ed_softc *sc = arg; struct mii_data *mii; int media = 0; @@ -1223,7 +1222,6 @@ } } - callout_reset(&sc->tick_ch, hz, ed_pccard_tick, sc); } static device_method_t ed_pccard_methods[] = { --- //depot/vendor/freebsd/src/sys/dev/ed/if_edvar.h 2009/04/20 01:26:04 +++ //depot/user/jhb/cleanup/sys/dev/ed/if_edvar.h 2009/10/03 16:13:53 @@ -65,11 +65,12 @@ void (*mii_writebits)(struct ed_softc *, u_int, int); u_int (*mii_readbits)(struct ed_softc *, int); struct callout tick_ch; - void (*sc_tick)(void *); + void (*sc_tick)(struct ed_softc *); void (*readmem)(struct ed_softc *sc, bus_size_t src, uint8_t *dst, uint16_t amount); u_short (*sc_write_mbufs)(struct ed_softc *, struct mbuf *, bus_size_t); + int tx_timer; int nic_offset; /* NIC (DS8390) I/O bus address offset */ int asic_offset; /* ASIC I/O bus address offset */ --- //depot/vendor/freebsd/src/sys/dev/ep/if_ep.c 2009/09/08 16:40:13 +++ //depot/user/jhb/cleanup/sys/dev/ep/if_ep.c 2009/11/06 15:35:53 @@ -62,6 +62,7 @@ #include #include +#include #include #include #include @@ -91,10 +92,12 @@ 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 @@ 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, IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 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 @@ 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 @@ GO_WINDOW(sc, 1); epstart_locked(ifp); + callout_reset(&sc->watchdog_timer, hz, eptick, sc); } static void @@ -556,7 +561,7 @@ BPF_MTAP(ifp, m0); - ifp->if_timer = 2; + sc->tx_timer = 2; ifp->if_opackets++; m_freem(m0); @@ -583,20 +588,26 @@ ep_intr(void *arg) { struct ep_softc *sc; + + 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; - sc = (struct ep_softc *) arg; - EP_LOCK(sc); /* 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 @@ 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 @@ #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. * @@ -700,7 +710,6 @@ /* re-enable Ints */ CSR_WRITE_2(sc, EP_COMMAND, SET_INTR_MASK | S_5_INTS); - EP_UNLOCK(sc); } static void @@ -933,7 +942,6 @@ 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 */ @@ -966,15 +974,27 @@ } static void -epwatchdog(struct ifnet *ifp) +eptick(void *arg) +{ + 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 ep_softc *sc = ifp->if_softc; + 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 @@ -997,4 +1017,7 @@ 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); } --- //depot/vendor/freebsd/src/sys/dev/ep/if_epvar.h 2009/04/11 04:36:50 +++ //depot/user/jhb/cleanup/sys/dev/ep/if_epvar.h 2009/10/03 16:13:53 @@ -45,6 +45,9 @@ 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. */ --- //depot/vendor/freebsd/src/sys/dev/fatm/if_fatm.c 2008/09/30 18:55:14 +++ //depot/user/jhb/cleanup/sys/dev/fatm/if_fatm.c 2009/10/05 18:59:18 @@ -391,16 +391,14 @@ * 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 @@ (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 @@ /* * 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_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 @@ 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 @@ 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); --- //depot/vendor/freebsd/src/sys/dev/fatm/if_fatmvar.h 2005/06/10 16:51:34 +++ //depot/user/jhb/cleanup/sys/dev/fatm/if_fatmvar.h 2009/10/05 18:59:18 @@ -188,6 +188,7 @@ 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 */ --- //depot/vendor/freebsd/src/sys/dev/ixgb/if_ixgb.c 2009/11/06 14:55:14 +++ //depot/user/jhb/cleanup/sys/dev/ixgb/if_ixgb.c 2009/11/10 21:59:42 @@ -97,7 +97,7 @@ static void ixgb_start(struct ifnet *); static void ixgb_start_locked(struct ifnet *); static int ixgb_ioctl(struct ifnet *, IOCTL_CMD_TYPE, caddr_t); -static void ixgb_watchdog(struct ifnet *); +static void ixgb_watchdog(struct adapter *); static void ixgb_init(void *); static void ixgb_init_locked(struct adapter *); static void ixgb_stop(void *); @@ -274,7 +274,7 @@ (void *)adapter, 0, ixgb_sysctl_stats, "I", "Statistics"); - callout_init(&adapter->timer, CALLOUT_MPSAFE); + callout_init_mtx(&adapter->timer, &adapter->mtx, 0); /* Determine hardware revision */ ixgb_identify_hardware(adapter); @@ -382,13 +382,14 @@ IXGB_UNLOCK(adapter); #if __FreeBSD_version < 500000 - ether_ifdetach(adapter->ifp, ETHER_BPF_SUPPORTED); + ether_ifdetach(ifp, ETHER_BPF_SUPPORTED); #else - ether_ifdetach(adapter->ifp); + ether_ifdetach(ifp); #endif + callout_drain(&adapter->timer); ixgb_free_pci_resources(adapter); #if __FreeBSD_version >= 500000 - if_free(adapter->ifp); + if_free(ifp); #endif /* Free Transmit Descriptor ring */ @@ -409,9 +410,6 @@ if (adapter->prev != NULL) adapter->prev->next = adapter->next; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - ifp->if_timer = 0; - IXGB_LOCK_DESTROY(adapter); return (0); } @@ -473,7 +471,7 @@ ETHER_BPF_MTAP(ifp, m_head); #endif /* Set timeout in case hardware has problems transmitting */ - ifp->if_timer = IXGB_TX_TIMEOUT; + adapter->tx_timer = IXGB_TX_TIMEOUT; } return; @@ -610,26 +608,24 @@ **********************************************************************/ static void -ixgb_watchdog(struct ifnet * ifp) +ixgb_watchdog(struct adapter *adapter) { - struct adapter *adapter; - adapter = ifp->if_softc; + struct ifnet *ifp; + + ifp = adapter->ifp; /* * If we are in this routine because of pause frames, then don't * reset the hardware. */ if (IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF) { - ifp->if_timer = IXGB_TX_TIMEOUT; + adapter->tx_timer = IXGB_TX_TIMEOUT; return; } if_printf(ifp, "watchdog timeout -- resetting\n"); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - - ixgb_stop(adapter); - ixgb_init(adapter); + ixgb_init_locked(adapter); ifp->if_oerrors++; @@ -713,7 +709,7 @@ temp_reg |= IXGB_CTRL0_JFE; IXGB_WRITE_REG(&adapter->hw, CTRL0, temp_reg); } - callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, adapter); + callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter); ixgb_clear_hw_cntrs(&adapter->hw); #ifdef DEVICE_POLLING /* @@ -753,11 +749,8 @@ if (cmd == POLL_AND_CHECK_STATUS) { reg_icr = IXGB_READ_REG(&adapter->hw, ICR); if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) { - callout_stop(&adapter->timer); ixgb_check_for_link(&adapter->hw); ixgb_print_link_status(adapter); - callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, - adapter); } } rx_npkts = ixgb_process_receive_interrupts(adapter, count); @@ -830,11 +823,8 @@ /* Link status change */ if (reg_icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC)) { - callout_stop(&adapter->timer); ixgb_check_for_link(&adapter->hw); ixgb_print_link_status(adapter); - callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, - adapter); } while (loop_cnt > 0) { if (ifp->if_drv_flags & IFF_DRV_RUNNING) { @@ -1123,7 +1113,7 @@ struct adapter *adapter = arg; ifp = adapter->ifp; - IXGB_LOCK(adapter); + IXGB_LOCK_ASSERT(adapter); ixgb_check_for_link(&adapter->hw); ixgb_print_link_status(adapter); @@ -1131,10 +1121,9 @@ if (ixgb_display_debug_stats && ifp->if_drv_flags & IFF_DRV_RUNNING) { ixgb_print_hw_stats(adapter); } - callout_reset(&adapter->timer, 2 * hz, ixgb_local_timer, adapter); - - IXGB_UNLOCK(adapter); - return; + if (adapter->tx_timer != 0 && --adapter->tx_timer == 0) + ixgb_watchdog(adapter); + callout_reset(&adapter->timer, hz, ixgb_local_timer, adapter); } static void @@ -1183,9 +1172,9 @@ ixgb_free_transmit_structures(adapter); ixgb_free_receive_structures(adapter); - /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + adapter->tx_timer = 0; return; } @@ -1352,7 +1341,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ixgb_ioctl; ifp->if_start = ixgb_start; - ifp->if_watchdog = ixgb_watchdog; ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1; #if __FreeBSD_version < 500000 @@ -1755,9 +1743,9 @@ ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; if (num_avail == adapter->num_tx_desc) - ifp->if_timer = 0; + adapter->tx_timer = 0; else if (num_avail == adapter->num_tx_desc_avail) - ifp->if_timer = IXGB_TX_TIMEOUT; + adapter->tx_timer = IXGB_TX_TIMEOUT; } adapter->num_tx_desc_avail = num_avail; return; --- //depot/vendor/freebsd/src/sys/dev/ixgb/if_ixgb.h 2009/11/06 14:55:14 +++ //depot/user/jhb/cleanup/sys/dev/ixgb/if_ixgb.h 2009/11/06 15:02:44 @@ -284,6 +284,7 @@ struct ifmedia media; struct callout timer; int io_rid; + int tx_timer; struct mtx mtx; /* Info about the board itself */ --- //depot/vendor/freebsd/src/sys/dev/lge/if_lge.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/lge/if_lge.c 2009/11/06 15:35:53 @@ -137,7 +137,7 @@ static void lge_init(void *); static void lge_init_locked(struct lge_softc *); static void lge_stop(struct lge_softc *); -static void lge_watchdog(struct ifnet *); +static void lge_watchdog(struct lge_softc *); static int lge_shutdown(device_t); static int lge_ifmedia_upd(struct ifnet *); static void lge_ifmedia_upd_locked(struct ifnet *); @@ -544,7 +544,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = lge_ioctl; ifp->if_start = lge_start; - ifp->if_watchdog = lge_watchdog; ifp->if_init = lge_init; ifp->if_snd.ifq_maxlen = LGE_TX_LIST_CNT - 1; ifp->if_capabilities = IFCAP_RXCSUM; @@ -1000,7 +999,7 @@ ifp = sc->lge_ifp; /* Clear the timeout timer. */ - ifp->if_timer = 0; + sc->lge_timer = 0; /* * Go through our tx list and free mbufs for those @@ -1021,7 +1020,7 @@ txdone--; LGE_INC(idx, LGE_TX_LIST_CNT); - ifp->if_timer = 0; + sc->lge_timer = 0; } sc->lge_cdata.lge_tx_cons = idx; @@ -1064,6 +1063,8 @@ } } + if (sc->lge_timer != 0 && --sc->lge_timer == 0) + lge_watchdog(sc); callout_reset(&sc->lge_stat_callout, hz, lge_tick, sc); return; @@ -1236,7 +1237,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->lge_timer = 5; return; } @@ -1506,14 +1507,14 @@ } static void -lge_watchdog(ifp) +lge_watchdog(sc) + struct lge_softc *sc; +{ struct ifnet *ifp; -{ - struct lge_softc *sc; - sc = ifp->if_softc; + LGE_LOCK_ASSERT(sc); + ifp = sc->lge_ifp; - LGE_LOCK(sc); ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); @@ -1524,9 +1525,6 @@ if (ifp->if_snd.ifq_head != NULL) lge_start_locked(ifp); - LGE_UNLOCK(sc); - - return; } /* @@ -1542,7 +1540,7 @@ LGE_LOCK_ASSERT(sc); ifp = sc->lge_ifp; - ifp->if_timer = 0; + sc->lge_timer = 0; callout_stop(&sc->lge_stat_callout); CSR_WRITE_4(sc, LGE_IMR, LGE_IMR_INTR_ENB); --- //depot/vendor/freebsd/src/sys/dev/lge/if_lgereg.h 2006/09/15 15:22:43 +++ //depot/user/jhb/cleanup/sys/dev/lge/if_lgereg.h 2009/10/05 19:04:20 @@ -534,6 +534,7 @@ u_int8_t lge_link; u_int8_t lge_pcs; int lge_if_flags; + int lge_timer; struct lge_list_data *lge_ldata; struct lge_ring_data lge_cdata; struct callout lge_stat_callout; --- //depot/vendor/freebsd/src/sys/dev/lmc/if_lmc.c 2009/05/30 18:40:23 +++ //depot/user/jhb/cleanup/sys/dev/lmc/if_lmc.c 2009/10/05 19:43:45 @@ -4642,8 +4642,9 @@ /* Called from a softirq once a second. */ static void -lmc_ifnet_watchdog(struct ifnet *ifp) +lmc_watchdog(void *arg) { + struct ifnet *ifp = arg; softc_t *sc = IFP2SC(ifp); u_int8_t old_oper_status = sc->status.oper_status; struct event_cntrs *cntrs = &sc->status.cntrs; @@ -4734,7 +4735,7 @@ # endif /* Call this procedure again after one second. */ - ifp->if_timer = 1; + callout_reset(&sc->callout, hz, lmc_watchdog, ifp); } # ifdef __OpenBSD__ @@ -4822,8 +4823,6 @@ ifp->if_start = lmc_ifnet_start; /* sppp changes this */ ifp->if_output = lmc_raw_output; /* sppp & p2p change this */ ifp->if_input = lmc_raw_input; - ifp->if_watchdog = lmc_ifnet_watchdog; - ifp->if_timer = 1; ifp->if_mtu = MAX_DESC_LEN; /* sppp & p2p change this */ ifp->if_type = IFT_PTPSERIAL; /* p2p changes this */ @@ -4917,6 +4916,8 @@ } # endif /* __OpenBSD__ */ + callout_reset(&sc->callout, hz, lmc_watchdog, sc); + return 0; } @@ -5244,7 +5245,7 @@ sc->status.line_prot = 0; /* Call this procedure again after one second. */ - callout_reset(&sc->ng_callout, hz, ng_watchdog, sc); + callout_reset(&sc->callout, hz, ng_watchdog, sc); } # endif @@ -5301,16 +5302,9 @@ IFQ_SET_MAXLEN(&sc->ng_sndq, SNDQ_MAXLEN); IFQ_SET_READY(&sc->ng_sndq); - /* If ifnet is present, it will call watchdog. */ - /* Otherwise, arrange to call watchdog here. */ # if (IFNET == 0) /* Arrange to call ng_watchdog() once a second. */ -# if (__FreeBSD_version >= 500000) - callout_init(&sc->ng_callout, 0); -# else /* FreeBSD-4 */ - callout_init(&sc->ng_callout); -# endif - callout_reset(&sc->ng_callout, hz, ng_watchdog, sc); + callout_reset(&sc->callout, hz, ng_watchdog, sc); # endif return 0; @@ -5319,9 +5313,7 @@ static void ng_detach(softc_t *sc) { -# if (IFNET == 0) - callout_stop(&sc->ng_callout); -# endif + callout_drain(&sc->callout); # if (__FreeBSD_version >= 500000) mtx_destroy(&sc->ng_sndq.ifq_mtx); mtx_destroy(&sc->ng_fastq.ifq_mtx); @@ -5493,6 +5485,12 @@ /* Start the card. */ if ((error = startup_card(sc))) return error; +# if (__FreeBSD_version >= 500000) + callout_init(&sc->callout, 0); +# else /* FreeBSD-4 */ + callout_init(&sc->callout); +# endif + /* Attach a kernel interface. */ #if NETGRAPH if ((error = ng_attach(sc))) return error; --- //depot/vendor/freebsd/src/sys/dev/lmc/if_lmc.h 2009/05/30 18:40:23 +++ //depot/user/jhb/cleanup/sys/dev/lmc/if_lmc.h 2009/10/05 19:43:45 @@ -1140,7 +1140,6 @@ #endif #if NETGRAPH - struct callout ng_callout; /* ng_watchdog needs this */ node_p ng_node; /* pointer to our node struct */ hook_p ng_hook; /* non-zero means NETGRAPH owns device */ # if (__FreeBSD_version >= 503000) @@ -1153,6 +1152,7 @@ #endif #ifdef __FreeBSD__ + struct callout callout; /* watchdog needs this */ struct device *dev; /* base device pointer */ bus_space_tag_t csr_tag; /* bus_space needs this */ bus_space_handle_t csr_handle;/* bus_space_needs this */ @@ -1596,7 +1596,6 @@ static void lmc_ifnet_start(struct ifnet *); static int lmc_raw_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct route *); -static void lmc_ifnet_watchdog(struct ifnet *); # ifdef __OpenBSD__ static int ifmedia_change(struct ifnet *); static void ifmedia_status(struct ifnet *, struct ifmediareq *); --- //depot/vendor/freebsd/src/sys/dev/malo/if_malo.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/malo/if_malo.c 2009/11/06 15:35:53 @@ -135,7 +135,7 @@ 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 @@ 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 @@ 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, IFQ_MAXLEN); @@ -1076,7 +1076,7 @@ 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_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 @@ } 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 @@ 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 @@ * 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 @@ * 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); --- //depot/vendor/freebsd/src/sys/dev/malo/if_malo.h 2009/05/20 20:05:15 +++ //depot/user/jhb/cleanup/sys/dev/malo/if_malo.h 2009/10/05 20:33:26 @@ -550,6 +550,8 @@ 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; --- //depot/vendor/freebsd/src/sys/dev/mwl/if_mwl.c 2009/09/23 17:50:15 +++ //depot/user/jhb/cleanup/sys/dev/mwl/if_mwl.c 2009/11/06 17:18:04 @@ -98,7 +98,7 @@ 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 @@ 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 @@ 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, IFQ_MAXLEN); @@ -558,6 +558,7 @@ * 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 @@ 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 @@ * 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); } } @@ -3411,7 +3414,7 @@ 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; @@ -3558,7 +3561,7 @@ 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); @@ -3624,7 +3627,7 @@ 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 @@ -4770,10 +4773,17 @@ #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"); --- //depot/vendor/freebsd/src/sys/dev/mwl/if_mwlvar.h 2009/07/05 18:00:16 +++ //depot/user/jhb/cleanup/sys/dev/mwl/if_mwlvar.h 2009/10/05 20:43:47 @@ -255,6 +255,8 @@ 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 */ --- //depot/vendor/freebsd/src/sys/dev/my/if_my.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/my/if_my.c 2009/11/04 15:56:21 @@ -126,7 +126,8 @@ static void my_init(void *); static void my_init_locked(struct my_softc *); static void my_stop(struct my_softc *); -static void my_watchdog(struct ifnet *); +static void my_autoneg_timeout(void *); +static void my_watchdog(void *); static int my_shutdown(device_t); static int my_ifmedia_upd(struct ifnet *); static void my_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -382,7 +383,16 @@ return; } +static void +my_autoneg_timeout(void *arg) +{ + struct my_softc *sc; + sc = arg; + MY_LOCK_ASSERT(sc); + my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1); +} + /* * Invoke autonegotiation on a PHY. */ @@ -439,12 +449,13 @@ return; } my_autoneg_xmit(sc); - ifp->if_timer = 5; + callout_reset(&sc->my_autoneg_timer, hz * 5, my_autoneg_timeout, + sc); sc->my_autoneg = 1; sc->my_want_auto = 0; return; case MY_FLAG_DELAYTIMEO: - ifp->if_timer = 0; + callout_stop(&sc->my_autoneg_timer); sc->my_autoneg = 0; break; default: @@ -661,7 +672,8 @@ */ if (sc->my_autoneg) { device_printf(sc->my_dev, "canceling autoneg session\n"); - ifp->if_timer = sc->my_autoneg = sc->my_want_auto = 0; + callout_stop(&sc->my_autoneg_timer); + sc->my_autoneg = sc->my_want_auto = 0; bmcr = my_phy_readreg(sc, PHY_BMCR); bmcr &= ~PHY_BMCR_AUTONEGENBL; my_phy_writereg(sc, PHY_BMCR, bmcr); @@ -808,6 +820,8 @@ sc->my_dev = dev; mtx_init(&sc->my_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); + callout_init_mtx(&sc->my_autoneg_timer, &sc->my_mtx, 0); + callout_init_mtx(&sc->my_watchdog, &sc->my_mtx, 0); /* * Map control/status registers. @@ -886,7 +900,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = my_ioctl; ifp->if_start = my_start; - ifp->if_watchdog = my_watchdog; ifp->if_init = my_init; ifp->if_baudrate = 10000000; IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); @@ -984,13 +997,15 @@ struct ifnet *ifp; sc = device_get_softc(dev); + ifp = sc->my_ifp; + ether_ifdetach(ifp); MY_LOCK(sc); my_stop(sc); MY_UNLOCK(sc); bus_teardown_intr(dev, sc->my_irq, sc->my_intrhand); + callout_drain(&sc->my_watchdog); + callout_drain(&sc->my_autoneg_timer); - ifp = sc->my_ifp; - ether_ifdetach(ifp); if_free(ifp); free(sc->my_ldata_ptr, M_DEVBUF); @@ -1188,7 +1203,7 @@ MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; /* Clear the timeout timer. */ - ifp->if_timer = 0; + sc->my_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { return; } @@ -1240,7 +1255,7 @@ MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; - ifp->if_timer = 0; + sc->my_timer = 0; if (sc->my_cdata.my_tx_head == NULL) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->my_cdata.my_tx_tail = NULL; @@ -1249,7 +1264,7 @@ } else { if (MY_TXOWN(sc->my_cdata.my_tx_head) == MY_UNSENT) { MY_TXOWN(sc->my_cdata.my_tx_head) = MY_OWNByNIC; - ifp->if_timer = 5; + sc->my_timer = 5; CSR_WRITE_4(sc, MY_TXPDR, 0xFFFFFFFF); } } @@ -1455,7 +1470,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->my_timer = 5; return; } @@ -1555,6 +1570,8 @@ my_phy_writereg(sc, PHY_BMCR, phy_bmcr); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + callout_reset(&sc->my_watchdog, hz, my_watchdog, sc); return; } @@ -1680,17 +1697,18 @@ } static void -my_watchdog(struct ifnet * ifp) +my_watchdog(void *arg) { struct my_softc *sc; + struct ifnet *ifp; - sc = ifp->if_softc; - MY_LOCK(sc); - if (sc->my_autoneg) { - my_autoneg_mii(sc, MY_FLAG_DELAYTIMEO, 1); - MY_UNLOCK(sc); + sc = arg; + MY_LOCK_ASSERT(sc); + callout_reset(&sc->my_watchdog, hz, my_watchdog, sc); + if (sc->my_timer == 0 || --sc->my_timer > 0) return; - } + + ifp = sc->my_ifp; ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); if (!(my_phy_readreg(sc, PHY_BMSR) & PHY_BMSR_LINKSTAT)) @@ -1700,8 +1718,6 @@ my_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) my_start_locked(ifp); - MY_UNLOCK(sc); - return; } @@ -1716,7 +1732,9 @@ MY_LOCK_ASSERT(sc); ifp = sc->my_ifp; - ifp->if_timer = 0; + + callout_stop(&sc->my_autoneg_timer); + callout_stop(&sc->my_watchdog); MY_CLRBIT(sc, MY_TCRRCR, (MY_RE | MY_TE)); CSR_WRITE_4(sc, MY_IMR, 0x00000000); --- //depot/vendor/freebsd/src/sys/dev/my/if_myreg.h 2006/09/15 15:17:40 +++ //depot/user/jhb/cleanup/sys/dev/my/if_myreg.h 2009/11/04 13:53:22 @@ -371,8 +371,10 @@ struct my_chain_data my_cdata; device_t my_miibus; /* Add by Surfer 2001/12/2 */ - struct mtx my_mtx; - + struct mtx my_mtx; + struct callout my_autoneg_timer; + struct callout my_watchdog; + int my_timer; }; /* Add by Surfer 2001/12/2 */ --- //depot/vendor/freebsd/src/sys/dev/nve/if_nve.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/nve/if_nve.c 2009/11/04 15:56:55 @@ -140,7 +140,7 @@ static void nve_intr(void *); static void nve_tick(void *); static void nve_setmulti(struct nve_softc *); -static void nve_watchdog(struct ifnet *); +static void nve_watchdog(struct nve_softc *); static void nve_update_stats(struct nve_softc *); static int nve_ifmedia_upd(struct ifnet *); @@ -540,8 +540,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nve_ioctl; ifp->if_start = nve_ifstart; - ifp->if_watchdog = nve_watchdog; - ifp->if_timer = 0; ifp->if_init = nve_init; ifp->if_mtu = ETHERMTU; ifp->if_baudrate = IF_Mbps(100); @@ -709,7 +707,7 @@ DEBUGOUT(NVE_DEBUG_RUNNING, "nve: nve_stop - entry\n"); ifp = sc->ifp; - ifp->if_timer = 0; + sc->tx_timer = 0; /* Cancel tick timer */ callout_stop(&sc->stat_callout); @@ -983,7 +981,7 @@ return; } /* Set watchdog timer. */ - ifp->if_timer = 8; + sc->tx_timer = 8; /* Copy packet to BPF tap */ BPF_MTAP(ifp, m0); @@ -1095,7 +1093,7 @@ /* If no pending packets we don't need a timeout */ if (sc->pending_txs == 0) - sc->ifp->if_timer = 0; + sc->tx_timer = 0; NVE_UNLOCK(sc); DEBUGOUT(NVE_DEBUG_INTERRUPT, "nve: nve_intr - exit\n"); @@ -1236,6 +1234,9 @@ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) nve_ifstart_locked(ifp); } + + if (sc->tx_timer > 0 && --sc->tx_timer == 0) + nve_watchdog(sc); callout_reset(&sc->stat_callout, hz, nve_tick, sc); return; @@ -1307,12 +1308,13 @@ /* Watchdog timer to prevent PHY lockups */ static void -nve_watchdog(struct ifnet *ifp) +nve_watchdog(struct nve_softc *sc) { - struct nve_softc *sc = ifp->if_softc; + struct ifnet *ifp; int pending_txs_start; - NVE_LOCK(sc); + NVE_LOCK_ASSERT(sc); + ifp = sc->ifp; /* * The nvidia driver blob defers tx completion notifications. @@ -1328,24 +1330,18 @@ sc->hwapi->pfnDisableInterrupts(sc->hwapi->pADCX); sc->hwapi->pfnHandleInterrupt(sc->hwapi->pADCX); sc->hwapi->pfnEnableInterrupts(sc->hwapi->pADCX); - if (sc->pending_txs < pending_txs_start) { - NVE_UNLOCK(sc); + if (sc->pending_txs < pending_txs_start) return; - } device_printf(sc->dev, "device timeout (%d)\n", sc->pending_txs); sc->tx_errors++; nve_stop(sc); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; nve_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) nve_ifstart_locked(ifp); - NVE_UNLOCK(sc); - - return; } /* --- Start of NVOSAPI interface --- */ --- //depot/vendor/freebsd/src/sys/dev/nve/if_nvereg.h 2008/05/31 14:20:16 +++ //depot/user/jhb/cleanup/sys/dev/nve/if_nvereg.h 2009/11/04 15:56:55 @@ -138,6 +138,7 @@ device_t miibus; device_t dev; struct callout stat_callout; + int tx_timer; void *sc_ih; bus_space_tag_t sc_st; --- //depot/vendor/freebsd/src/sys/dev/pcn/if_pcn.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/pcn/if_pcn.c 2009/11/04 16:14:22 @@ -143,7 +143,7 @@ static void pcn_init(void *); static void pcn_init_locked(struct pcn_softc *); static void pcn_stop(struct pcn_softc *); -static void pcn_watchdog(struct ifnet *); +static void pcn_watchdog(struct pcn_softc *); static int pcn_shutdown(device_t); static int pcn_ifmedia_upd(struct ifnet *); static void pcn_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -630,7 +630,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = pcn_ioctl; ifp->if_start = pcn_start; - ifp->if_watchdog = pcn_watchdog; ifp->if_init = pcn_init; ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1; @@ -948,7 +947,7 @@ sc->pcn_cdata.pcn_tx_cons = idx; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } - ifp->if_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5; + sc->pcn_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5; return; } @@ -980,6 +979,8 @@ pcn_start_locked(ifp); } + if (sc->pcn_timer > 0 && --sc->pcn_timer == 0) + pcn_watchdog(sc); callout_reset(&sc->pcn_stat_callout, hz, pcn_tick, sc); return; @@ -1147,7 +1148,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->pcn_timer = 5; return; } @@ -1429,14 +1430,12 @@ } static void -pcn_watchdog(ifp) +pcn_watchdog(struct pcn_softc *sc) +{ struct ifnet *ifp; -{ - struct pcn_softc *sc; - sc = ifp->if_softc; - - PCN_LOCK(sc); + PCN_LOCK_ASSERT(sc); + ifp = sc->pcn_ifp; ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); @@ -1447,10 +1446,6 @@ if (ifp->if_snd.ifq_head != NULL) pcn_start_locked(ifp); - - PCN_UNLOCK(sc); - - return; } /* @@ -1465,7 +1460,7 @@ PCN_LOCK_ASSERT(sc); ifp = sc->pcn_ifp; - ifp->if_timer = 0; + sc->pcn_timer = 0; callout_stop(&sc->pcn_stat_callout); --- //depot/vendor/freebsd/src/sys/dev/pcn/if_pcnreg.h 2008/08/14 20:40:15 +++ //depot/user/jhb/cleanup/sys/dev/pcn/if_pcnreg.h 2009/11/04 16:14:22 @@ -465,6 +465,7 @@ struct pcn_ring_data pcn_cdata; struct callout pcn_stat_callout; struct mtx pcn_mtx; + int pcn_timer; }; #define PCN_LOCK(_sc) mtx_lock(&(_sc)->pcn_mtx) --- //depot/vendor/freebsd/src/sys/dev/pdq/if_fea.c 2007/02/23 20:16:55 +++ //depot/user/jhb/cleanup/sys/dev/pdq/if_fea.c 2009/11/05 16:29:35 @@ -163,11 +163,9 @@ pdq_eisa_ifintr(arg) void * arg; { - device_t dev; pdq_softc_t * sc; - dev = (device_t)arg; - sc = device_get_softc(dev); + sc = arg; PDQ_LOCK(sc); (void) pdq_interrupt(sc->sc_pdq); @@ -181,11 +179,9 @@ device_t dev; { pdq_softc_t * sc; - struct ifnet * ifp; int error; sc = device_get_softc(dev); - ifp = sc->ifp; sc->dev = dev; @@ -222,28 +218,20 @@ goto bad; } - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - pdq_eisa_devinit(sc); - sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, - ifp->if_xname, -1, - (void *)sc, PDQ_DEFEA); - if (sc->sc_pdq == NULL) { - device_printf(dev, "Initialization failed.\n"); - error = ENXIO; + error = pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, + PDQ_DEFEA); + if (error) goto bad; - } - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, - NULL, pdq_eisa_ifintr, dev, &sc->irq_ih); + error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, + NULL, pdq_eisa_ifintr, sc, &sc->irq_ih); if (error) { device_printf(dev, "Failed to setup interrupt handler.\n"); - error = ENXIO; - goto bad; + pdq_ifdetach(sc); + return (error); } - pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes); - return (0); bad: pdq_free(dev); @@ -269,7 +257,9 @@ pdq_softc_t * sc; sc = device_get_softc(dev); + PDQ_LOCK(sc); pdq_hwreset(sc->sc_pdq); + PDQ_UNLOCK(sc); return (0); } --- //depot/vendor/freebsd/src/sys/dev/pdq/if_fpa.c 2009/06/11 17:15:20 +++ //depot/user/jhb/cleanup/sys/dev/pdq/if_fpa.c 2009/11/05 16:29:35 @@ -73,11 +73,9 @@ static void pdq_pci_ifintr(void *arg) { - device_t dev; pdq_softc_t *sc; - dev = (device_t)arg; - sc = device_get_softc(dev); + sc = arg; PDQ_LOCK(sc); (void) pdq_interrupt(sc->sc_pdq); @@ -105,12 +103,10 @@ pdq_pci_attach(device_t dev) { pdq_softc_t *sc; - struct ifnet *ifp; u_int32_t command; int error; sc = device_get_softc(dev); - ifp = sc->ifp; sc->dev = dev; @@ -146,26 +142,18 @@ goto bad; } - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - - sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, - ifp->if_xname, -1, - (void *)sc, PDQ_DEFPA); - if (sc->sc_pdq == NULL) { - device_printf(dev, "Initialization failed.\n"); - error = ENXIO; + error = pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, PDQ_DEFPA); + if (error) goto bad; - } - - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, NULL, - pdq_pci_ifintr, dev, &sc->irq_ih); + + error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, + pdq_pci_ifintr, sc, &sc->irq_ih); if (error) { device_printf(dev, "Failed to setup interrupt handler.\n"); - error = ENXIO; - goto bad; + pdq_ifdetach(sc); + return (error); } - pdq_ifattach(sc, sc->sc_pdq->pdq_hwaddr.lanaddr_bytes); return (0); bad: @@ -191,7 +179,9 @@ pdq_softc_t *sc; sc = device_get_softc(dev); + PDQ_LOCK(sc); pdq_hwreset(sc->sc_pdq); + PDQ_UNLOCK(sc); return (0); } --- //depot/vendor/freebsd/src/sys/dev/pdq/pdq_freebsd.h 2006/05/16 14:41:44 +++ //depot/user/jhb/cleanup/sys/dev/pdq/pdq_freebsd.h 2009/11/05 16:29:35 @@ -124,10 +124,13 @@ void * irq_ih; struct mtx mtx; + struct callout watchdog; + int timer; } pdq_softc_t; #define PDQ_LOCK(_sc) mtx_lock(&(_sc)->mtx) #define PDQ_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) +#define PDQ_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) #define PDQ_OS_HDR_OFFSET PDQ_RX_FC_OFFSET @@ -255,7 +258,8 @@ * OS dependent functions provided by * pdq_ifsubr.c or pdq.c to the bus front ends */ -void pdq_ifattach (pdq_softc_t *, const pdq_uint8_t *); +int pdq_ifattach (pdq_softc_t *, const pdq_uint8_t *, + pdq_type_t type); void pdq_ifdetach (pdq_softc_t *); void pdq_free (device_t); int pdq_interrupt (pdq_t *pdq); --- //depot/vendor/freebsd/src/sys/dev/pdq/pdq_ifsubr.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/pdq/pdq_ifsubr.c 2009/11/05 16:29:35 @@ -69,10 +69,23 @@ devclass_t pdq_devclass; +static void pdq_watchdog(void *); + static void -pdq_ifinit( - pdq_softc_t *sc) +pdq_ifstop(pdq_softc_t *sc) +{ + + PDQ_IFNET(sc)->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_pdq->pdq_flags &= ~PDQ_RUNNING; + pdq_stop(sc->sc_pdq); + callout_stop(&sc->watchdog); +} + +static void +pdq_ifinit_locked(pdq_softc_t *sc) { + + PDQ_LOCK_ASSERT(sc); if (PDQ_IFNET(sc)->if_flags & IFF_UP) { PDQ_IFNET(sc)->if_drv_flags |= IFF_DRV_RUNNING; if (PDQ_IFNET(sc)->if_flags & IFF_PROMISC) { @@ -87,24 +100,40 @@ } sc->sc_pdq->pdq_flags |= PDQ_RUNNING; pdq_run(sc->sc_pdq); - } else { - PDQ_IFNET(sc)->if_drv_flags &= ~IFF_DRV_RUNNING; - sc->sc_pdq->pdq_flags &= ~PDQ_RUNNING; - pdq_stop(sc->sc_pdq); - } + callout_reset(&sc->watchdog, hz, pdq_watchdog, sc); + } else + pdq_ifstop(sc); +} + +static void +pdq_ifinit(void *arg) +{ + pdq_softc_t *sc; + + sc = arg; + PDQ_LOCK(sc); + pdq_ifinit_locked(sc); + PDQ_UNLOCK(sc); } static void -pdq_ifwatchdog( - struct ifnet *ifp) +pdq_watchdog(void *arg) { + pdq_softc_t *sc; + struct ifnet *ifp; + + sc = arg; + PDQ_LOCK_ASSERT(sc); + callout_reset(&sc->watchdog, hz, pdq_watchdog, sc); + if (sc->timer == 0 || --sc->timer > 0) + return; + /* * No progress was made on the transmit queue for PDQ_OS_TX_TRANSMIT * seconds. Remove all queued packets. */ - + ifp = PDQ_IFNET(sc); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_timer = 0; for (;;) { struct mbuf *m; IFQ_DEQUEUE(&ifp->if_snd, m); @@ -115,18 +144,18 @@ } static void -pdq_ifstart( - struct ifnet *ifp) +pdq_ifstart_locked(struct ifnet *ifp) { pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp); struct mbuf *m; int tx = 0; + PDQ_LOCK_ASSERT(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - if (PDQ_IFNET(sc)->if_timer == 0) - PDQ_IFNET(sc)->if_timer = PDQ_OS_TX_TIMEOUT; + if (sc->timer == 0) + sc->timer = PDQ_OS_TX_TIMEOUT; if ((sc->sc_pdq->pdq_flags & PDQ_TXOK) == 0) { PDQ_IFNET(sc)->if_drv_flags |= IFF_DRV_OACTIVE; @@ -177,6 +206,16 @@ PDQ_DO_TYPE2_PRODUCER(sc->sc_pdq); sc->sc_flags &= ~PDQIF_DOWNCALL; } + +static void +pdq_ifstart(struct ifnet *ifp) +{ + pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp); + + PDQ_LOCK(sc); + pdq_ifstart_locked(ifp); + PDQ_UNLOCK(sc); +} void pdq_os_receive_pdu( @@ -218,7 +257,9 @@ } m->m_pkthdr.rcvif = ifp; + PDQ_UNLOCK(sc); (*ifp->if_input)(ifp, m); + PDQ_LOCK(sc); } void @@ -228,11 +269,11 @@ pdq_softc_t *sc = pdq->pdq_os_ctx; PDQ_IFNET(sc)->if_drv_flags &= ~IFF_DRV_OACTIVE; if (IFQ_IS_EMPTY(&PDQ_IFNET(sc)->if_snd) == 0) { - PDQ_IFNET(sc)->if_timer = PDQ_OS_TX_TIMEOUT; + sc->timer = PDQ_OS_TX_TIMEOUT; if ((sc->sc_flags & PDQIF_DOWNCALL) == 0) - pdq_ifstart(PDQ_IFNET(sc)); + pdq_ifstart_locked(PDQ_IFNET(sc)); } else { - PDQ_IFNET(sc)->if_timer = 0; + sc->timer = 0; } } @@ -305,6 +346,7 @@ { pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp); + PDQ_LOCK(sc); if (sc->sc_ifmedia.ifm_media & IFM_FDX) { if ((sc->sc_pdq->pdq_flags & PDQ_WANT_FDX) == 0) { sc->sc_pdq->pdq_flags |= PDQ_WANT_FDX; @@ -316,6 +358,7 @@ if (sc->sc_pdq->pdq_flags & PDQ_RUNNING) pdq_run(sc->sc_pdq); } + PDQ_UNLOCK(sc); return 0; } @@ -327,6 +370,7 @@ { pdq_softc_t * const sc = PDQ_OS_IFP_TO_SOFTC(ifp); + PDQ_LOCK(sc); ifmr->ifm_status = IFM_AVALID; if (sc->sc_pdq->pdq_flags & PDQ_IS_ONRING) ifmr->ifm_status |= IFM_ACTIVE; @@ -334,6 +378,7 @@ ifmr->ifm_active = (ifmr->ifm_current & ~IFM_FDX); if (sc->sc_pdq->pdq_flags & PDQ_IS_FDX) ifmr->ifm_active |= IFM_FDX; + PDQ_UNLOCK(sc); } void @@ -369,8 +414,6 @@ pdq_softc_t *sc = PDQ_OS_IFP_TO_SOFTC(ifp); int error = 0; - PDQ_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: { pdq_ifinit(sc); @@ -379,10 +422,12 @@ case SIOCADDMULTI: case SIOCDELMULTI: { + PDQ_LOCK(sc); if (PDQ_IFNET(sc)->if_drv_flags & IFF_DRV_RUNNING) { pdq_run(sc->sc_pdq); error = 0; } + PDQ_UNLOCK(sc); break; } @@ -401,7 +446,6 @@ } } - PDQ_UNLOCK(sc); return error; } @@ -409,25 +453,27 @@ #define IFF_NOTRAILERS 0 #endif -void -pdq_ifattach(pdq_softc_t *sc, const pdq_uint8_t *llc) +int +pdq_ifattach(pdq_softc_t *sc, const pdq_uint8_t *llc, pdq_type_t type) { struct ifnet *ifp; ifp = PDQ_IFNET(sc) = if_alloc(IFT_FDDI); - if (ifp == NULL) - panic("%s: can not if_alloc()", device_get_nameunit(sc->dev)); + if (ifp == NULL) { + device_printf(sc->dev, "can not if_alloc()\n"); + return (ENOSPC); + } mtx_init(&sc->mtx, device_get_nameunit(sc->dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); + callout_init_mtx(&sc->watchdog, &sc->mtx, 0); + if_initname(ifp, device_get_name(sc->dev), device_get_unit(sc->dev)); ifp->if_softc = sc; - ifp->if_init = (if_init_f_t *)pdq_ifinit; + ifp->if_init = pdq_ifinit; ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST; - ifp->if_watchdog = pdq_ifwatchdog; - ifp->if_ioctl = pdq_ifioctl; ifp->if_start = pdq_ifstart; @@ -441,7 +487,15 @@ } #endif + sc->sc_pdq = pdq_initialize(sc->mem_bst, sc->mem_bsh, ifp->if_xname, -1, + sc, type); + if (sc->sc_pdq == NULL) { + device_printf(sc->dev, "Initialization failed.\n"); + return (ENXIO); + } + fddi_ifattach(ifp, llc, FDDI_BPF_SUPPORTED); + return (0); } void @@ -452,8 +506,10 @@ ifp = sc->ifp; fddi_ifdetach(ifp, FDDI_BPF_SUPPORTED); - if_free(ifp); - pdq_stop(sc->sc_pdq); + PDQ_LOCK(sc); + pdq_ifstop(sc); + PDQ_UNLOCK(sc); + callout_drain(&sc->watchdog); pdq_free(sc->dev); return; @@ -474,6 +530,8 @@ bus_teardown_intr(dev, sc->irq, sc->irq_ih); if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); + if (sc->ifp) + if_free(sc->ifp); /* * Destroy the mutex. --- //depot/vendor/freebsd/src/sys/dev/sn/if_sn.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/sn/if_sn.c 2009/11/05 17:17:17 @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,7 @@ 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 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_LOCK_INIT(sc); + callout_init_mtx(&sc->watchdog, &sc->sc_mtx, 0); snstop(sc); sc->pages_wanted = -1; @@ -202,13 +205,11 @@ 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, IFQ_MAXLEN); ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - ifp->if_timer = 0; ether_ifattach(ifp, eaddr); @@ -233,9 +234,11 @@ struct sn_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->ifp; + ether_ifdetach(ifp); + SN_LOCK(sc); snstop(sc); - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - ether_ifdetach(ifp); + SN_UNLOCK(sc); + callout_drain(&sc->watchdog); sn_deactivate(dev); if_free(ifp); SN_LOCK_DESTROY(sc); @@ -342,6 +345,7 @@ */ 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 @@ 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 @@ 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 @@ 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 @@ * 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) { + 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 sn_softc *sc = (struct sn_softc *) arg; struct ifnet *ifp = sc->ifp; /* @@ -783,12 +795,10 @@ 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 @@ 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 @@ 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 @@ } 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 @@ /* * Cancel watchdog. */ - ifp->if_timer = 0; + sc->timer = 0; + callout_stop(&sc->watchdog); + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); } @@ -1220,8 +1237,6 @@ sn_deactivate(dev); return ENOMEM; } - sc->bst = rman_get_bustag(sc->port_res); - sc->bsh = rman_get_bushandle(sc->port_res); return (0); } --- //depot/vendor/freebsd/src/sys/dev/sn/if_sn_pccard.c 2005/09/13 19:30:22 +++ //depot/user/jhb/cleanup/sys/dev/sn/if_sn_pccard.c 2009/11/05 17:17:17 @@ -271,8 +271,6 @@ sn_deactivate(dev); return ENOMEM; } - sc->bst = rman_get_bustag(sc->port_res); - sc->bsh = rman_get_bushandle(sc->port_res); return 0; } --- //depot/vendor/freebsd/src/sys/dev/sn/if_snvar.h 2005/09/15 19:35:18 +++ //depot/user/jhb/cleanup/sys/dev/sn/if_snvar.h 2009/11/05 17:17:17 @@ -32,9 +32,9 @@ struct sn_softc { struct ifnet *ifp; - 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; @@ -55,20 +55,20 @@ int sn_activate(device_t); void sn_deactivate(device_t); -#define CSR_READ_1(sc, off) (bus_space_read_1((sc)->bst, (sc)->bsh, off)) -#define CSR_READ_2(sc, off) (bus_space_read_2((sc)->bst, (sc)->bsh, off)) +#define CSR_READ_1(sc, off) (bus_read_1((sc)->port_res, off)) +#define CSR_READ_2(sc, off) (bus_read_2((sc)->port_res, off)) #define CSR_WRITE_1(sc, off, val) \ - bus_space_write_1(sc->bst, sc->bsh, off, val) + bus_write_1((sc)->port_res, off, val) #define CSR_WRITE_2(sc, off, val) \ - bus_space_write_2(sc->bst, sc->bsh, off, val) + bus_write_2((sc)->port_res, off, val) #define CSR_WRITE_MULTI_1(sc, off, addr, count) \ - bus_space_write_multi_1(sc->bst, sc->bsh, off, addr, count) + bus_write_multi_1((sc)->port_res, off, addr, count) #define CSR_WRITE_MULTI_2(sc, off, addr, count) \ - bus_space_write_multi_2(sc->bst, sc->bsh, off, addr, count) + bus_write_multi_2((sc)->port_res, off, addr, count) #define CSR_READ_MULTI_1(sc, off, addr, count) \ - bus_space_read_multi_1(sc->bst, sc->bsh, off, addr, count) + bus_read_multi_1((sc)->port_res, off, addr, count) #define CSR_READ_MULTI_2(sc, off, addr, count) \ - bus_space_read_multi_2(sc->bst, sc->bsh, off, addr, count) + bus_read_multi_2((sc)->port_res, off, addr, count) #define SN_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define SN_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) --- //depot/vendor/freebsd/src/sys/dev/ste/if_ste.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/ste/if_ste.c 2009/11/05 19:24:07 @@ -108,7 +108,7 @@ static int ste_encap(struct ste_softc *, struct ste_chain *, struct mbuf *); static void ste_start(struct ifnet *); static void ste_start_locked(struct ifnet *); -static void ste_watchdog(struct ifnet *); +static void ste_watchdog(struct ste_softc *); static int ste_shutdown(device_t); static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *, struct mbuf *); @@ -924,7 +924,7 @@ sc->ste_cdata.ste_tx_cons = idx; if (idx == sc->ste_cdata.ste_tx_prod) - ifp->if_timer = 0; + sc->ste_timer = 0; } static void @@ -960,6 +960,8 @@ } } + if (sc->ste_timer > 0 && --sc->ste_timer == 0) + ste_watchdog(sc); callout_reset(&sc->ste_stat_callout, hz, ste_stats_update, sc); return; @@ -1094,7 +1096,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = ste_ioctl; ifp->if_start = ste_start; - ifp->if_watchdog = ste_watchdog; ifp->if_init = ste_init; IFQ_SET_MAXLEN(&ifp->if_snd, STE_TX_LIST_CNT - 1); ifp->if_snd.ifq_drv_maxlen = STE_TX_LIST_CNT - 1; @@ -1159,11 +1160,11 @@ /* These should only be active if attach succeeded */ if (device_is_attached(dev)) { + ether_ifdetach(ifp); STE_LOCK(sc); ste_stop(sc); STE_UNLOCK(sc); callout_drain(&sc->ste_stat_callout); - ether_ifdetach(ifp); } if (sc->ste_miibus) device_delete_child(dev, sc->ste_miibus); @@ -1708,7 +1709,7 @@ BPF_MTAP(ifp, cur_tx->ste_mbuf); STE_INC(idx, STE_TX_LIST_CNT); - ifp->if_timer = 5; + sc->ste_timer = 5; } sc->ste_cdata.ste_tx_prod = idx; @@ -1716,13 +1717,12 @@ } static void -ste_watchdog(ifp) +ste_watchdog(struct ste_softc *sc) +{ struct ifnet *ifp; -{ - struct ste_softc *sc; - sc = ifp->if_softc; - STE_LOCK(sc); + ifp = sc->ste_ifp; + STE_LOCK_ASSERT(sc); ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); @@ -1736,7 +1736,6 @@ if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) ste_start_locked(ifp); - STE_UNLOCK(sc); return; } --- //depot/vendor/freebsd/src/sys/dev/ste/if_stereg.h 2008/08/14 20:15:14 +++ //depot/user/jhb/cleanup/sys/dev/ste/if_stereg.h 2009/11/05 19:24:07 @@ -517,6 +517,7 @@ int ste_tx_thresh; u_int8_t ste_link; int ste_if_flags; + int ste_timer; struct ste_chain *ste_tx_prev; struct ste_list_data *ste_ldata; struct ste_chain_data ste_cdata; --- //depot/vendor/freebsd/src/sys/dev/ti/if_ti.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/ti/if_ti.c 2009/11/05 19:43:32 @@ -194,7 +194,7 @@ 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 *); @@ -2285,6 +2285,7 @@ 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) { @@ -2486,7 +2487,6 @@ 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_mtu = ETHERMTU; @@ -2565,24 +2565,22 @@ { 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) + if (device_is_attached(dev)) { + ether_ifdetach(ifp); + TI_LOCK(sc); ti_stop(sc); - TI_UNLOCK(sc); - if (attached) - ether_ifdetach(ifp); + 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); @@ -2866,7 +2864,7 @@ } 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 @@ -3121,7 +3119,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->ti_timer = 5; } } @@ -3225,6 +3223,7 @@ 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 @@ -3786,30 +3785,31 @@ } 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); } /* @@ -3859,6 +3859,7 @@ sc->ti_tx_saved_considx = TI_TXCONS_UNSET; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + callout_stop(&sc->ti_watchdog); } /* --- //depot/vendor/freebsd/src/sys/dev/ti/if_tireg.h 2006/01/03 06:15:46 +++ //depot/user/jhb/cleanup/sys/dev/ti/if_tireg.h 2009/11/05 19:43:32 @@ -1038,6 +1038,8 @@ 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; }; --- //depot/vendor/freebsd/src/sys/dev/tl/if_tl.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/tl/if_tl.c 2009/11/05 19:57:31 @@ -281,7 +281,7 @@ static void tl_init(void *); static void tl_init_locked(struct tl_softc *); static void tl_stop(struct tl_softc *); -static void tl_watchdog(struct ifnet *); +static void tl_watchdog(struct tl_softc *); static int tl_shutdown(device_t); static int tl_ifmedia_upd(struct ifnet *); static void tl_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -1170,9 +1170,6 @@ goto fail; } - sc->tl_btag = rman_get_bustag(sc->tl_res); - sc->tl_bhandle = rman_get_bushandle(sc->tl_res); - #ifdef notdef /* * The ThunderLAN manual suggests jacking the PCI latency @@ -1263,7 +1260,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = tl_ioctl; ifp->if_start = tl_start; - ifp->if_watchdog = tl_watchdog; ifp->if_init = tl_init; ifp->if_mtu = ETHERMTU; ifp->if_snd.ifq_maxlen = TL_TX_LIST_CNT - 1; @@ -1340,11 +1336,11 @@ /* These should only be active if attach succeeded */ if (device_is_attached(dev)) { + ether_ifdetach(ifp); TL_LOCK(sc); tl_stop(sc); TL_UNLOCK(sc); callout_drain(&sc->tl_stat_callout); - ether_ifdetach(ifp); } if (sc->tl_miibus) device_delete_child(dev, sc->tl_miibus); @@ -1638,7 +1634,7 @@ ifp = sc->tl_ifp; /* Clear the timeout timer. */ - ifp->if_timer = 0; + sc->tl_timer = 0; if (sc->tl_cdata.tl_tx_head == NULL) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1824,6 +1820,9 @@ } } + if (sc->tl_timer > 0 && --sc->tl_timer == 0) + tl_watchdog(sc); + callout_reset(&sc->tl_stat_callout, hz, tl_stats_update, sc); if (!sc->tl_bitrate) { @@ -2032,7 +2031,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->tl_timer = 5; return; } @@ -2257,21 +2256,20 @@ } static void -tl_watchdog(ifp) +tl_watchdog(sc) + struct tl_softc *sc; +{ struct ifnet *ifp; -{ - struct tl_softc *sc; - sc = ifp->if_softc; + TL_LOCK_ASSERT(sc); + ifp = sc->tl_ifp; if_printf(ifp, "device timeout\n"); - TL_LOCK(sc); ifp->if_oerrors++; tl_softreset(sc, 1); tl_init_locked(sc); - TL_UNLOCK(sc); return; } --- //depot/vendor/freebsd/src/sys/dev/tl/if_tlreg.h 2008/08/14 20:05:14 +++ //depot/user/jhb/cleanup/sys/dev/tl/if_tlreg.h 2009/11/05 19:57:31 @@ -112,8 +112,6 @@ struct ifnet *tl_ifp; device_t tl_dev; struct ifmedia ifmedia; /* media info */ - bus_space_handle_t tl_bhandle; - bus_space_tag_t tl_btag; void *tl_intrhand; struct resource *tl_irq; struct resource *tl_res; @@ -127,6 +125,7 @@ int tl_if_flags; struct callout tl_stat_callout; struct mtx tl_mtx; + int tl_timer; }; #define TL_LOCK(_sc) mtx_lock(&(_sc)->tl_mtx) @@ -493,19 +492,13 @@ /* * register space access macros */ -#define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->tl_btag, sc->tl_bhandle, reg, val) -#define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->tl_btag, sc->tl_bhandle, reg, val) -#define CSR_WRITE_1(sc, reg, val) \ - bus_space_write_1(sc->tl_btag, sc->tl_bhandle, reg, val) +#define CSR_WRITE_4(sc, reg, val) bus_write_4(sc->tl_res, reg, val) +#define CSR_WRITE_2(sc, reg, val) bus_write_2(sc->tl_res, reg, val) +#define CSR_WRITE_1(sc, reg, val) bus_write_1(sc->tl_res, reg, val) -#define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->tl_btag, sc->tl_bhandle, reg) -#define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->tl_btag, sc->tl_bhandle, reg) -#define CSR_READ_1(sc, reg) \ - bus_space_read_1(sc->tl_btag, sc->tl_bhandle, reg) +#define CSR_READ_4(sc, reg) bus_read_4(sc->tl_res, reg) +#define CSR_READ_2(sc, reg) bus_read_2(sc->tl_res, reg) +#define CSR_READ_1(sc, reg) bus_read_1(sc->tl_res, reg) #define CMD_PUT(sc, x) CSR_WRITE_4(sc, TL_HOSTCMD, x) #define CMD_SET(sc, x) \ --- //depot/vendor/freebsd/src/sys/dev/vge/if_vge.c 2009/11/06 14:55:14 +++ //depot/user/jhb/cleanup/sys/dev/vge/if_vge.c 2009/11/06 15:02:44 @@ -93,7 +93,6 @@ #include #include #include -#include #include #include @@ -160,12 +159,13 @@ static void vge_txeof (struct vge_softc *); static void vge_intr (void *); static void vge_tick (void *); -static void vge_tx_task (void *, int); static void vge_start (struct ifnet *); +static void vge_start_locked (struct ifnet *); static int vge_ioctl (struct ifnet *, u_long, caddr_t); static void vge_init (void *); +static void vge_init_locked (struct vge_softc *); static void vge_stop (struct vge_softc *); -static void vge_watchdog (struct ifnet *); +static void vge_watchdog (void *); static int vge_suspend (device_t); static int vge_resume (device_t); static int vge_shutdown (device_t); @@ -378,7 +378,7 @@ if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F)) return(0); - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); vge_miipoll_stop(sc); /* Specify the register we want to read. */ @@ -400,7 +400,6 @@ rval = CSR_READ_2(sc, VGE_MIIDATA); vge_miipoll_start(sc); - VGE_UNLOCK(sc); return (rval); } @@ -418,7 +417,7 @@ if (phy != (CSR_READ_1(sc, VGE_MIICFG) & 0x1F)) return(0); - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); vge_miipoll_stop(sc); /* Specify the register we want to write. */ @@ -443,7 +442,6 @@ } vge_miipoll_start(sc); - VGE_UNLOCK(sc); return (rval); } @@ -929,7 +927,9 @@ sc->vge_dev = dev; mtx_init(&sc->vge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); + callout_init_mtx(&sc->vge_watchdog, &sc->vge_mtx, 0); + /* * Map control/status registers. */ @@ -945,9 +945,6 @@ goto fail; } - sc->vge_btag = rman_get_bustag(sc->vge_res); - sc->vge_bhandle = rman_get_bushandle(sc->vge_res); - /* Allocate interrupt */ rid = 0; sc->vge_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, @@ -1017,14 +1014,11 @@ #ifdef DEVICE_POLLING ifp->if_capabilities |= IFCAP_POLLING; #endif - ifp->if_watchdog = vge_watchdog; ifp->if_init = vge_init; IFQ_SET_MAXLEN(&ifp->if_snd, VGE_IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = VGE_IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - TASK_INIT(&sc->vge_txtask, 0, vge_tx_task, ifp); - /* * Call MI attach routine. */ @@ -1073,21 +1067,11 @@ /* These should only be active if attach succeeded */ if (device_is_attached(dev)) { + ether_ifdetach(ifp); + VGE_LOCK(sc); vge_stop(sc); - /* - * Force off the IFF_UP flag here, in case someone - * still had a BPF descriptor attached to this - * interface. If they do, ether_ifattach() will cause - * the BPF code to try and clear the promisc mode - * flag, which will bubble down to vge_ioctl(), - * which will try to call vge_init() again. This will - * turn the NIC back on and restart the MII ticker, - * which will panic the system when the kernel tries - * to invoke the vge_tick() function that isn't there - * anymore. - */ - ifp->if_flags &= ~IFF_UP; - ether_ifdetach(ifp); + VGE_UNLOCK(sc); + callout_drain(&sc->vge_watchdog); } if (sc->vge_miibus) device_delete_child(dev, sc->vge_miibus); @@ -1526,7 +1510,7 @@ if (idx != sc->vge_ldata.vge_tx_considx) { sc->vge_ldata.vge_tx_considx = idx; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_timer = 0; + sc->vge_timer = 0; } /* @@ -1552,7 +1536,7 @@ sc = xsc; ifp = sc->vge_ifp; - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); mii = device_get_softc(sc->vge_miibus); mii_tick(mii); @@ -1569,13 +1553,10 @@ if_link_state_change(sc->vge_ifp, LINK_STATE_UP); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(taskqueue_swi, - &sc->vge_txtask); + vge_start_locked(ifp); } } - VGE_UNLOCK(sc); - return; } @@ -1595,7 +1576,7 @@ vge_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(taskqueue_swi, &sc->vge_txtask); + vge_start_locked(ifp); if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */ u_int32_t status; @@ -1611,7 +1592,7 @@ if (status & VGE_ISR_TXDMA_STALL || status & VGE_ISR_RXDMA_STALL) - vge_init(sc); + vge_init_locked(sc); if (status & (VGE_ISR_RXOFLOW|VGE_ISR_RXNODESC)) { vge_rxeof(sc); @@ -1684,7 +1665,7 @@ vge_txeof(sc); if (status & (VGE_ISR_TXDMA_STALL|VGE_ISR_RXDMA_STALL)) - vge_init(sc); + vge_init_locked(sc); if (status & VGE_ISR_LINKSTS) vge_tick(sc); @@ -1693,11 +1674,11 @@ /* Re-enable interrupts */ CSR_WRITE_1(sc, VGE_CRS3, VGE_CR3_INT_GMSK); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + vge_start_locked(ifp); + VGE_UNLOCK(sc); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(taskqueue_swi, &sc->vge_txtask); - return; } @@ -1777,25 +1758,24 @@ return (0); } +/* + * Main transmit routine. + */ + static void -vge_tx_task(arg, npending) - void *arg; - int npending; +vge_start(ifp) + struct ifnet *ifp; { - struct ifnet *ifp; + struct vge_softc *sc; - ifp = arg; - vge_start(ifp); - - return; + sc = ifp->if_softc; + VGE_LOCK(sc); + vge_start_locked(ifp); + VGE_UNLOCK(sc); } -/* - * Main transmit routine. - */ - static void -vge_start(ifp) +vge_start_locked(ifp) struct ifnet *ifp; { struct vge_softc *sc; @@ -1803,17 +1783,13 @@ int idx, pidx = 0; sc = ifp->if_softc; - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); - if (!sc->vge_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) { - VGE_UNLOCK(sc); + if (!sc->vge_link || ifp->if_drv_flags & IFF_DRV_OACTIVE) return; - } - if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { - VGE_UNLOCK(sc); + if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) return; - } idx = sc->vge_ldata.vge_tx_prodidx; @@ -1846,10 +1822,8 @@ ETHER_BPF_MTAP(ifp, m_head); } - if (idx == sc->vge_ldata.vge_tx_prodidx) { - VGE_UNLOCK(sc); + if (idx == sc->vge_ldata.vge_tx_prodidx) return; - } /* Flush the TX descriptors */ @@ -1873,12 +1847,10 @@ */ CSR_WRITE_1(sc, VGE_CRS1, VGE_CR1_TIMER0_ENABLE); - VGE_UNLOCK(sc); - /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->vge_timer = 5; return; } @@ -1888,11 +1860,20 @@ void *xsc; { struct vge_softc *sc = xsc; + + VGE_LOCK(sc); + vge_init_locked(sc); + VGE_UNLOCK(sc); +} + +static void +vge_init_locked(struct vge_softc *sc) +{ struct ifnet *ifp = sc->vge_ifp; struct mii_data *mii; int i; - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); mii = device_get_softc(sc->vge_miibus); /* @@ -2048,12 +2029,11 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc); sc->vge_if_flags = 0; sc->vge_link = 0; - VGE_UNLOCK(sc); - return; } @@ -2090,7 +2070,9 @@ sc = ifp->if_softc; mii = device_get_softc(sc->vge_miibus); + VGE_LOCK(sc); mii_pollstat(mii); + VGE_UNLOCK(sc); ifmr->ifm_active = mii->mii_media_active; ifmr->ifm_status = mii->mii_media_status; @@ -2165,6 +2147,7 @@ ifp->if_mtu = ifr->ifr_mtu; break; case SIOCSIFFLAGS: + VGE_LOCK(sc); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING && ifp->if_flags & IFF_PROMISC && @@ -2179,16 +2162,19 @@ VGE_RXCTL_RX_PROMISC); vge_setmulti(sc); } else - vge_init(sc); + vge_init_locked(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) vge_stop(sc); } sc->vge_if_flags = ifp->if_flags; + VGE_UNLOCK(sc); break; case SIOCADDMULTI: case SIOCDELMULTI: + VGE_LOCK(sc); vge_setmulti(sc); + VGE_UNLOCK(sc); break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: @@ -2222,6 +2208,7 @@ } } #endif /* DEVICE_POLLING */ + VGE_LOCK(sc); if ((mask & IFCAP_TXCSUM) != 0 && (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { ifp->if_capenable ^= IFCAP_TXCSUM; @@ -2233,6 +2220,7 @@ if ((mask & IFCAP_RXCSUM) != 0 && (ifp->if_capabilities & IFCAP_RXCSUM) != 0) ifp->if_capenable ^= IFCAP_RXCSUM; + VGE_UNLOCK(sc); } break; default: @@ -2244,22 +2232,25 @@ } static void -vge_watchdog(ifp) - struct ifnet *ifp; +vge_watchdog(void *arg) { - struct vge_softc *sc; + struct vge_softc *sc; + struct ifnet *ifp; + + sc = arg; + VGE_LOCK_ASSERT(sc); + callout_reset(&sc->vge_watchdog, hz, vge_watchdog, sc); + if (sc->vge_timer == 0 || --sc->vge_timer > 0) + return; - sc = ifp->if_softc; - VGE_LOCK(sc); + ifp = sc->vge_ifp; if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; vge_txeof(sc); vge_rxeof(sc); - vge_init(sc); - - VGE_UNLOCK(sc); + vge_init_locked(sc); return; } @@ -2275,9 +2266,10 @@ register int i; struct ifnet *ifp; - VGE_LOCK(sc); + VGE_LOCK_ASSERT(sc); ifp = sc->vge_ifp; - ifp->if_timer = 0; + sc->vge_timer = 0; + callout_stop(&sc->vge_watchdog); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); @@ -2315,8 +2307,6 @@ } } - VGE_UNLOCK(sc); - return; } @@ -2333,9 +2323,11 @@ sc = device_get_softc(dev); + VGE_LOCK(sc); vge_stop(sc); sc->suspended = 1; + VGE_UNLOCK(sc); return (0); } @@ -2360,10 +2352,12 @@ pci_enable_io(dev, SYS_RES_MEMORY); /* reinitialize interface if necessary */ + VGE_LOCK(sc); if (ifp->if_flags & IFF_UP) - vge_init(sc); + vge_init_locked(sc); sc->suspended = 0; + VGE_UNLOCK(sc); return (0); } @@ -2380,7 +2374,9 @@ sc = device_get_softc(dev); + VGE_LOCK(sc); vge_stop(sc); + VGE_UNLOCK(sc); return (0); } --- //depot/vendor/freebsd/src/sys/dev/vge/if_vgevar.h 2009/11/06 14:55:14 +++ //depot/user/jhb/cleanup/sys/dev/vge/if_vgevar.h 2009/11/06 15:02:44 @@ -100,8 +100,6 @@ struct vge_softc { struct ifnet *vge_ifp; /* interface info */ device_t vge_dev; - bus_space_handle_t vge_bhandle; /* bus space handle */ - bus_space_tag_t vge_btag; /* bus space tag */ struct resource *vge_res; struct resource *vge_irq; void *vge_intrhand; @@ -113,8 +111,9 @@ int vge_rx_consumed; int vge_link; int vge_camidx; - struct task vge_txtask; struct mtx vge_mtx; + struct callout vge_watchdog; + int vge_timer; struct mbuf *vge_head; struct mbuf *vge_tail; @@ -134,20 +133,20 @@ * register space access macros */ #define CSR_WRITE_STREAM_4(sc, reg, val) \ - bus_space_write_stream_4(sc->vge_btag, sc->vge_bhandle, reg, val) + bus_write_stream_4(sc->vge_res, reg, val) #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->vge_btag, sc->vge_bhandle, reg, val) + bus_write_4(sc->vge_res, reg, val) #define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->vge_btag, sc->vge_bhandle, reg, val) + bus_write_2(sc->vge_res, reg, val) #define CSR_WRITE_1(sc, reg, val) \ - bus_space_write_1(sc->vge_btag, sc->vge_bhandle, reg, val) + bus_write_1(sc->vge_res, reg, val) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->vge_btag, sc->vge_bhandle, reg) + bus_read_4(sc->vge_res, reg) #define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->vge_btag, sc->vge_bhandle, reg) + bus_read_2(sc->vge_res, reg) #define CSR_READ_1(sc, reg) \ - bus_space_read_1(sc->vge_btag, sc->vge_bhandle, reg) + bus_read_1(sc->vge_res, reg) #define CSR_SETBIT_1(sc, reg, x) \ CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | (x)) --- //depot/vendor/freebsd/src/sys/dev/vx/if_vx.c 2008/04/24 22:57:29 +++ //depot/user/jhb/cleanup/sys/dev/vx/if_vx.c 2009/11/05 21:27:11 @@ -129,7 +129,7 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ /* 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 @@ CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */ ++ifp->if_opackets; - ifp->if_timer = 1; + sc->vx_timer = 1; readcheck: if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) { @@ -661,18 +662,18 @@ if (status & S_RX_COMPLETE) vx_read(sc); if (status & S_TX_AVAIL) { - ifp->if_timer = 0; + sc->vx_timer = 0; sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; vx_start_locked(sc->vx_ifp); } if (status & S_CARD_FAILURE) { if_printf(ifp, "adapter failure (%x)\n", status); - ifp->if_timer = 0; + sc->vx_timer = 0; vx_reset(sc); break; } if (status & S_TX_COMPLETE) { - ifp->if_timer = 0; + sc->vx_timer = 0; vx_txstat(sc); vx_start_locked(ifp); } @@ -970,26 +971,32 @@ } static void -vx_watchdog(struct ifnet *ifp) +vx_watchdog(void *arg) { - struct vx_softc *sc = ifp->if_softc; + struct vx_softc *sc; + struct ifnet *ifp; + + sc = arg; + VX_LOCK_ASSERT(sc); + callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc); + if (sc->vx_timer == 0 || --sc->vx_timer > 0) + return; - VX_LOCK(sc); + ifp = sc->vx_ifp; if (ifp->if_flags & IFF_DEBUG) if_printf(ifp, "device timeout\n"); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; vx_start_locked(ifp); vx_intr(sc); - VX_UNLOCK(sc); } void vx_stop(struct vx_softc *sc) { - struct ifnet *ifp = sc->vx_ifp; VX_LOCK_ASSERT(sc); - ifp->if_timer = 0; + sc->vx_timer = 0; + callout_stop(&sc->vx_watchdog); CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE); CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK); --- //depot/vendor/freebsd/src/sys/dev/vx/if_vxvar.h 2005/10/06 18:30:36 +++ //depot/user/jhb/cleanup/sys/dev/vx/if_vxvar.h 2009/11/05 21:27:11 @@ -51,8 +51,10 @@ int vx_tx_succ_ok; /* # packets sent in sequence */ /* w/o underrun */ struct callout vx_callout; /* Callout for timeouts */ + struct callout vx_watchdog; struct mtx vx_mtx; int vx_buffill_pending; + int vx_timer; }; #define CSR_WRITE_4(sc, reg, val) \ --- //depot/vendor/freebsd/src/sys/dev/wb/if_wb.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/dev/wb/if_wb.c 2009/11/05 21:37:39 @@ -158,7 +158,7 @@ static void wb_init(void *); static void wb_init_locked(struct wb_softc *); static void wb_stop(struct wb_softc *); -static void wb_watchdog(struct ifnet *); +static void wb_watchdog(struct wb_softc *); static int wb_shutdown(device_t); static int wb_ifmedia_upd(struct ifnet *); static void wb_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -804,9 +804,6 @@ goto fail; } - sc->wb_btag = rman_get_bustag(sc->wb_res); - sc->wb_bhandle = rman_get_bushandle(sc->wb_res); - /* Allocate interrupt */ rid = 0; sc->wb_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, @@ -852,7 +849,6 @@ ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = wb_ioctl; ifp->if_start = wb_start; - ifp->if_watchdog = wb_watchdog; ifp->if_init = wb_init; ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1; @@ -910,11 +906,11 @@ * This should only be done if attach succeeded. */ if (device_is_attached(dev)) { + ether_ifdetach(ifp); WB_LOCK(sc); wb_stop(sc); WB_UNLOCK(sc); callout_drain(&sc->wb_stat_callout); - ether_ifdetach(ifp); } if (sc->wb_miibus) device_delete_child(dev, sc->wb_miibus); @@ -1160,7 +1156,7 @@ ifp = sc->wb_ifp; /* Clear the timeout timer. */ - ifp->if_timer = 0; + sc->wb_timer = 0; if (sc->wb_cdata.wb_tx_head == NULL) return; @@ -1215,7 +1211,7 @@ ifp = sc->wb_ifp; - ifp->if_timer = 0; + sc->wb_timer = 0; if (sc->wb_cdata.wb_tx_head == NULL) { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1223,7 +1219,7 @@ } else { if (WB_TXOWN(sc->wb_cdata.wb_tx_head) == WB_UNSENT) { WB_TXOWN(sc->wb_cdata.wb_tx_head) = WB_TXSTAT_OWN; - ifp->if_timer = 5; + sc->wb_timer = 5; CSR_WRITE_4(sc, WB_TXSTART, 0xFFFFFFFF); } } @@ -1332,6 +1328,8 @@ mii_tick(mii); + if (sc->wb_timer > 0 && --sc->wb_timer == 0) + wb_watchdog(sc); callout_reset(&sc->wb_stat_callout, hz, wb_tick, sc); return; @@ -1532,7 +1530,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->wb_timer = 5; return; } @@ -1751,14 +1749,13 @@ } static void -wb_watchdog(ifp) +wb_watchdog(sc) + struct wb_softc *sc; +{ struct ifnet *ifp; -{ - struct wb_softc *sc; - sc = ifp->if_softc; - - WB_LOCK(sc); + WB_LOCK_ASSERT(sc); + ifp = sc->wb_ifp; ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); #ifdef foo @@ -1771,7 +1768,6 @@ if (ifp->if_snd.ifq_head != NULL) wb_start_locked(ifp); - WB_UNLOCK(sc); return; } @@ -1789,7 +1785,7 @@ WB_LOCK_ASSERT(sc); ifp = sc->wb_ifp; - ifp->if_timer = 0; + sc->wb_timer = 0; callout_stop(&sc->wb_stat_callout); --- //depot/vendor/freebsd/src/sys/dev/wb/if_wbreg.h 2008/08/14 21:30:14 +++ //depot/user/jhb/cleanup/sys/dev/wb/if_wbreg.h 2009/11/05 21:37:39 @@ -365,8 +365,6 @@ struct ifnet *wb_ifp; /* interface info */ device_t wb_dev; device_t wb_miibus; - bus_space_handle_t wb_bhandle; - bus_space_tag_t wb_btag; struct resource *wb_res; struct resource *wb_irq; void *wb_intrhand; @@ -374,6 +372,7 @@ u_int8_t wb_type; u_int16_t wb_txthresh; int wb_cachesize; + int wb_timer; caddr_t wb_ldata_ptr; struct wb_list_data *wb_ldata; struct wb_chain_data wb_cdata; @@ -388,19 +387,13 @@ /* * register space access macros */ -#define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->wb_btag, sc->wb_bhandle, reg, val) -#define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->wb_btag, sc->wb_bhandle, reg, val) -#define CSR_WRITE_1(sc, reg, val) \ - bus_space_write_1(sc->wb_btag, sc->wb_bhandle, reg, val) +#define CSR_WRITE_4(sc, reg, val) bus_write_4(sc->wb_res, reg, val) +#define CSR_WRITE_2(sc, reg, val) bus_write_2(sc->wb_res, reg, val) +#define CSR_WRITE_1(sc, reg, val) bus_write_1(sc->wb_res, reg, val) -#define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->wb_btag, sc->wb_bhandle, reg) -#define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->wb_btag, sc->wb_bhandle, reg) -#define CSR_READ_1(sc, reg) \ - bus_space_read_1(sc->wb_btag, sc->wb_bhandle, reg) +#define CSR_READ_4(sc, reg) bus_read_4(sc->wb_res, reg) +#define CSR_READ_2(sc, reg) bus_read_2(sc->wb_res, reg) +#define CSR_READ_1(sc, reg) bus_read_1(sc->wb_res, reg) #define WB_TIMEOUT 1000 --- //depot/vendor/freebsd/src/sys/dev/xen/netfront/netfront.c 2009/06/13 22:00:28 +++ //depot/user/jhb/cleanup/sys/dev/xen/netfront/netfront.c 2009/11/05 21:38:42 @@ -1056,7 +1056,6 @@ return; ifp = np->xn_ifp; - ifp->if_timer = 0; do { prod = np->tx.sring->rsp_prod; @@ -1948,9 +1947,6 @@ ifp->if_ioctl = xn_ioctl; ifp->if_output = ether_output; ifp->if_start = xn_start; -#ifdef notyet - ifp->if_watchdog = xn_watchdog; -#endif ifp->if_init = xn_ifinit; ifp->if_mtu = ETHERMTU; ifp->if_snd.ifq_maxlen = NET_TX_RING_SIZE - 1; --- //depot/vendor/freebsd/src/sys/mips/adm5120/if_admsw.c 2009/06/26 11:50:17 +++ //depot/user/jhb/cleanup/sys/mips/adm5120/if_admsw.c 2009/11/05 22:30:40 @@ -128,7 +128,7 @@ /* ifnet entry points */ static void admsw_start(struct ifnet *); -static void admsw_watchdog(struct ifnet *); +static void admsw_watchdog(void *); static int admsw_ioctl(struct ifnet *, u_long, caddr_t); static void admsw_init(void *); static void admsw_stop(struct ifnet *, int); @@ -398,6 +398,7 @@ device_printf(sc->sc_dev, "base Ethernet address %s\n", ether_sprintf(enaddr)); + callout_init(&sc->sc_watchdog, 1); rid = 0; if ((sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, @@ -536,8 +537,6 @@ ifp->if_ioctl = admsw_ioctl; ifp->if_output = ether_output; ifp->if_start = admsw_start; - ifp->if_watchdog = admsw_watchdog; - ifp->if_timer = 0; ifp->if_init = admsw_init; ifp->if_mtu = ETHERMTU; ifp->if_baudrate = IF_Mbps(100); @@ -733,7 +732,7 @@ BPF_MTAP(ifp, m0); /* Set a watchdog timer in case the chip flakes out. */ - sc->sc_ifnet[0]->if_timer = 5; + sc->sc_timer = 5; } } @@ -743,25 +742,29 @@ * Watchdog timer handler. */ static void -admsw_watchdog(struct ifnet *ifp) +admsw_watchdog(void *arg) { - struct admsw_softc *sc = ifp->if_softc; + struct admsw_softc *sc = arg; int vlan; + callout_reset(&sc->watchdog, hz, admsw_watchdog, sc); + if (sc->sc_timer == 0 || --sc->timer > 0) + return; + /* Check if an interrupt was lost. */ if (sc->sc_txfree == ADMSW_NTXLDESC) { device_printf(sc->sc_dev, "watchdog false alarm\n"); return; } - if (sc->sc_ifnet[0]->if_timer != 0) + if (sc->sc_timer != 0) device_printf(sc->sc_dev, "watchdog timer is %d!\n", - sc->sc_ifnet[0]->if_timer); + sc->sc_timer); admsw_txintr(sc, 0); if (sc->sc_txfree == ADMSW_NTXLDESC) { device_printf(sc->sc_dev, "tx IRQ lost (queue empty)\n"); return; } - if (sc->sc_ifnet[0]->if_timer != 0) { + if (sc->sc_timer != 0) { device_printf(sc->sc_dev, "tx IRQ lost (timer recharged)\n"); return; } @@ -938,7 +941,7 @@ * cancel the watchdog timer. */ if (sc->sc_txfree == ADMSW_NTXLDESC) - ifp->if_timer = 0; + sc->sc_timer = 0; } @@ -1096,6 +1099,9 @@ ~(ADMSW_INTR_SHD | ADMSW_INTR_SLD | ADMSW_INTR_RHD | ADMSW_INTR_RLD | ADMSW_INTR_HDF | ADMSW_INTR_LDF)); + + callout_reset(&sc->sc_watchdog, hz, + admsw_watchdog, sc); } sc->ndevs++; } @@ -1137,11 +1143,14 @@ /* disable interrupts */ REG_WRITE(ADMSW_INT_MASK, INT_MASK); + + /* Cancel the watchdog timer. */ + sc->sc_timer = 0; + callout_stop(&sc->sc_watchdog); } - /* Mark the interface as down and cancel the watchdog timer. */ + /* Mark the interface as down. */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - ifp->if_timer = 0; return; } --- //depot/vendor/freebsd/src/sys/mips/adm5120/if_admswvar.h 2008/09/10 03:51:01 +++ //depot/user/jhb/cleanup/sys/mips/adm5120/if_admswvar.h 2009/11/05 22:30:40 @@ -132,7 +132,9 @@ bus_dma_tag_t sc_bufs_dmat; /* bus DMA tag for buffers */ struct ifmedia sc_ifmedia[SW_DEVS]; int ndevs; /* number of IFF_RUNNING interfaces */ - struct ifnet *sc_ifnet[SW_DEVS]; + struct ifnet *sc_ifnet[SW_DEVS]; + struct callout sc_watchdog; + int sc_timer; /* Ethernet common data */ void *sc_ih; /* interrupt cookie */ struct resource *irq_res;