From febcff0a3bd6a05f70dc982f84459a8ade0fc73b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 26 Jul 2008 17:04:30 +0000 Subject: [PATCH] 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.... --- sys/dev/wi/if_wi.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 51c672da5983..f0d939f22fc5 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); }