diff options
author | jhb <jhb@FreeBSD.org> | 2011-01-06 19:32:00 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2011-01-06 19:32:00 +0000 |
commit | 1e0411c61aeadd42541f03eed397d32209175f7d (patch) | |
tree | 69ca75365d77bc96950bb75332f63065cdea75f6 /sys/arm | |
parent | dd8fee4f825a7c2be410296910c7dd3cd6e3826d (diff) | |
download | FreeBSD-src-1e0411c61aeadd42541f03eed397d32209175f7d.zip FreeBSD-src-1e0411c61aeadd42541f03eed397d32209175f7d.tar.gz |
- Use macbstart_locked() directly instead of deferring it to a task.
- Expand locking scope in interrupt handler.
- Flesh out the detach routine.
Reviewed by: cognet
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/at91/if_macb.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/sys/arm/at91/if_macb.c b/sys/arm/at91/if_macb.c index 02dedac..b985f26 100644 --- a/sys/arm/at91/if_macb.c +++ b/sys/arm/at91/if_macb.c @@ -137,7 +137,6 @@ macb_watchdog(struct macb_softc *sc); static int macb_intr_rx_locked(struct macb_softc *sc, int count); static void macb_intr_task(void *arg, int pending __unused); -static void macb_tx_task(void *arg, int pending __unused); static void macb_intr(void *xsc); static void @@ -533,7 +532,7 @@ macb_watchdog(struct macb_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_RUNNING; macbinit_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task); + macbstart_locked(ifp); } @@ -837,6 +836,7 @@ macb_intr(void *xsc) return; } + MACB_LOCK(sc); status = read_4(sc, EMAC_ISR); while (status) { @@ -846,16 +846,15 @@ macb_intr(void *xsc) } if (status & TCOMP_INTERRUPT) { - MACB_LOCK(sc); macb_tx_cleanup(sc); - MACB_UNLOCK(sc); } status = read_4(sc, EMAC_ISR); } if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(sc->sc_tq, &sc->sc_tx_task); + macbstart_locked(ifp); + MACB_UNLOCK(sc); } static inline int @@ -1026,16 +1025,6 @@ macbstart(struct ifnet *ifp) static void -macb_tx_task(void *arg, int pending __unused) -{ - struct ifnet *ifp; - - ifp = (struct ifnet *)arg; - macbstart(ifp); -} - - -static void macbstop(struct macb_softc *sc) { struct ifnet *ifp = sc->ifp; @@ -1392,7 +1381,6 @@ macb_attach(device_t dev) sc->if_flags = ifp->if_flags; TASK_INIT(&sc->sc_intr_task, 0, macb_intr_task, sc); - TASK_INIT(&sc->sc_tx_task, 0, macb_tx_task, ifp); sc->sc_tq = taskqueue_create_fast("macb_taskq", M_WAITOK, taskqueue_thread_enqueue, &sc->sc_tq); @@ -1434,8 +1422,18 @@ macb_detach(device_t dev) struct macb_softc *sc; sc = device_get_softc(dev); + ether_ifdetach(sc->ifp); + MACB_LOCK(sc); macbstop(sc); + MACB_UNLOCK(sc); + callout_drain(&sc->tick_ch); + bus_teardown_intr(dev, sc->irq_res, sc->intrhand); + taskqueue_drain(sc->sc_tq, &sc->sc_intr_task); + taskqueue_free(sc->sc_tq); macb_deactivate(dev); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); + MACB_LOCK_DESTROY(sc); return (0); } |