DragonFly BSD
DragonFly kernel List (threaded) for 2005-12
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

Re: iwi panic


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Dec 2005 12:45:39 -0800 (PST)

:When my iwi0 interface associates with an AP my kernel panics.  I have
:a kernel/vmcore if necessary.  
:
:Thanks,
:Joe

    Try this patch.

					-Matt

Index: if_iwi.c
===================================================================
RCS file: /cvs/src/sys/dev/netif/iwi/if_iwi.c,v
retrieving revision 1.8
diff -u -r1.8 if_iwi.c
--- if_iwi.c	22 Nov 2005 00:24:32 -0000	1.8
+++ if_iwi.c	16 Dec 2005 20:44:21 -0000
@@ -167,7 +167,6 @@
 static int		iwi_scan(struct iwi_softc *);
 static int		iwi_auth_and_assoc(struct iwi_softc *);
 static void		iwi_init(void *);
-static void		iwi_init_locked(void *);
 static void		iwi_stop(void *);
 static void		iwi_dump_fw_event_log(struct iwi_softc *sc);
 static void		iwi_dump_fw_error_log(struct iwi_softc *sc);
@@ -249,7 +248,9 @@
 iwi_fw_monitor(void *arg)
 {
 	struct iwi_softc *sc = (struct iwi_softc *)arg;
+	struct ifnet *ifp = &sc->sc_ic.ic_if;
 	int error, boff;
+
 	for ( ;; ) {
 		error = tsleep(IWI_FW_WAKE_MONITOR(sc), 0, "iwifwm", 0 );
 		if ( error == 0 ) {
@@ -261,7 +262,9 @@
 				for ( boff = 1; sc->flags & IWI_FLAG_RESET ; boff++ ) {
 					if ( sc->debug_level > 0 )
 						iwi_dump_fw_error_log(sc);
-					iwi_init_locked(sc);
+					lwkt_serialize_enter(ifp->if_serializer);
+					iwi_init(sc);
+					lwkt_serialize_exit(ifp->if_serializer);
 					if ((sc->flags & IWI_FLAG_FW_INITED))
 						sc->flags &= ~( IWI_FLAG_RESET );
 					error = tsleep( IWI_FW_CMD_ACKED(sc), 0,
@@ -301,9 +304,6 @@
 
 	sc->sc_dev = dev;
 
-	IWI_LOCK_INIT( &sc->sc_lock );
-	IWI_LOCK_INIT( &sc->sc_intrlock );
-
 	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
 		device_printf(dev, "chip is in D%d power mode "
 		    "-- setting to D0\n", pci_get_powerstate(dev));
@@ -414,7 +414,7 @@
 	ifp->if_softc = sc;
 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-	ifp->if_init = iwi_init_locked;
+	ifp->if_init = iwi_init;
 	ifp->if_ioctl = iwi_ioctl;
 	ifp->if_start = iwi_start;
 	ifp->if_watchdog = iwi_watchdog;
@@ -537,7 +537,7 @@
 	 * Hook our interrupt after all initialization is complete
 	 */
 	error = bus_setup_intr(dev, sc->irq, INTR_MPSAFE,
-			       iwi_intr, sc, &sc->sc_ih, NULL);
+			       iwi_intr, sc, &sc->sc_ih, ifp->if_serializer);
 	if (error != 0) {
 		device_printf(dev, "could not set up interrupt\n");
 		goto fail2;
@@ -558,17 +558,13 @@
 {
 	struct iwi_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = &sc->sc_ic.ic_if;
-	IWI_LOCK_INFO;
-	IWI_IPLLOCK_INFO;
 
 	sc->flags |= IWI_FLAG_EXIT;
 	wakeup(IWI_FW_WAKE_MONITOR(sc)); /* Stop firmware monitor. */
 
 	tsleep(IWI_FW_MON_EXIT(sc), 0, "iwiexi", 10 * hz);
 
-	IWI_LOCK(sc);
-	IWI_IPLLOCK(sc);
-
+	lwkt_serialize_enter(ifp->if_serializer);
 	if (device_is_attached(dev)) {
 		iwi_stop(sc);
 		iwi_free_firmware(sc);
@@ -577,18 +573,13 @@
 	}
 
 	if (sc->sysctl_tree) {
-		crit_enter();
 		sysctl_ctx_free(&sc->sysctl_ctx);
-		crit_exit();
 		sc->sysctl_tree = 0;
 	}
 
 	if (sc->sc_ih != NULL)
 		bus_teardown_intr(dev, sc->irq, sc->sc_ih);
 
-	IWI_IPLUNLOCK(sc);
-	IWI_UNLOCK(sc);
-
 	if (sc->irq != NULL)
 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
 
@@ -596,12 +587,10 @@
 		bus_release_resource(dev, SYS_RES_MEMORY, IWI_PCI_BAR0,
 		    sc->mem);
 	}
+	lwkt_serialize_exit(ifp->if_serializer);
 
 	iwi_release(sc);
 
-	IWI_LOCK_DESTROY(&(sc->sc_lock));
-	IWI_LOCK_DESTROY(&(sc->sc_intrlock));
-
 	return 0;
 }
 
@@ -813,13 +802,11 @@
 iwi_shutdown(device_t dev)
 {
 	struct iwi_softc *sc = device_get_softc(dev);
-	IWI_LOCK_INFO;
-
-	IWI_LOCK(sc);
+	struct ifnet *ifp = &sc->sc_ic.ic_if;
 
+	lwkt_serialize_enter(ifp->if_serializer);
 	iwi_stop(sc);
-
-	IWI_UNLOCK(sc);
+	lwkt_serialize_exit(ifp->if_serializer);
 
 	return 0;
 }
@@ -828,14 +815,11 @@
 iwi_suspend(device_t dev)
 {
 	struct iwi_softc *sc = device_get_softc(dev);
+	struct ifnet *ifp = &sc->sc_ic.ic_if;
 
-	IWI_LOCK_INFO;
-
-	IWI_LOCK(sc);
-
+	lwkt_serialize_enter(ifp->if_serializer);
 	iwi_stop(sc);
-
-	IWI_UNLOCK(sc);
+	lwkt_serialize_exit(ifp->if_serializer);
 
 	return 0;
 }
@@ -845,10 +829,8 @@
 {
 	struct iwi_softc *sc = device_get_softc(dev);
 	struct ifnet *ifp = &sc->sc_ic.ic_if;
-	IWI_LOCK_INFO;
-
-	IWI_LOCK(sc);
 
+	lwkt_serialize_enter(ifp->if_serializer);
 	pci_write_config(dev, 0x41, 0, 1);
 
 	if (ifp->if_flags & IFF_UP) {
@@ -856,9 +838,7 @@
 		if (ifp->if_flags & IFF_RUNNING)
 			ifp->if_start(ifp);
 	}
-
-	IWI_UNLOCK(sc);
-
+	lwkt_serialize_exit(ifp->if_serializer);
 	return 0;
 }
 
@@ -867,13 +847,9 @@
 {
 	struct iwi_softc *sc = ifp->if_softc;
 	int error = 0;
-	IWI_LOCK_INFO;
-
-	IWI_LOCK(sc);
 
 	error = ieee80211_media_change(ifp);
 	if (error != ENETRESET) {
-		IWI_UNLOCK(sc);
 		return error;
 	}
 	error = 0; /* clear ENETRESET */
@@ -882,10 +858,6 @@
 		iwi_init(sc);
 		error = tsleep( IWI_FW_CMD_ACKED(sc), 0, "iwirun", hz );
 	}
-
-
-	IWI_UNLOCK(sc);
-
 	return error;
 }
 
@@ -1413,13 +1385,8 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ifnet *ifp = &ic->ic_if;
 	u_int32_t r;
-	IWI_LOCK_INFO;
-	IWI_IPLLOCK_INFO;
-
-	IWI_IPLLOCK(sc);
 
 	if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff) {
-		IWI_IPLUNLOCK(sc);
 		return;
 	}
 
@@ -1440,9 +1407,7 @@
 	if (r & IWI_INTR_PARITY_ERROR) {
 			device_printf(sc->sc_dev, "fatal error\n");
 			sc->sc_ic.ic_if.if_flags &= ~IFF_UP;
-			IWI_LOCK(sc);
 			iwi_stop(sc);
-			IWI_UNLOCK(sc);
 	}
 
 	if (r & IWI_INTR_FW_INITED) {
@@ -1453,9 +1418,7 @@
 	if (r & IWI_INTR_RADIO_OFF) {
 		DPRINTF(("radio transmitter off\n"));
 		sc->sc_ic.ic_if.if_flags &= ~IFF_UP;
-		IWI_LOCK(sc);
 		iwi_stop(sc);
-		IWI_UNLOCK(sc);
 		sc->flags |= IWI_FLAG_RF_DISABLED;
 	}
 
@@ -1479,8 +1442,6 @@
 	/* Re-enable interrupts */
 	CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK);
 
-	IWI_IPLUNLOCK(sc);
-
 	if ((ifp->if_flags & IFF_RUNNING) && !ifq_is_empty(&ifp->if_snd))
 		iwi_start(ifp);
 }
@@ -1556,8 +1517,6 @@
 	struct mbuf *mnew;
 	u_int32_t id = 0;
 	int error, i;
-	IWI_IPLLOCK_INFO; /* XXX still need old ipl locking mech. here */
-	IWI_IPLLOCK(sc);
 
 	if (sc->sc_drvbpf != NULL) {
 		struct iwi_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1589,7 +1548,6 @@
 		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
 		    error);
 		m_freem(m0);
-		IWI_IPLUNLOCK(sc);
 		return error;
 	}
 	if (error != 0) {
@@ -1598,7 +1556,6 @@
 			device_printf(sc->sc_dev,
 			    "could not defragment mbuf\n");
 			m_freem(m0);
-			IWI_IPLUNLOCK(sc);
 			return ENOBUFS;
 		}
 		m0 = mnew;
