summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2016-02-09 17:09:14 +0000
committerhselasky <hselasky@FreeBSD.org>2016-02-09 17:09:14 +0000
commit4a8d8f7fba6ae0abcfae7ee40db2bcf9b563fe01 (patch)
treeec2214ed481c12474964e82661ccf4447aabd5f8 /sys/dev/sound
parent327efa1f370e07e616f2d2adcd796a056eae2454 (diff)
downloadFreeBSD-src-4a8d8f7fba6ae0abcfae7ee40db2bcf9b563fe01.zip
FreeBSD-src-4a8d8f7fba6ae0abcfae7ee40db2bcf9b563fe01.tar.gz
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
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/pcm/sndstat.c464
-rw-r--r--sys/dev/sound/pcm/sound.c17
-rw-r--r--sys/dev/sound/pcm/sound.h2
3 files changed, 225 insertions, 258 deletions
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index 2162145..e0cb5df 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -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)
-
-static SLIST_HEAD(, sndstat_entry) sndstat_devlist = SLIST_HEAD_INITIALIZER(sndstat_devlist);
+struct sndstat_file {
+ TAILQ_ENTRY(sndstat_file) entry;
+ struct sbuf sbuf;
+ int out_offset;
+ int in_offset;
+};
-int snd_verbose = 0;
+static struct sx sndstat_lock;
+static struct cdev *sndstat_dev;
-#ifdef SND_DEBUG
-static int
-sysctl_hw_snd_sndstat_pid(SYSCTL_HANDLER_ARGS)
-{
- int err, val;
+#define SNDSTAT_LOCK() sx_xlock(&sndstat_lock)
+#define SNDSTAT_UNLOCK() sx_xunlock(&sndstat_lock)
- if (sndstat_dev == NULL)
- return (EINVAL);
+static TAILQ_HEAD(, sndstat_entry) sndstat_devlist = TAILQ_HEAD_INITIALIZER(sndstat_devlist);
+static TAILQ_HEAD(, sndstat_file) sndstat_filelist = TAILQ_HEAD_INITIALIZER(sndstat_filelist);
- 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, CTLTYPE_INT | CTLFLAG_RWTUN,
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;
-}
-
-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;
+ pf = malloc(sizeof(*pf), M_DEVBUF, M_WAITOK | M_ZERO);
- 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);
+ devfs_set_cdevpriv(pf, &sndstat_close);
- sx_unlock(&sndstat_lock);
-
- 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;
-
- if (sndstat_dev == NULL || i_dev != sndstat_dev)
- return EBADF;
+ struct sndstat_file *pf = (struct sndstat_file *)sndstat_file;
- 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);
+ SNDSTAT_LOCK();
+ sbuf_delete(&pf->sbuf);
+ TAILQ_REMOVE(&sndstat_filelist, pf, entry);
+ SNDSTAT_UNLOCK();
- 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;
+ 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_PID_SET(sndstat_dev, td->td_proc->p_pid);
- sx_unlock(&sndstat_lock);
- return 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, sndstat_handler handler)
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, sndstat_handler handler)
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);
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 108c284..44b77ee 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -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, void *data)
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;
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 32e0343..2897aed 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -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);
OpenPOWER on IntegriCloud