summaryrefslogtreecommitdiffstats
path: root/sys/dev/fxp
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2003-04-29 05:45:09 +0000
committerimp <imp@FreeBSD.org>2003-04-29 05:45:09 +0000
commit6acb819c04fd80b98e4e35832411e903607e59a1 (patch)
tree2b2f7e683cef705453c16be536814036776b3aec /sys/dev/fxp
parent917a0299733c2efdf3eaeb96e6aada214c83de40 (diff)
downloadFreeBSD-src-6acb819c04fd80b98e4e35832411e903607e59a1.zip
FreeBSD-src-6acb819c04fd80b98e4e35832411e903607e59a1.tar.gz
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
Diffstat (limited to 'sys/dev/fxp')
-rw-r--r--sys/dev/fxp/if_fxp.c18
-rw-r--r--sys/dev/fxp/if_fxpvar.h1
2 files changed, 11 insertions, 8 deletions
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 427e874..27e6975 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 0dee4ad..b73cf50 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;
OpenPOWER on IntegriCloud