summaryrefslogtreecommitdiffstats
path: root/sys/dev/cm/smc90cx6.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
committerjhb <jhb@FreeBSD.org>2009-11-19 22:06:40 +0000
commitaffabaa85e18565f9c0a68b33c5b0f2e0587f05a (patch)
tree8407585eec2a1c0c6cadd011a7eb682949649bde /sys/dev/cm/smc90cx6.c
parentd49024b6f48c6368a3af0f695133bdc2a695e281 (diff)
downloadFreeBSD-src-affabaa85e18565f9c0a68b33c5b0f2e0587f05a.zip
FreeBSD-src-affabaa85e18565f9c0a68b33c5b0f2e0587f05a.tar.gz
- Add a private timer to drive the transmit watchdog instead of using
if_watchdog and if_timer. - Fix some issues in detach for sn(4), ste(4), and ti(4). Primarily this means calling ether_ifdetach() before anything else.
Diffstat (limited to 'sys/dev/cm/smc90cx6.c')
-rw-r--r--sys/dev/cm/smc90cx6.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/sys/dev/cm/smc90cx6.c b/sys/dev/cm/smc90cx6.c
index 1dda17f..a0dedd9 100644
--- a/sys/dev/cm/smc90cx6.c
+++ b/sys/dev/cm/smc90cx6.c
@@ -124,7 +124,7 @@ static void cm_reset_locked(struct cm_softc *);
void cm_start(struct ifnet *);
void cm_start_locked(struct ifnet *);
int cm_ioctl(struct ifnet *, unsigned long, caddr_t);
-void cm_watchdog(struct ifnet *);
+void cm_watchdog(void *);
void cm_srint_locked(void *vsc);
static void cm_tint_locked(struct cm_softc *, int);
void cm_reconwatch_locked(void *);
@@ -194,11 +194,9 @@ cm_attach(dev)
ifp->if_output = arc_output;
ifp->if_start = cm_start;
ifp->if_ioctl = cm_ioctl;
- ifp->if_watchdog = cm_watchdog;
ifp->if_init = cm_init;
/* XXX IFQ_SET_READY(&ifp->if_snd); */
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
- ifp->if_timer = 0;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
arc_ifattach(ifp, linkaddress);
@@ -210,6 +208,7 @@ cm_attach(dev)
#endif
callout_init_mtx(&sc->sc_recon_ch, &sc->sc_mtx, 0);
+ callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
if_printf(ifp, "link addr 0x%02x (%d)\n", linkaddress, linkaddress);
return 0;
@@ -315,6 +314,7 @@ cm_reset_locked(sc)
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
cm_start_locked(ifp);
}
@@ -332,7 +332,8 @@ cm_stop_locked(sc)
GETREG(CMRESET);
/* Stop watchdog timer */
- sc->sc_ifp->if_timer = 0;
+ callout_stop(&sc->sc_watchdog_timer);
+ sc->sc_timer = 0;
}
void
@@ -464,7 +465,7 @@ cm_start_locked(ifp)
PUTREG(CMCMD, CM_TX(buffer));
PUTREG(CMSTAT, sc->sc_intmask);
- ifp->if_timer = ARCTIMEOUT;
+ sc->sc_timer = ARCTIMEOUT;
}
m_freem(m);
@@ -627,7 +628,7 @@ cm_tint_locked(sc, isr)
if (isr & CM_TMA || sc->sc_broadcast[buffer])
ifp->if_opackets++;
#ifdef CMRETRANSMIT
- else if (ifp->if_flags & IFF_LINK2 && ifp->if_timer > 0
+ else if (ifp->if_flags & IFF_LINK2 && sc->sc_timer > 0
&& --sc->sc_retransmits[buffer] > 0) {
/* retransmit same buffer */
PUTREG(CMCMD, CM_TX(buffer));
@@ -657,7 +658,7 @@ cm_tint_locked(sc, isr)
*/
PUTREG(CMCMD, CM_TX(buffer));
/* init watchdog timer */
- ifp->if_timer = ARCTIMEOUT;
+ sc->sc_timer = ARCTIMEOUT;
#if defined(CM_DEBUG) && (CM_DEBUG > 1)
if_printf(ifp,
@@ -669,7 +670,7 @@ cm_tint_locked(sc, isr)
sc->sc_intmask &= ~CM_TA;
PUTREG(CMSTAT, sc->sc_intmask);
/* ... and watchdog timer */
- ifp->if_timer = 0;
+ sc->sc_timer = 0;
#ifdef CM_DEBUG
if_printf(ifp, "tint: no more buffers to send, status 0x%02x\n",
@@ -920,12 +921,13 @@ cm_ioctl(ifp, command, data)
* retransmission is implemented).
*/
void
-cm_watchdog(ifp)
- struct ifnet *ifp;
+cm_watchdog(void *arg)
{
- struct cm_softc *sc = ifp->if_softc;
+ struct cm_softc *sc;
- CM_LOCK(sc);
+ sc = arg;
+ callout_reset(&sc->sc_watchdog_timer, hz, cm_watchdog, sc);
+ if (sc->sc_timer == 0 || --sc->sc_timer > 0)
+ return;
PUTREG(CMCMD, CM_TXDIS);
- CM_UNLOCK(sc);
}
OpenPOWER on IntegriCloud