summaryrefslogtreecommitdiffstats
path: root/sys/dev/pcn
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-11-19 22:14:23 +0000
committerjhb <jhb@FreeBSD.org>2009-11-19 22:14:23 +0000
commit3593f855442b4c99d0bb2e5e2240edc25e4a9de9 (patch)
tree56a1666c810529df49b7c20e9c73407f13a80405 /sys/dev/pcn
parentaffabaa85e18565f9c0a68b33c5b0f2e0587f05a (diff)
downloadFreeBSD-src-3593f855442b4c99d0bb2e5e2240edc25e4a9de9.zip
FreeBSD-src-3593f855442b4c99d0bb2e5e2240edc25e4a9de9.tar.gz
- Hook into the existing stat timer to drive the transmit watchdog instead
of using if_watchdog and if_timer. - Reorder detach to call ether_ifdetach() before anything else in tl(4) and wb(4).
Diffstat (limited to 'sys/dev/pcn')
-rw-r--r--sys/dev/pcn/if_pcn.c25
-rw-r--r--sys/dev/pcn/if_pcnreg.h1
2 files changed, 11 insertions, 15 deletions
diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c
index c52c22b..6295a46 100644
--- a/sys/dev/pcn/if_pcn.c
+++ b/sys/dev/pcn/if_pcn.c
@@ -143,7 +143,7 @@ static int pcn_ioctl(struct ifnet *, u_long, caddr_t);
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 @@ pcn_attach(dev)
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 @@ pcn_txeof(sc)
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_tick(xsc)
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 @@ pcn_start_locked(ifp)
/*
* Set a timeout in case the chip goes out to lunch.
*/
- ifp->if_timer = 5;
+ sc->pcn_timer = 5;
return;
}
@@ -1429,14 +1430,12 @@ pcn_ioctl(ifp, command, data)
}
static void
-pcn_watchdog(ifp)
- struct ifnet *ifp;
+pcn_watchdog(struct pcn_softc *sc)
{
- struct pcn_softc *sc;
-
- sc = ifp->if_softc;
+ struct ifnet *ifp;
- PCN_LOCK(sc);
+ PCN_LOCK_ASSERT(sc);
+ ifp = sc->pcn_ifp;
ifp->if_oerrors++;
if_printf(ifp, "watchdog timeout\n");
@@ -1447,10 +1446,6 @@ pcn_watchdog(ifp)
if (ifp->if_snd.ifq_head != NULL)
pcn_start_locked(ifp);
-
- PCN_UNLOCK(sc);
-
- return;
}
/*
@@ -1465,7 +1460,7 @@ pcn_stop(struct pcn_softc *sc)
PCN_LOCK_ASSERT(sc);
ifp = sc->pcn_ifp;
- ifp->if_timer = 0;
+ sc->pcn_timer = 0;
callout_stop(&sc->pcn_stat_callout);
diff --git a/sys/dev/pcn/if_pcnreg.h b/sys/dev/pcn/if_pcnreg.h
index 406d438..a10edfd 100644
--- a/sys/dev/pcn/if_pcnreg.h
+++ b/sys/dev/pcn/if_pcnreg.h
@@ -465,6 +465,7 @@ struct pcn_softc {
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)
OpenPOWER on IntegriCloud