Index: kernel/OS/FreeBSD/os_freebsd.c ================================================================== --- kernel/OS/FreeBSD/os_freebsd.c +++ kernel/OS/FreeBSD/os_freebsd.c @@ -471,19 +471,21 @@ volatile int active; int timestamp; void (*func) (void *); void *arg; - struct callout_handle timer; + struct callout timer; } tmout_desc_t; static volatile int next_id = 0; #define MAX_TMOUTS 128 tmout_desc_t tmouts[MAX_TMOUTS] = { {0} }; int timeout_random = 0x12123400; + +static struct mtx oss_timeout_mutex; void oss_timer_callback (void *arg) { int ix; @@ -505,10 +507,12 @@ oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks) { tmout_desc_t *tmout = NULL; int id, n; + mtx_lock(&oss_timeout_mutex); + timeout_random++; n = 0; id = -1; @@ -525,19 +529,22 @@ next_id = (next_id + 1) % MAX_TMOUTS; } if (id == -1) /* No timer slots available */ { + mtx_unlock(&oss_timeout_mutex); cmn_err (CE_CONT, "Timeout table full\n"); return 0; } tmout->func = func; tmout->arg = arg; tmout->timestamp = id | (timeout_random & ~0xff); - tmout->timer = timeout (oss_timer_callback, tmout, ticks); + mtx_unlock(&oss_timeout_mutex); + + callout_reset(&tmout->timer, ticks, oss_timer_callback, tmout); return id | (timeout_random & ~0xff); } void @@ -548,17 +555,21 @@ ix = id & 0xff; if (ix < 0 || ix >= MAX_TMOUTS) return; + mtx_lock(&oss_timeout_mutex); + timeout_random++; tmout = &tmouts[ix]; + + mtx_unlock(&oss_timeout_mutex); if (tmout->timestamp != id) /* Expired timer */ return; if (tmout->active) - untimeout (oss_timer_callback, tmout, tmout->timer); + callout_stop(&tmout->timer); tmout->active = 0; tmout->timestamp = 0; } int @@ -616,10 +627,11 @@ } int soundcard_attach (void) { + int i; oss_device_t *osdev; if (module_lookupbyname("sound") != NULL) { cmn_err (CE_WARN, "Open Sound System conflicts with FreeBSD driver\n"); @@ -647,10 +659,16 @@ osdev->major = oss_major; oss_register_device (osdev, "OSS core services"); oss_common_init (osdev); + mtx_init(&oss_timeout_mutex, "OSS timeout", NULL, MTX_DEF); + + for (i = 0; i < MAX_TMOUTS; ++i) + callout_init_mtx(&tmouts[i].timer, &oss_timeout_mutex, + CALLOUT_RETURNUNLOCKED); + return 0; } int soundcard_detach (void) @@ -657,10 +675,15 @@ { int i; if (refcount > 0 || open_devices > 0) return EBUSY; + + for (i = 0; i < MAX_TMOUTS; ++i) + callout_drain(&tmouts[i].timer); + + mtx_destroy(&oss_timeout_mutex); oss_unload_drivers (); osdev_delete (core_osdev);