From owner-svn-src-all@freebsd.org Tue Feb 9 17:09:16 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0455AAA3948; Tue, 9 Feb 2016 17:09:16 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B909111CF; Tue, 9 Feb 2016 17:09:15 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u19H9EBP092335; Tue, 9 Feb 2016 17:09:14 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u19H9EVs092332; Tue, 9 Feb 2016 17:09:14 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201602091709.u19H9EVs092332@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Tue, 9 Feb 2016 17:09:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295440 - head/sys/dev/sound/pcm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Feb 2016 17:09:16 -0000 Author: hselasky Date: Tue Feb 9 17:09:14 2016 New Revision: 295440 URL: https://svnweb.freebsd.org/changeset/base/295440 Log: To support userspace audio daemons like Virtual OSS, /dev/sndstat is made writeable by the root user. Userspace audio daemons can add or update an entry in /dev/sndstat by doing a single system write call to any /dev/sndstat file descriptor handle. When the audio daemon closes the file handle or is killed the entry disappears. While at it, cleanup the sound status code a bit: - keep the device list sorted to avoid sorting the list every time a /dev/sndstat read request is made. - factor out locking into a pair of locking macros. - use the sound status lock to protect all per file handle states, when generating the output for /dev/sndstat and when removing or adding sound status devices. This way sndstat_acquire() and sndstat_release() become superfluous and can be removed. Reviewed by: mav @ Differential Revision: https://reviews.freebsd.org/D5191 Modified: head/sys/dev/sound/pcm/sndstat.c head/sys/dev/sound/pcm/sound.c head/sys/dev/sound/pcm/sound.h Modified: head/sys/dev/sound/pcm/sndstat.c ============================================================================== --- head/sys/dev/sound/pcm/sndstat.c Tue Feb 9 16:58:50 2016 (r295439) +++ head/sys/dev/sound/pcm/sndstat.c Tue Feb 9 17:09:14 2016 (r295440) @@ -37,77 +37,51 @@ SND_DECLARE_FILE("$FreeBSD$"); #define SS_TYPE_MODULE 0 -#define SS_TYPE_FIRST 1 #define SS_TYPE_PCM 1 #define SS_TYPE_MIDI 2 #define SS_TYPE_SEQUENCER 3 -#define SS_TYPE_LAST 3 static d_open_t sndstat_open; -static d_close_t sndstat_close; +static void sndstat_close(void *); static d_read_t sndstat_read; +static d_write_t sndstat_write; static struct cdevsw sndstat_cdevsw = { .d_version = D_VERSION, .d_open = sndstat_open, - .d_close = sndstat_close, .d_read = sndstat_read, + .d_write = sndstat_write, .d_name = "sndstat", .d_flags = D_TRACKCLOSE, }; struct sndstat_entry { - SLIST_ENTRY(sndstat_entry) link; + TAILQ_ENTRY(sndstat_entry) link; device_t dev; char *str; sndstat_handler handler; int type, unit; }; -static struct sx sndstat_lock; -static struct sbuf sndstat_sbuf; -static struct cdev *sndstat_dev = NULL; -static int sndstat_bufptr = -1; -static int sndstat_maxunit = -1; -static int sndstat_files = 0; - -#define SNDSTAT_PID(x) ((pid_t)((intptr_t)((x)->si_drv1))) -#define SNDSTAT_PID_SET(x, y) (x)->si_drv1 = (void *)((intptr_t)(y)) -#define SNDSTAT_FLUSH() do { \ - if (sndstat_bufptr != -1) { \ - sbuf_delete(&sndstat_sbuf); \ - sndstat_bufptr = -1; \ - } \ -} while (0) +struct sndstat_file { + TAILQ_ENTRY(sndstat_file) entry; + struct sbuf sbuf; + int out_offset; + int in_offset; +}; -static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(sndstat_devlist); +static struct sx sndstat_lock; +static struct cdev *sndstat_dev; -int snd_verbose = 0; +#define SNDSTAT_LOCK() sx_xlock(&sndstat_lock) +#define SNDSTAT_UNLOCK() sx_xunlock(&sndstat_lock) -#ifdef SND_DEBUG -static int -sysctl_hw_snd_sndstat_pid(SYSCTL_HANDLER_ARGS) -{ - int err, val; +static TAILQ_HEAD(, sndstat_entry) sndstat_devlist = TAILQ_HEAD_INITIALIZER(sndstat_devlist); +static TAILQ_HEAD(, sndstat_file) sndstat_filelist = TAILQ_HEAD_INITIALIZER(sndstat_filelist); - if (sndstat_dev == NULL) - return (EINVAL); - - sx_xlock(&sndstat_lock); - val = (int)SNDSTAT_PID(sndstat_dev); - err = sysctl_handle_int(oidp, &val, 0, req); - if (err == 0 && req->newptr != NULL && val == 0) { - SNDSTAT_FLUSH(); - SNDSTAT_PID_SET(sndstat_dev, 0); - } - sx_unlock(&sndstat_lock); - return (err); -} -SYSCTL_PROC(_hw_snd, OID_AUTO, sndstat_pid, CTLTYPE_INT | CTLFLAG_RWTUN, - 0, sizeof(int), sysctl_hw_snd_sndstat_pid, "I", "sndstat busy pid"); -#endif +int snd_verbose = 0; -static int sndstat_prepare(struct sbuf *s); +static int sndstat_prepare(struct sndstat_file *); static int sysctl_hw_sndverbose(SYSCTL_HANDLER_ARGS) @@ -122,7 +96,7 @@ sysctl_hw_sndverbose(SYSCTL_HANDLER_ARGS else snd_verbose = verbose; } - return error; + return (error); } SYSCTL_PROC(_hw_snd, OID_AUTO, verbose, CTLTYPE_INT | CTLFLAG_RWTUN, 0, sizeof(int), sysctl_hw_sndverbose, "I", "verbosity level"); @@ -130,128 +104,135 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, verbose, static int sndstat_open(struct cdev *i_dev, int flags, int mode, struct thread *td) { - if (sndstat_dev == NULL || i_dev != sndstat_dev) - return EBADF; + struct sndstat_file *pf; - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(i_dev) != 0) { - sx_unlock(&sndstat_lock); - return EBUSY; - } - SNDSTAT_PID_SET(i_dev, td->td_proc->p_pid); - if (sbuf_new(&sndstat_sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { - SNDSTAT_PID_SET(i_dev, 0); - sx_unlock(&sndstat_lock); - return ENXIO; - } - sndstat_bufptr = 0; - sx_unlock(&sndstat_lock); - return 0; -} + pf = malloc(sizeof(*pf), M_DEVBUF, M_WAITOK | M_ZERO); -static int -sndstat_close(struct cdev *i_dev, int flags, int mode, struct thread *td) -{ - if (sndstat_dev == NULL || i_dev != sndstat_dev) - return EBADF; - - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(i_dev) == 0) { - sx_unlock(&sndstat_lock); - return EBADF; + SNDSTAT_LOCK(); + if (sbuf_new(&pf->sbuf, NULL, 4096, SBUF_AUTOEXTEND) == NULL) { + SNDSTAT_UNLOCK(); + free(pf, M_DEVBUF); + return (ENOMEM); } + TAILQ_INSERT_TAIL(&sndstat_filelist, pf, entry); + SNDSTAT_UNLOCK(); - SNDSTAT_FLUSH(); - SNDSTAT_PID_SET(i_dev, 0); - - sx_unlock(&sndstat_lock); + devfs_set_cdevpriv(pf, &sndstat_close); - return 0; + return (0); } -static int -sndstat_read(struct cdev *i_dev, struct uio *buf, int flag) +static void +sndstat_close(void *sndstat_file) { - int l, err; + struct sndstat_file *pf = (struct sndstat_file *)sndstat_file; - if (sndstat_dev == NULL || i_dev != sndstat_dev) - return EBADF; + SNDSTAT_LOCK(); + sbuf_delete(&pf->sbuf); + TAILQ_REMOVE(&sndstat_filelist, pf, entry); + SNDSTAT_UNLOCK(); - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(i_dev) != buf->uio_td->td_proc->p_pid || - sndstat_bufptr == -1) { - sx_unlock(&sndstat_lock); - return EBADF; - } - - if (sndstat_bufptr == 0) { - err = (sndstat_prepare(&sndstat_sbuf) > 0) ? 0 : ENOMEM; - if (err) { - SNDSTAT_FLUSH(); - sx_unlock(&sndstat_lock); - return err; - } - } - - l = min(buf->uio_resid, sbuf_len(&sndstat_sbuf) - sndstat_bufptr); - err = (l > 0)? uiomove(sbuf_data(&sndstat_sbuf) + sndstat_bufptr, l, buf) : 0; - sndstat_bufptr += l; - sx_unlock(&sndstat_lock); - - return err; + free(pf, M_DEVBUF); } -/************************************************************************/ - -static struct sndstat_entry * -sndstat_find(int type, int unit) +static int +sndstat_read(struct cdev *i_dev, struct uio *buf, int flag) { - struct sndstat_entry *ent; - - SLIST_FOREACH(ent, &sndstat_devlist, link) { - if (ent->type == type && ent->unit == unit) - return ent; + struct sndstat_file *pf; + int err; + int len; + + err = devfs_get_cdevpriv((void **)&pf); + if (err != 0) + return (err); + + /* skip zero-length reads */ + if (buf->uio_resid == 0) + return (0); + + SNDSTAT_LOCK(); + if (pf->out_offset != 0) { + /* don't allow both reading and writing */ + err = EINVAL; + goto done; + } else if (pf->in_offset == 0) { + err = sndstat_prepare(pf); + if (err <= 0) { + err = ENOMEM; + goto done; + } } - - return NULL; + len = sbuf_len(&pf->sbuf) - pf->in_offset; + if (len > buf->uio_resid) + len = buf->uio_resid; + if (len > 0) + err = uiomove(sbuf_data(&pf->sbuf) + pf->in_offset, len, buf); + pf->in_offset += len; +done: + SNDSTAT_UNLOCK(); + return (err); } -int -sndstat_acquire(struct thread *td) +static int +sndstat_write(struct cdev *i_dev, struct uio *buf, int flag) { - if (sndstat_dev == NULL) - return EBADF; - - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(sndstat_dev) != 0) { - sx_unlock(&sndstat_lock); - return EBUSY; - } - SNDSTAT_PID_SET(sndstat_dev, td->td_proc->p_pid); - sx_unlock(&sndstat_lock); - return 0; + struct sndstat_file *pf; + uint8_t temp[64]; + int err; + int len; + + err = devfs_get_cdevpriv((void **)&pf); + if (err != 0) + return (err); + + /* skip zero-length writes */ + if (buf->uio_resid == 0) + return (0); + + /* don't allow writing more than 64Kbytes */ + if (buf->uio_resid > 65536) + return (ENOMEM); + + SNDSTAT_LOCK(); + if (pf->in_offset != 0) { + /* don't allow both reading and writing */ + err = EINVAL; + } else { + /* only remember the last write - allows for updates */ + sbuf_clear(&pf->sbuf); + while (1) { + len = sizeof(temp); + if (len > buf->uio_resid) + len = buf->uio_resid; + if (len > 0) { + err = uiomove(temp, len, buf); + if (err) + break; + } else { + break; + } + if (sbuf_bcat(&pf->sbuf, temp, len) < 0) { + err = ENOMEM; + break; + } + } + sbuf_finish(&pf->sbuf); + if (err == 0) + pf->out_offset = sbuf_len(&pf->sbuf); + else + pf->out_offset = 0; + } + SNDSTAT_UNLOCK(); + return (err); } -int -sndstat_release(struct thread *td) -{ - if (sndstat_dev == NULL) - return EBADF; - - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(sndstat_dev) != td->td_proc->p_pid) { - sx_unlock(&sndstat_lock); - return EBADF; - } - SNDSTAT_PID_SET(sndstat_dev, 0); - sx_unlock(&sndstat_lock); - return 0; -} +/************************************************************************/ int sndstat_register(device_t dev, char *str, sndstat_handler handler) { struct sndstat_entry *ent; + struct sndstat_entry *pre; const char *devtype; int type, unit; @@ -265,7 +246,7 @@ sndstat_register(device_t dev, char *str else if (!strcmp(devtype, "sequencer")) type = SS_TYPE_SEQUENCER; else - return EINVAL; + return (EINVAL); } else { type = SS_TYPE_MODULE; unit = -1; @@ -278,168 +259,167 @@ sndstat_register(device_t dev, char *str ent->unit = unit; ent->handler = handler; - sx_xlock(&sndstat_lock); - SLIST_INSERT_HEAD(&sndstat_devlist, ent, link); - if (type == SS_TYPE_MODULE) - sndstat_files++; - sndstat_maxunit = (unit > sndstat_maxunit)? unit : sndstat_maxunit; - sx_unlock(&sndstat_lock); + SNDSTAT_LOCK(); + /* sorted list insertion */ + TAILQ_FOREACH(pre, &sndstat_devlist, link) { + if (pre->unit > unit) + break; + else if (pre->unit < unit) + continue; + if (pre->type > type) + break; + else if (pre->type < unit) + continue; + } + if (pre == NULL) { + TAILQ_INSERT_TAIL(&sndstat_devlist, ent, link); + } else { + TAILQ_INSERT_BEFORE(pre, ent, link); + } + SNDSTAT_UNLOCK(); - return 0; + return (0); } int sndstat_registerfile(char *str) { - return sndstat_register(NULL, str, NULL); + return (sndstat_register(NULL, str, NULL)); } int sndstat_unregister(device_t dev) { struct sndstat_entry *ent; + int error = ENXIO; - sx_xlock(&sndstat_lock); - SLIST_FOREACH(ent, &sndstat_devlist, link) { + SNDSTAT_LOCK(); + TAILQ_FOREACH(ent, &sndstat_devlist, link) { if (ent->dev == dev) { - SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link); - sx_unlock(&sndstat_lock); + TAILQ_REMOVE(&sndstat_devlist, ent, link); free(ent, M_DEVBUF); - - return 0; + error = 0; + break; } } - sx_unlock(&sndstat_lock); + SNDSTAT_UNLOCK(); - return ENXIO; + return (error); } int sndstat_unregisterfile(char *str) { struct sndstat_entry *ent; + int error = ENXIO; - sx_xlock(&sndstat_lock); - SLIST_FOREACH(ent, &sndstat_devlist, link) { + SNDSTAT_LOCK(); + TAILQ_FOREACH(ent, &sndstat_devlist, link) { if (ent->dev == NULL && ent->str == str) { - SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link); - sndstat_files--; - sx_unlock(&sndstat_lock); + TAILQ_REMOVE(&sndstat_devlist, ent, link); free(ent, M_DEVBUF); - - return 0; + error = 0; + break; } } - sx_unlock(&sndstat_lock); + SNDSTAT_UNLOCK(); - return ENXIO; + return (error); } /************************************************************************/ static int -sndstat_prepare(struct sbuf *s) +sndstat_prepare(struct sndstat_file *pf_self) { + struct sbuf *s = &pf_self->sbuf; struct sndstat_entry *ent; struct snddev_info *d; - int i, j; + struct sndstat_file *pf; + int k; + /* make sure buffer is reset */ + sbuf_clear(s); + if (snd_verbose > 0) { sbuf_printf(s, "FreeBSD Audio Driver (%ubit %d/%s)\n", (u_int)sizeof(intpcm32_t) << 3, SND_DRV_VERSION, MACHINE_ARCH); } - if (SLIST_EMPTY(&sndstat_devlist)) { - sbuf_printf(s, "No devices installed.\n"); - sbuf_finish(s); - return sbuf_len(s); - } - - sbuf_printf(s, "Installed devices:\n"); - - for (i = 0; i <= sndstat_maxunit; i++) { - for (j = SS_TYPE_FIRST; j <= SS_TYPE_LAST; j++) { - ent = sndstat_find(j, i); - if (!ent) - continue; - d = device_get_softc(ent->dev); - if (!PCM_REGISTERED(d)) - continue; + /* generate list of installed devices */ + k = 0; + TAILQ_FOREACH(ent, &sndstat_devlist, link) { + if (ent->dev == NULL) + continue; + d = device_get_softc(ent->dev); + if (!PCM_REGISTERED(d)) + continue; + if (!k++) + sbuf_printf(s, "Installed devices:\n"); + sbuf_printf(s, "%s:", device_get_nameunit(ent->dev)); + sbuf_printf(s, " <%s>", device_get_desc(ent->dev)); + if (snd_verbose > 0) + sbuf_printf(s, " %s", ent->str); + if (ent->handler) { /* XXX Need Giant magic entry ??? */ PCM_ACQUIRE_QUICK(d); - sbuf_printf(s, "%s:", device_get_nameunit(ent->dev)); - sbuf_printf(s, " <%s>", device_get_desc(ent->dev)); - if (snd_verbose > 0) - sbuf_printf(s, " %s", ent->str); - if (ent->handler) - ent->handler(s, ent->dev, snd_verbose); - sbuf_printf(s, "\n"); + ent->handler(s, ent->dev, snd_verbose); PCM_RELEASE_QUICK(d); } - } - - if (snd_verbose >= 3 && sndstat_files > 0) { - sbuf_printf(s, "\nFile Versions:\n"); + sbuf_printf(s, "\n"); + } + if (k == 0) + sbuf_printf(s, "No devices installed.\n"); - SLIST_FOREACH(ent, &sndstat_devlist, link) { - if (ent->dev == NULL && ent->str != NULL) + /* append any input from userspace */ + k = 0; + TAILQ_FOREACH(pf, &sndstat_filelist, entry) { + if (pf == pf_self) + continue; + if (pf->out_offset == 0) + continue; + if (!k++) + sbuf_printf(s, "Installed devices from userspace:\n"); + sbuf_bcat(s, sbuf_data(&pf->sbuf), + sbuf_len(&pf->sbuf)); + } + if (k == 0) + sbuf_printf(s, "No devices installed from userspace.\n"); + + /* append any file versions */ + if (snd_verbose >= 3) { + k = 0; + TAILQ_FOREACH(ent, &sndstat_devlist, link) { + if (ent->dev == NULL && ent->str != NULL) { + if (!k++) + sbuf_printf(s, "\nFile Versions:\n"); sbuf_printf(s, "%s\n", ent->str); + } } + if (k == 0) + sbuf_printf(s, "\nNo file versions.\n"); } - sbuf_finish(s); - return sbuf_len(s); -} - -static int -sndstat_init(void) -{ - if (sndstat_dev != NULL) - return EINVAL; - sx_init(&sndstat_lock, "sndstat lock"); - sndstat_dev = make_dev(&sndstat_cdevsw, SND_DEV_STATUS, - UID_ROOT, GID_WHEEL, 0444, "sndstat"); - return 0; -} - -static int -sndstat_uninit(void) -{ - if (sndstat_dev == NULL) - return EINVAL; - - sx_xlock(&sndstat_lock); - if (SNDSTAT_PID(sndstat_dev) != curthread->td_proc->p_pid) { - sx_unlock(&sndstat_lock); - return EBUSY; - } - - /* XXXPHO: use destroy_dev_sched() */ - destroy_dev(sndstat_dev); - sndstat_dev = NULL; - - SNDSTAT_FLUSH(); - - sx_unlock(&sndstat_lock); - sx_destroy(&sndstat_lock); - return 0; + return (sbuf_len(s)); } static void sndstat_sysinit(void *p) { - sndstat_init(); + sx_init(&sndstat_lock, "sndstat lock"); + sndstat_dev = make_dev(&sndstat_cdevsw, SND_DEV_STATUS, + UID_ROOT, GID_WHEEL, 0644, "sndstat"); } +SYSINIT(sndstat_sysinit, SI_SUB_DRIVERS, SI_ORDER_FIRST, sndstat_sysinit, NULL); static void sndstat_sysuninit(void *p) { - int error; - - error = sndstat_uninit(); - KASSERT(error == 0, ("%s: error = %d", __func__, error)); + if (sndstat_dev != NULL) { + /* destroy_dev() will wait for all references to go away */ + destroy_dev(sndstat_dev); + } + sx_destroy(&sndstat_lock); } - -SYSINIT(sndstat_sysinit, SI_SUB_DRIVERS, SI_ORDER_FIRST, sndstat_sysinit, NULL); SYSUNINIT(sndstat_sysuninit, SI_SUB_DRIVERS, SI_ORDER_FIRST, sndstat_sysuninit, NULL); Modified: head/sys/dev/sound/pcm/sound.c ============================================================================== --- head/sys/dev/sound/pcm/sound.c Tue Feb 9 16:58:50 2016 (r295439) +++ head/sys/dev/sound/pcm/sound.c Tue Feb 9 17:09:14 2016 (r295440) @@ -1153,18 +1153,12 @@ pcm_unregister(device_t dev) return (0); } - if (sndstat_acquire(td) != 0) { - device_printf(dev, "unregister: sndstat busy\n"); - return (EBUSY); - } - PCM_LOCK(d); PCM_WAIT(d); if (d->inprog != 0) { device_printf(dev, "unregister: operation in progress\n"); PCM_UNLOCK(d); - sndstat_release(td); return (EBUSY); } @@ -1179,7 +1173,6 @@ pcm_unregister(device_t dev) ch->name, ch->pid); CHN_UNLOCK(ch); PCM_RELEASE_QUICK(d); - sndstat_release(td); return (EBUSY); } CHN_UNLOCK(ch); @@ -1189,7 +1182,6 @@ pcm_unregister(device_t dev) if (snd_clone_busy(d->clones) != 0) { device_printf(dev, "unregister: clone busy\n"); PCM_RELEASE_QUICK(d); - sndstat_release(td); return (EBUSY); } else { PCM_LOCK(d); @@ -1205,10 +1197,12 @@ pcm_unregister(device_t dev) (void)snd_clone_enable(d->clones); PCM_RELEASE(d); PCM_UNLOCK(d); - sndstat_release(td); return (EBUSY); } + /* remove /dev/sndstat entry first */ + sndstat_unregister(dev); + PCM_LOCK(d); d->flags |= SD_F_DYING; d->flags &= ~SD_F_REGISTERED; @@ -1242,8 +1236,6 @@ pcm_unregister(device_t dev) cv_destroy(&d->cv); PCM_UNLOCK(d); snd_mtxfree(d->lock); - sndstat_unregister(dev); - sndstat_release(td); if (snd_unit == device_get_unit(dev)) { snd_unit = pcm_best_unit(-1); @@ -1415,9 +1407,6 @@ sound_modevent(module_t mod, int type, v pcmsg_unrhdr = new_unrhdr(1, INT_MAX, NULL); break; case MOD_UNLOAD: - ret = sndstat_acquire(curthread); - if (ret != 0) - break; if (pcmsg_unrhdr != NULL) { delete_unrhdr(pcmsg_unrhdr); pcmsg_unrhdr = NULL; Modified: head/sys/dev/sound/pcm/sound.h ============================================================================== --- head/sys/dev/sound/pcm/sound.h Tue Feb 9 16:58:50 2016 (r295439) +++ head/sys/dev/sound/pcm/sound.h Tue Feb 9 17:09:14 2016 (r295440) @@ -350,8 +350,6 @@ void snd_mtxassert(void *m); #define snd_mtxunlock(m) mtx_unlock(m) typedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose); -int sndstat_acquire(struct thread *td); -int sndstat_release(struct thread *td); int sndstat_register(device_t dev, char *str, sndstat_handler handler); int sndstat_registerfile(char *str); int sndstat_unregister(device_t dev);