summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2006-12-13 22:38:56 +0000
committeralfred <alfred@FreeBSD.org>2006-12-13 22:38:56 +0000
commite9e77760fbb37300b2b391fdc5459f7f77e69094 (patch)
tree25796d9d70a6676394e18c14834db5643c359742 /sys/dev/usb
parent481eab37220c87aa4eb38eff743986d815f939e6 (diff)
downloadFreeBSD-src-e9e77760fbb37300b2b391fdc5459f7f77e69094.zip
FreeBSD-src-e9e77760fbb37300b2b391fdc5459f7f77e69094.tar.gz
Use callouts to prevent races.
Cleanup debug code.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/if_aue.c15
-rw-r--r--sys/dev/usb/if_auereg.h36
2 files changed, 31 insertions, 20 deletions
diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c
index 6290537..223eb91 100644
--- a/sys/dev/usb/if_aue.c
+++ b/sys/dev/usb/if_aue.c
@@ -761,7 +761,6 @@ USB_ATTACH(aue)
* Call MI attach routine.
*/
ether_ifattach(ifp, eaddr);
- callout_handle_init(&sc->aue_stat_ch);
usb_register_netisr();
sc->aue_dying = 0;
@@ -780,7 +779,7 @@ aue_detach(device_t dev)
ifp = sc->aue_ifp;
sc->aue_dying = 1;
- untimeout(aue_tick, sc, sc->aue_stat_ch);
+ callout_drain(&sc->aue_tick_callout);
taskqueue_drain(taskqueue_thread, &sc->aue_task);
ether_ifdetach(ifp);
if_free(ifp);
@@ -989,6 +988,10 @@ aue_tick_thread(struct aue_softc *sc)
AUE_SXASSERTLOCKED(sc);
ifp = sc->aue_ifp;
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ return;
+ }
+
mii = GET_MII(sc);
if (mii == NULL) {
goto resched;
@@ -1002,7 +1005,7 @@ aue_tick_thread(struct aue_softc *sc)
aue_start_thread(sc);
}
resched:
- sc->aue_stat_ch = timeout(aue_tick, sc, hz);
+ (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
return;
}
@@ -1188,8 +1191,8 @@ aue_init(void *xsc)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
TASK_INIT(&sc->aue_task, 0, aue_task, sc);
- sc->aue_stat_ch = timeout(aue_tick, sc, hz);
-
+ callout_init(&sc->aue_tick_callout, 1);
+ (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc);
return;
}
@@ -1326,7 +1329,7 @@ aue_stop(struct aue_softc *sc)
aue_csr_write_1(sc, AUE_CTL0, 0);
aue_csr_write_1(sc, AUE_CTL1, 0);
aue_reset(sc);
- untimeout(aue_tick, sc, sc->aue_stat_ch);
+ callout_drain(&sc->aue_tick_callout);
taskqueue_drain(taskqueue_thread, &sc->aue_task);
/* Stop transfers. */
diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h
index 40e0ed7..02158c3 100644
--- a/sys/dev/usb/if_auereg.h
+++ b/sys/dev/usb/if_auereg.h
@@ -225,7 +225,7 @@ struct aue_softc {
u_int8_t aue_link;
int aue_if_flags;
struct ue_cdata aue_cdata;
- struct callout_handle aue_stat_ch;
+ struct callout aue_tick_callout;
struct task aue_task;
struct mtx aue_mtx;
struct sx aue_sx;
@@ -236,7 +236,11 @@ struct aue_softc {
int aue_deferedtasks;
};
-#if 1
+#if 0
+/*
+ * Some debug code to make sure we don't take a blocking lock in
+ * interrupt context.
+ */
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/kdb.h>
@@ -254,15 +258,14 @@ aue_dumpstate(const char *func, const char *tag)
curthread->td_pflags & TDP_ITHREAD ? "yes" : "no");
}
}
-
-#define AUE_LOCK(_sc) mtx_lock(&(_sc)->aue_mtx)
-#define AUE_UNLOCK(_sc) mtx_unlock(&(_sc)->aue_mtx)
#else
-#define AUE_LOCK(_sc)
-#define AUE_UNLOCK(_sc)
+#define AUE_DUMPSTATE(tag)
#endif
-#define AUE_SXLOCK(_sc) do { AUE_DUMPSTATE("sxlock");sx_xlock(&(_sc)->aue_sx); }while(0)
+#define AUE_LOCK(_sc) mtx_lock(&(_sc)->aue_mtx)
+#define AUE_UNLOCK(_sc) mtx_unlock(&(_sc)->aue_mtx)
+#define AUE_SXLOCK(_sc) \
+ do { AUE_DUMPSTATE("sxlock"); sx_xlock(&(_sc)->aue_sx); } while(0)
#define AUE_SXUNLOCK(_sc) sx_xunlock(&(_sc)->aue_sx)
#define AUE_SXASSERTLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_XLOCKED)
#define AUE_SXASSERTUNLOCKED(_sc) sx_assert(&(_sc)->aue_sx, SX_UNLOCKED)
@@ -271,12 +274,17 @@ aue_dumpstate(const char *func, const char *tag)
#define AUE_MIN_FRAMELEN 60
#define AUE_INTR_INTERVAL 100 /* ms */
-#define AUE_TASK_WATCHDOG 0x0001
-#define AUE_TASK_TICK 0x0002
-#define AUE_TASK_START 0x0004
-#define AUE_TASK_RXSTART 0x0008
-#define AUE_TASK_RXEOF 0x0010
-#define AUE_TASK_TXEOF 0x0020
+/*
+ * These bits are used to notify the task about pending events.
+ * The names correspond to the interrupt context routines that would
+ * be normally called. (example: AUE_TASK_WATCHDOG -> aue_watchdog())
+ */
+#define AUE_TASK_WATCHDOG 0x0001
+#define AUE_TASK_TICK 0x0002
+#define AUE_TASK_START 0x0004
+#define AUE_TASK_RXSTART 0x0008
+#define AUE_TASK_RXEOF 0x0010
+#define AUE_TASK_TXEOF 0x0020
#define AUE_GIANTLOCK() mtx_lock(&Giant);
#define AUE_GIANTUNLOCK() mtx_unlock(&Giant);
OpenPOWER on IntegriCloud