@@ -1609,7 +1566,6 @@
 			device_printf(sc->sc_dev,
 			    "could not map mbuf (error %d)\n", error);
 			m_freem(m0);
-			IWI_IPLUNLOCK(sc);
 			return error;
 		}
 	}
@@ -1655,7 +1611,6 @@
 	sc->tx_cur = (sc->tx_cur + 1) % IWI_TX_RING_SIZE;
 	CSR_WRITE_4(sc, IWI_CSR_TX1_WRITE_INDEX, sc->tx_cur);
 
-	IWI_IPLUNLOCK(sc);
 	return 0;
 }
 
@@ -1764,16 +1719,12 @@
 	struct ieee80211req *ireq;
 	struct ifaddr *ifa;
 	int error = 0;
-	IWI_LOCK_INFO;
-
-	IWI_LOCK(sc);
 
 	switch (cmd) {
        case SIOCSIFADDR:
 		/*
 		 * Handle this here instead of in net80211_ioctl.c
-		 * so that we can lock (IWI_LOCK) the call to
-		 * iwi_init().
+		 * so that we can lock the call to iwi_init().
 		 */
 		ifa = (struct ifaddr *) data;
 		switch (ifa->ifa_addr->sa_family) {
@@ -1898,9 +1849,6 @@
 			error = tsleep(IWI_FW_CMD_ACKED(sc), 0, "iwirun", hz);
 		}
 	}
