--- sys/dev/usb/if_axe.c.orig 2008-05-13 23:00:09.000000000 +0900 +++ sys/dev/usb/if_axe.c 2008-06-02 03:19:07.685569729 +0900 @@ -171,7 +171,7 @@ static int axe_ioctl(struct ifnet *, u_long, caddr_t); static void axe_init(void *); static void axe_stop(struct axe_softc *); -static void axe_watchdog(struct ifnet *); +static void axe_watchdog(struct axe_softc *); static int axe_cmd(struct axe_softc *, int, int, int, void *); static int axe_ifmedia_upd(struct ifnet *); static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); @@ -604,7 +604,7 @@ mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); - sx_init(&sc->axe_sleeplock, device_get_nameunit(self)); + sx_init(&sc->axe_sx, device_get_nameunit(self)); AXE_SLEEPLOCK(sc); AXE_LOCK(sc); @@ -640,7 +640,7 @@ device_printf(sc->axe_dev, "can not if_alloc()\n"); AXE_UNLOCK(sc); AXE_SLEEPUNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); + sx_destroy(&sc->axe_sx); mtx_destroy(&sc->axe_mtx); return ENXIO; } @@ -651,7 +651,6 @@ IFF_NEEDSGIANT; ifp->if_ioctl = axe_ioctl; ifp->if_start = axe_start; - ifp->if_watchdog = axe_watchdog; ifp->if_init = axe_init; IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; @@ -663,7 +662,7 @@ if_free(ifp); AXE_UNLOCK(sc); AXE_SLEEPUNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); + sx_destroy(&sc->axe_sx); mtx_destroy(&sc->axe_mtx); return ENXIO; } @@ -709,7 +708,7 @@ usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]); AXE_UNLOCK(sc); - sx_destroy(&sc->axe_sleeplock); + sx_destroy(&sc->axe_sx); mtx_destroy(&sc->axe_mtx); return(0); @@ -939,7 +938,7 @@ return; } - ifp->if_timer = 0; + sc->axe_timer = 0; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err); @@ -971,6 +970,8 @@ if (sc->axe_dying) return; + axe_watchdog(sc); + /* Perform periodic stuff in process context */ usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER); } @@ -1111,7 +1112,7 @@ /* * Set a timeout in case the chip goes out to lunch. */ - ifp->if_timer = 5; + sc->axe_timer = 5; AXE_UNLOCK(sc); return; @@ -1310,15 +1311,18 @@ } static void -axe_watchdog(struct ifnet *ifp) +axe_watchdog(struct axe_softc *sc) { - struct axe_softc *sc; + struct ifnet *ifp; struct axe_chain *c; usbd_status stat; - sc = ifp->if_softc; + ifp = sc->axe_ifp; AXE_LOCK(sc); + if (sc->axe_timer == 0 || --sc->axe_timer) + return; + ifp->if_oerrors++; device_printf(sc->axe_dev, "watchdog timeout\n"); @@ -1348,7 +1352,7 @@ AXE_LOCK(sc); ifp = sc->axe_ifp; - ifp->if_timer = 0; + sc->axe_timer = 0; untimeout(axe_tick, sc, sc->axe_stat_ch);