summaryrefslogtreecommitdiffstats
path: root/sys/dev/sk
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2007-04-02 04:43:41 +0000
committeryongari <yongari@FreeBSD.org>2007-04-02 04:43:41 +0000
commit78e041986d28eb106928e5dbef14e924aefbbcc5 (patch)
treea18a03d8514d3ec65b3edfa4a6e3e8dc9bb3ee78 /sys/dev/sk
parentb975b5f5f0f06cdd1235d5fa049cb2510ed3cd91 (diff)
downloadFreeBSD-src-78e041986d28eb106928e5dbef14e924aefbbcc5.zip
FreeBSD-src-78e041986d28eb106928e5dbef14e924aefbbcc5.tar.gz
Use our own timer for watchdog instead of if_watchdog/if_timer
interface.
Diffstat (limited to 'sys/dev/sk')
-rw-r--r--sys/dev/sk/if_sk.c30
-rw-r--r--sys/dev/sk/if_skreg.h2
2 files changed, 24 insertions, 8 deletions
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index 83ec4b7..605fb61 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -217,7 +217,7 @@ static void sk_init_locked(struct sk_if_softc *);
static void sk_init_xmac(struct sk_if_softc *);
static void sk_init_yukon(struct sk_if_softc *);
static void sk_stop(struct sk_if_softc *);
-static void sk_watchdog(struct ifnet *);
+static void sk_watchdog(void *);
static int sk_ifmedia_upd(struct ifnet *);
static void sk_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static void sk_reset(struct sk_softc *);
@@ -1368,6 +1368,7 @@ sk_attach(dev)
sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1;
callout_init_mtx(&sc_if->sk_tick_ch, &sc_if->sk_softc->sk_mtx, 0);
+ callout_init_mtx(&sc_if->sk_watchdog_ch, &sc_if->sk_softc->sk_mtx, 0);
if (sk_dma_alloc(sc_if) != 0) {
error = ENOMEM;
@@ -1397,7 +1398,8 @@ sk_attach(dev)
ifp->if_capenable = ifp->if_capabilities;
ifp->if_ioctl = sk_ioctl;
ifp->if_start = sk_start;
- ifp->if_watchdog = sk_watchdog;
+ ifp->if_timer = 0;
+ ifp->if_watchdog = NULL;
ifp->if_init = sk_init;
IFQ_SET_MAXLEN(&ifp->if_snd, SK_TX_RING_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = SK_TX_RING_CNT - 1;
@@ -1839,6 +1841,7 @@ sk_detach(dev)
/* Can't hold locks while calling detach */
SK_IF_UNLOCK(sc_if);
callout_drain(&sc_if->sk_tick_ch);
+ callout_drain(&sc_if->sk_watchdog_ch);
ether_ifdetach(ifp);
SK_IF_LOCK(sc_if);
}
@@ -2652,20 +2655,26 @@ sk_start_locked(ifp)
CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
/* Set a timeout in case the chip goes out to lunch. */
- ifp->if_timer = 5;
+ sc_if->sk_watchdog_timer = 5;
}
}
static void
-sk_watchdog(ifp)
- struct ifnet *ifp;
+sk_watchdog(arg)
+ void *arg;
{
struct sk_if_softc *sc_if;
+ struct ifnet *ifp;
+ ifp = arg;
sc_if = ifp->if_softc;
- SK_IF_LOCK(sc_if);
+ SK_IF_LOCK_ASSERT(sc_if);
+
+ if (sc_if->sk_watchdog_timer == 0 || --sc_if->sk_watchdog_timer)
+ goto done;
+
/*
* Reclaim first as there is a possibility of losing Tx completion
* interrupts.
@@ -2677,7 +2686,9 @@ sk_watchdog(ifp)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
sk_init_locked(sc_if);
}
- SK_IF_UNLOCK(sc_if);
+
+done:
+ callout_reset(&sc_if->sk_watchdog_ch, hz, sk_watchdog, ifp);
return;
}
@@ -3030,7 +3041,7 @@ sk_txeof(sc_if)
txd = STAILQ_FIRST(&sc_if->sk_cdata.sk_txbusyq);
}
sc_if->sk_cdata.sk_tx_cons = idx;
- ifp->if_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
+ sc_if->sk_watchdog_timer = sc_if->sk_cdata.sk_tx_cnt > 0 ? 5 : 0;
bus_dmamap_sync(sc_if->sk_cdata.sk_tx_ring_tag,
sc_if->sk_cdata.sk_tx_ring_map,
@@ -3805,6 +3816,8 @@ sk_init_locked(sc_if)
break;
}
+ callout_reset(&sc_if->sk_watchdog_ch, hz, sk_watchdog, ifp);
+
return;
}
@@ -3825,6 +3838,7 @@ sk_stop(sc_if)
ifp = sc_if->sk_ifp;
callout_stop(&sc_if->sk_tick_ch);
+ callout_stop(&sc_if->sk_watchdog_ch);
/* stop Tx descriptor polling timer */
SK_IF_WRITE_4(sc_if, 0, SK_DPT_TIMER_CTRL, SK_DPT_TCTL_STOP);
diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h
index 98912b3..e9e55ea 100644
--- a/sys/dev/sk/if_skreg.h
+++ b/sys/dev/sk/if_skreg.h
@@ -1511,6 +1511,8 @@ struct sk_if_softc {
int sk_phyaddr;
int sk_link;
struct callout sk_tick_ch;
+ struct callout sk_watchdog_ch;
+ int sk_watchdog_timer;
struct sk_chain_data sk_cdata;
struct sk_ring_data sk_rdata;
struct sk_softc *sk_softc; /* parent controller */
OpenPOWER on IntegriCloud