-
-	IWI_UNLOCK(sc);
-
 	return error;
 }
 
@@ -2702,16 +2650,6 @@
 }
 
 static void
-iwi_init_locked(void *priv) 
-{
-	struct iwi_softc *sc = priv;
-	IWI_LOCK_INFO;
-	IWI_LOCK(sc);
-	iwi_init(sc);
-	IWI_UNLOCK(sc);
-}
-
-static void
 iwi_stop(void *priv)
 {
 	struct iwi_softc *sc = priv;
Index: if_iwivar.h
===================================================================
RCS file: /cvs/src/sys/dev/netif/iwi/if_iwivar.h,v
retrieving revision 1.3
diff -u -r1.3 if_iwivar.h
--- if_iwivar.h	27 Jun 2005 11:28:54 -0000	1.3
+++ if_iwivar.h	16 Dec 2005 20:37:51 -0000
@@ -179,25 +179,6 @@
 #define SIOCSLOADIBSSFW	 _IOW('i', 138, struct ifreq)
 #define SIOCSKILLFW	 _IOW('i', 139, struct ifreq)
 
-#define IWI_LOCK_INIT(tok)     lwkt_token_init(tok)
-#define IWI_LOCK_DESTROY(tok)  lwkt_token_uninit(tok)
-
-#define IWI_LOCK_INFO          struct lwkt_tokref tokinfo
-#define IWI_INTRLOCK_INFO      struct lwkt_tokref intrtokinfo
-#define IWI_INTRLOCK(_sc)      lwkt_gettoken(&intrtokinfo,(&(_sc)->sc_intrlock))
-#define IWI_INTRUNLOCK(SC)     lwkt_reltoken(&intrtokinfo)
-#define IWI_LOCK(_sc)          lwkt_gettoken(&tokinfo,&((_sc)->sc_lock))
-#define IWI_UNLOCK(SC)         lwkt_reltoken(&tokinfo)
-
-/*
- * Holding a token is not enough for iwi_tx_start() the DMA send
- * routine. Revert back to the old ipl mechanism for now.
- */
-
-#define IWI_IPLLOCK_INFO
-#define IWI_IPLLOCK(_sc)	crit_enter()
-#define IWI_IPLUNLOCK(_sc)	crit_exit()
-
 /* tsleepable events */
 #define IWI_FW_WAKE_MONITOR(sc)      (sc + 1)
 #define IWI_FW_INITIALIZED(sc)       (sc + 2)




[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]