summaryrefslogtreecommitdiffstats
path: root/sys/dev/wi/if_wi.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2008-07-26 17:04:30 +0000
committerimp <imp@FreeBSD.org>2008-07-26 17:04:30 +0000
commit2e7d905af740dd6e7eefac495be8104afaa7e96f (patch)
tree4f0e7377520d4e010f9d3c2cd43728416eaaddd2 /sys/dev/wi/if_wi.c
parent970f57859d4d105ea799288f5c6bfb36c688d4b6 (diff)
downloadFreeBSD-src-2e7d905af740dd6e7eefac495be8104afaa7e96f.zip
FreeBSD-src-2e7d905af740dd6e7eefac495be8104afaa7e96f.tar.gz
Register the interrupt handler at the end of wi_attach rather than at
the beginning. There's a race in the shared interrutp case. If another interrupt happens after the interrupt is setup, then we'd try to lock an uninitialized mutex. In addition, if we bailed out due to a too old version of firmware, we'd leave the interrupt enabled with all the fun that ensues....
Diffstat (limited to 'sys/dev/wi/if_wi.c')
-rw-r--r--sys/dev/wi/if_wi.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c
index 51c672d..f0d939f 100644
--- a/sys/dev/wi/if_wi.c
+++ b/sys/dev/wi/if_wi.c
@@ -250,19 +250,6 @@ wi_attach(device_t dev)
}
ic = ifp->if_l2com;
- /*
- * NB: no locking is needed here; don't put it here
- * unless you can prove it!
- */
- error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, wi_intr, sc, &sc->wi_intrhand);
-
- if (error) {
- device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
- wi_free(dev);
- return error;
- }
-
sc->sc_firmware_type = WI_NOTYPE;
sc->wi_cmd_count = 500;
/* Reset the NIC. */
@@ -473,6 +460,17 @@ wi_attach(device_t dev)
if (bootverbose)
ieee80211_announce(ic);
+ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, wi_intr, sc, &sc->wi_intrhand);
+ if (error) {
+ device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
+ bpfdetach(ifp);
+ ieee80211_ifdetach(ic);
+ if_free(sc->sc_ifp);
+ wi_free(dev);
+ return error;
+ }
+
return (0);
}
OpenPOWER on IntegriCloud