diff --git a/sys/dev/speaker/spkr.c b/dev/speaker/spkr.c --- a/sys/dev/speaker/spkr.c +++ b/dev/speaker/spkr.c @@ -14,9 +14,12 @@ #include #include #include +#include #include #include +static struct mtx spkr_mtx; + static d_open_t spkropen; static d_close_t spkrclose; static d_write_t spkrwrite; @@ -24,7 +27,6 @@ static struct cdevsw spkr_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = spkropen, .d_close = spkrclose, .d_write = spkrwrite, @@ -396,7 +398,6 @@ * endtone(), and rest() functions defined above. */ -static int spkr_active = FALSE; /* exclusion flag */ static char *spkr_inbuf; /* incoming buf */ static int @@ -406,17 +407,17 @@ (void) printf("spkropen: entering with dev = %s\n", devtoname(dev)); #endif /* DEBUG */ - if (spkr_active) + int r; + + r = mtx_trylock(&spkr_mtx); + if (r == 0) return(EBUSY); - else { #ifdef DEBUG - (void) printf("spkropen: about to perform play initialization\n"); + (void) printf("spkropen: about to perform play initialization\n"); #endif /* DEBUG */ - playinit(); - spkr_inbuf = malloc(DEV_BSIZE, M_SPKR, M_WAITOK); - spkr_active = TRUE; - return(0); - } + playinit(); + spkr_inbuf = malloc(DEV_BSIZE, M_SPKR, M_WAITOK); + return(0); } static int @@ -455,7 +456,7 @@ wakeup(&endtone); wakeup(&endrest); free(spkr_inbuf, M_SPKR); - spkr_active = FALSE; + mtx_unlock(&spkr_mtx); return(0); } @@ -511,12 +512,16 @@ switch(type) { case MOD_LOAD: + mtx_init(&spkr_mtx, "speaker lock", NULL, MTX_DEF); speaker_dev = make_dev(&spkr_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "speaker"); break; case MOD_SHUTDOWN: case MOD_UNLOAD: destroy_dev(speaker_dev); + mtx_lock(&spkr_mtx); + mtx_unlock(&spkr_mtx); + mtx_destroy(&spkr_mtx); break; default: error = EOPNOTSUPP;