1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-27 08:00:11 +00:00

Fix some bugs in my last set of changes to ale(4):

- Remove extra unlock from end of ale_start_locked().
- Expand scope of locking in interrupt handler.
- Move ether_ifdetach() earlier and retire now-unneeded DETACH flag.

Tested by:	Aryeh Friedman
Reviewed by:	yongari (earlier version)
This commit is contained in:
John Baldwin 2011-01-18 16:27:40 +00:00
parent 2e56cd38cb
commit 287e0d97bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217542
2 changed files with 8 additions and 9 deletions

View File

@ -675,14 +675,13 @@ ale_detach(device_t dev)
ifp = sc->ale_ifp;
if (device_is_attached(dev)) {
ether_ifdetach(ifp);
ALE_LOCK(sc);
sc->ale_flags |= ALE_FLAG_DETACH;
ale_stop(sc);
ALE_UNLOCK(sc);
callout_drain(&sc->ale_tick_ch);
taskqueue_drain(sc->ale_tq, &sc->ale_int_task);
taskqueue_drain(taskqueue_swi, &sc->ale_link_task);
ether_ifdetach(ifp);
}
if (sc->ale_tq != NULL) {
@ -1907,8 +1906,6 @@ ale_start_locked(struct ifnet *ifp)
/* Set a timeout in case the chip goes out to lunch. */
sc->ale_watchdog_timer = ALE_TX_TIMEOUT;
}
ALE_UNLOCK(sc);
}
static void
@ -1972,8 +1969,7 @@ ale_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
& (IFF_PROMISC | IFF_ALLMULTI)) != 0)
ale_rxfilter(sc);
} else {
if ((sc->ale_flags & ALE_FLAG_DETACH) == 0)
ale_init_locked(sc);
ale_init_locked(sc);
}
} else {
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
@ -2284,6 +2280,7 @@ ale_int_task(void *arg, int pending)
sc = (struct ale_softc *)arg;
status = CSR_READ_4(sc, ALE_INTR_STATUS);
ALE_LOCK(sc);
if (sc->ale_morework != 0)
status |= INTR_RX_PKT;
if ((status & ALE_INTRS) == 0)
@ -2299,7 +2296,6 @@ ale_int_task(void *arg, int pending)
if (more == EAGAIN)
sc->ale_morework = 1;
else if (more == EIO) {
ALE_LOCK(sc);
sc->ale_stats.reset_brk_seq++;
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ale_init_locked(sc);
@ -2314,7 +2310,6 @@ ale_int_task(void *arg, int pending)
if ((status & INTR_DMA_WR_TO_RST) != 0)
device_printf(sc->ale_dev,
"DMA write error! -- resetting\n");
ALE_LOCK(sc);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
ale_init_locked(sc);
ALE_UNLOCK(sc);
@ -2326,11 +2321,14 @@ ale_int_task(void *arg, int pending)
if (more == EAGAIN ||
(CSR_READ_4(sc, ALE_INTR_STATUS) & ALE_INTRS) != 0) {
ALE_UNLOCK(sc);
taskqueue_enqueue(sc->ale_tq, &sc->ale_int_task);
return;
}
done:
ALE_UNLOCK(sc);
/* Re-enable interrupts. */
CSR_WRITE_4(sc, ALE_INTR_STATUS, 0x7FFFFFFF);
}
@ -2587,7 +2585,9 @@ ale_rxeof(struct ale_softc *sc, int count)
}
/* Pass it to upper layer. */
ALE_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
ALE_LOCK(sc);
ale_rx_update_page(sc, &rx_page, length, &prod);
}

View File

@ -206,7 +206,6 @@ struct ale_softc {
#define ALE_FLAG_RXCSUM_BUG 0x0080
#define ALE_FLAG_TXCSUM_BUG 0x0100
#define ALE_FLAG_TXCMB_BUG 0x0200
#define ALE_FLAG_DETACH 0x4000
#define ALE_FLAG_LINK 0x8000
struct callout ale_tick_ch;