From 32cd7a9c0071fa2c184aa149a1b356ce51c0ce69 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 29 Apr 2003 05:45:09 +0000 Subject: [PATCH] Fix 5 bugs: 1) always call fxp_stop in fxp_detach. Since we don't read from the card, there's no need to carefully look at things with bus_child_present. 2) Call FXP_UNLOCK() before calling bus_teardown_intr to avoid a possible deadlock reported by jhb. 3) add gone to the softc. Set it to true in detach. 4) Return immediately if gone is true in fxp_ioctl 5) Return immediately if gone is true in fxp_intr --- sys/dev/fxp/if_fxp.c | 18 ++++++++++-------- sys/dev/fxp/if_fxpvar.h | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 427e874da587..27e69750341e 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -880,19 +880,19 @@ fxp_detach(device_t dev) FXP_LOCK(sc); s = splimp(); + + sc->gone = 1; /* * Close down routes etc. */ ether_ifdetach(&sc->arpcom.ac_if); /* - * Stop DMA and drop transmit queue. + * Stop DMA and drop transmit queue, but disable interrupts first. */ - if (bus_child_present(dev)) { - /* disable interrupts */ - CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); - fxp_stop(sc); - } + CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE); + fxp_stop(sc); + FXP_UNLOCK(sc); /* * Unhook interrupt before dropping lock. This is to prevent @@ -901,7 +901,6 @@ fxp_detach(device_t dev) bus_teardown_intr(sc->dev, sc->irq, sc->ih); sc->ih = NULL; - FXP_UNLOCK(sc); splx(s); /* Release our allocated resources. */ @@ -1859,7 +1858,7 @@ fxp_stop(struct fxp_softc *sc) txp = sc->fxp_desc.tx_list; if (txp != NULL) { for (i = 0; i < FXP_NTXCB; i++) { - if (txp[i].tx_mbuf != NULL) { + if (txp[i].tx_mbuf != NULL) { bus_dmamap_sync(sc->fxp_mtag, txp[i].tx_map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->fxp_mtag, txp[i].tx_map); @@ -2360,6 +2359,9 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct mii_data *mii; int s, error = 0; + if (sc->gone) + return (ENODEV); + FXP_LOCK(sc); s = splimp(); diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h index 0dee4ad27e3a..b73cf50b538c 100644 --- a/sys/dev/fxp/if_fxpvar.h +++ b/sys/dev/fxp/if_fxpvar.h @@ -189,6 +189,7 @@ struct fxp_softc { int cu_resume_bug; int revision; int flags; + int gone; u_int32_t saved_maps[5]; /* pci data */ u_int32_t saved_biosaddr; u_int8_t saved_intline;