From owner-svn-src-head@FreeBSD.ORG Tue Nov 17 14:23:10 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 019E4106566B; Tue, 17 Nov 2009 14:23:10 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E45A58FC0C; Tue, 17 Nov 2009 14:23:09 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAHEN9oo011959; Tue, 17 Nov 2009 14:23:09 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAHEN98w011955; Tue, 17 Nov 2009 14:23:09 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200911171423.nAHEN98w011955@svn.freebsd.org> From: John Baldwin Date: Tue, 17 Nov 2009 14:23:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199380 - head/sys/dev/ed X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Nov 2009 14:23:10 -0000 Author: jhb Date: Tue Nov 17 14:23:09 2009 New Revision: 199380 URL: http://svn.freebsd.org/changeset/base/199380 Log: Use a private callout timer to drive the transmit watchdog instead of using if_watchdog and if_timer. The driver already contained an optional stats timer that individual attachments could use to provide a 'tick' event. The stats timer only ran if the tick function pointer was non-NULL and the attachment's tick routine had to call callout_reset(), etc. Now the driver always schedules a stat timer and manages the callout_reset() internally. This timer is used to drive the watchdog and will also call the attachment's 'tick' handler if one is provided. Tested by: WATANABE Kazuhiro Modified: head/sys/dev/ed/if_ed.c head/sys/dev/ed/if_ed_pccard.c head/sys/dev/ed/if_edvar.h Modified: head/sys/dev/ed/if_ed.c ============================================================================== --- head/sys/dev/ed/if_ed.c Tue Nov 17 14:14:07 2009 (r199379) +++ head/sys/dev/ed/if_ed.c Tue Nov 17 14:23:09 2009 (r199380) @@ -77,7 +77,8 @@ static int ed_ioctl(struct ifnet *, u_lo 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 @@ ed_attach(device_t dev) 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_detach(device_t dev) ed_stop(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ED_UNLOCK(sc); - callout_drain(&sc->tick_ch); ether_ifdetach(ifp); + callout_drain(&sc->tick_ch); } if (sc->irq_res != NULL && sc->irq_handle) bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); @@ -447,26 +447,42 @@ void ed_stop(struct ed_softc *sc) { ED_ASSERT_LOCKED(sc); - if (sc->sc_tick) - callout_stop(&sc->tick_ch); + 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) + 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); +} + +/* * Device timeout/watchdog routine. Entered if the device neglects to * 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 @@ ed_init_locked(struct ed_softc *sc) /* 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_init_locked(struct ed_softc *sc) */ 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 @@ ed_init_locked(struct ed_softc *sc) 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 @@ ed_xmit(struct ed_softc *sc) /* * 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 @@ edintr(void *arg) /* * clear watchdog timer */ - ifp->if_timer = 0; + sc->tx_timer = 0; /* * Add in total number of collisions on last Modified: head/sys/dev/ed/if_ed_pccard.c ============================================================================== --- head/sys/dev/ed/if_ed_pccard.c Tue Nov 17 14:14:07 2009 (r199379) +++ head/sys/dev/ed/if_ed_pccard.c Tue Nov 17 14:23:09 2009 (r199380) @@ -250,7 +250,7 @@ static const struct ed_product { */ 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 @@ ed_child_detached(device_t dev, device_t } 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 @@ ed_pccard_tick(void *arg) } } - callout_reset(&sc->tick_ch, hz, ed_pccard_tick, sc); } static device_method_t ed_pccard_methods[] = { Modified: head/sys/dev/ed/if_edvar.h ============================================================================== --- head/sys/dev/ed/if_edvar.h Tue Nov 17 14:14:07 2009 (r199379) +++ head/sys/dev/ed/if_edvar.h Tue Nov 17 14:23:09 2009 (r199380) @@ -65,11 +65,12 @@ struct ed_softc { 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 */