diff options
| author | Benno Rice <benno@FreeBSD.org> | 2008-06-12 00:38:54 +0000 |
|---|---|---|
| committer | Benno Rice <benno@FreeBSD.org> | 2008-06-12 00:38:54 +0000 |
| commit | 764e058a5b37fb96a32c463db73c1e36bdfb05b0 (patch) | |
| tree | 89207568434b7aba04616ea8ca64e1ef279cb4ca /sys/dev/smc | |
| parent | 45cfd29bb8dca4d4e7be01862ca2ab8e83dc65ee (diff) | |
Notes
Diffstat (limited to 'sys/dev/smc')
| -rw-r--r-- | sys/dev/smc/if_smc.c | 43 | ||||
| -rw-r--r-- | sys/dev/smc/if_smcvar.h | 1 |
2 files changed, 37 insertions, 7 deletions
diff --git a/sys/dev/smc/if_smc.c b/sys/dev/smc/if_smc.c index 966c710357ee..81e468e3b442 100644 --- a/sys/dev/smc/if_smc.c +++ b/sys/dev/smc/if_smc.c @@ -101,6 +101,7 @@ static const char *smc_chip_ids[16] = { static void smc_init(void *); static void smc_start(struct ifnet *); +static void smc_stop(struct smc_softc *); static int smc_ioctl(struct ifnet *, u_long, caddr_t); static void smc_init_locked(struct smc_softc *); @@ -278,6 +279,7 @@ smc_attach(device_t dev) error = 0; sc->smc_dev = dev; + sc->smc_shutdown = 0; /* Set up watchdog callout. */ callout_init(&sc->smc_watchdog, 1); @@ -388,9 +390,19 @@ smc_detach(device_t dev) struct smc_softc *sc; sc = device_get_softc(dev); - - callout_stop(&sc->smc_watchdog); - + SMC_LOCK(sc); + sc->smc_shutdown = 1; + smc_stop(sc); + SMC_UNLOCK(sc); + + if (sc->smc_tq != NULL) { + taskqueue_drain(sc->smc_tq, &sc->smc_intr); + taskqueue_drain(sc->smc_tq, &sc->smc_rx); + taskqueue_drain(sc->smc_tq, &sc->smc_tx); + taskqueue_free(sc->smc_tq); + sc->smc_tq = NULL; + } + #ifdef DEVICE_POLLING if (sc->smc_ifp->if_capenable & IFCAP_POLLING) ether_poll_deregister(sc->smc_ifp); @@ -405,6 +417,7 @@ smc_detach(device_t dev) } if (sc->smc_miibus != NULL) { + callout_stop(&sc->smc_mii_tick_ch); device_delete_child(sc->smc_dev, sc->smc_miibus); bus_generic_detach(sc->smc_dev); } @@ -422,9 +435,6 @@ smc_detach(device_t dev) bus_release_resource(sc->smc_dev, SYS_RES_IRQ, sc->smc_irq_rid, sc->smc_irq); - if (sc->smc_tq != NULL) - taskqueue_free(sc->smc_tq); - if (mtx_initialized(&sc->smc_mtx)) mtx_destroy(&sc->smc_mtx); @@ -530,7 +540,11 @@ smc_task_tx(void *context, int pending) sc = ifp->if_softc; SMC_LOCK(sc); - + if (sc->smc_shutdown == 1) { + SMC_UNLOCK(sc); + return; + } + if (sc->smc_pending == NULL) { SMC_UNLOCK(sc); goto next_packet; @@ -633,6 +647,10 @@ smc_task_rx(void *context, int pending) mhead = mtail = NULL; SMC_LOCK(sc); + if (sc->smc_shutdown == 1) { + SMC_UNLOCK(sc); + return; + } packet = smc_read_1(sc, FIFO_RX); while ((packet & FIFO_EMPTY) == 0) { @@ -774,6 +792,11 @@ smc_task_intr(void *context, int pending) sc = ifp->if_softc; SMC_LOCK(sc); + if (sc->smc_shutdown == 1) { + SMC_UNLOCK(sc); + return; + } + smc_select_bank(sc, 2); /* @@ -1224,6 +1247,12 @@ smc_watchdog(void *arg) struct smc_softc *sc; sc = (struct smc_softc *)arg; + SMC_LOCK(sc); + if (sc->smc_shutdown == 1) { + SMC_UNLOCK(sc); + return; + } + SMC_UNLOCK(sc); device_printf(sc->smc_dev, "watchdog timeout\n"); taskqueue_enqueue_fast(sc->smc_tq, &sc->smc_intr); } diff --git a/sys/dev/smc/if_smcvar.h b/sys/dev/smc/if_smcvar.h index 9bff17df3ba0..7463d0ad136c 100644 --- a/sys/dev/smc/if_smcvar.h +++ b/sys/dev/smc/if_smcvar.h @@ -35,6 +35,7 @@ struct smc_softc { u_int smc_chip; u_int smc_rev; u_int smc_mask; + u_int smc_shutdown; /* Resources */ int smc_usemem; |
