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:
parent
2e56cd38cb
commit
287e0d97bf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=217542
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user