summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornetchild <netchild@FreeBSD.org>2005-10-02 15:43:57 +0000
committernetchild <netchild@FreeBSD.org>2005-10-02 15:43:57 +0000
commit64189db8f9fb40fc5f37654b4e5b4e770cb74562 (patch)
tree1d504890f882a85279fd6b8f488b3ab04f14a216 /sys
parent4846f24b0a4a69fef0bc9174b0c93fcc622821c4 (diff)
downloadFreeBSD-src-64189db8f9fb40fc5f37654b4e5b4e770cb74562.zip
FreeBSD-src-64189db8f9fb40fc5f37654b4e5b4e770cb74562.tar.gz
sys/dev/sound/pcm/sndstat.c:
* General spl* cleanup. It doesn't serve any purpose anymore. * Nuke sndstat_busy(). Addition of sndstat_acquire() / sndstat_release() for sndstat exclusive access. [1] sys/dev/sound/pcm/sound.c: * Remove duplicate SLIST_INIT() * Use sndstat_acquire() / release() to lock / release the entire sndstat during pcm_unregister(). This should fix LOR #159 [1] sys/dev/sound/pcm/sound.h: * Definition of SD_F_SOFTVOL (part of feeder volume) * Nuke sndstat_busy(). Addition of sndstat_acquire() / sndstat_release() for exclusive sndstat access. [1] Submitted by: Ariff Abdullah <skywizard@MyBSD.org.my> LOR: 159 [1] Discussed with: yongari [1]
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/pcm/sndstat.c66
-rw-r--r--sys/dev/sound/pcm/sound.c21
-rw-r--r--sys/dev/sound/pcm/sound.h6
3 files changed, 42 insertions, 51 deletions
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index 5ccf0b7..5b07ece 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -84,20 +84,17 @@ static int sndstat_prepare(struct sbuf *s);
static int
sysctl_hw_sndverbose(SYSCTL_HANDLER_ARGS)
{
- intrmask_t s;
int error, verbose;
verbose = sndstat_verbose;
error = sysctl_handle_int(oidp, &verbose, sizeof(verbose), req);
if (error == 0 && req->newptr != NULL) {
- s = spltty();
sx_xlock(&sndstat_lock);
if (verbose < 0 || verbose > 3)
error = EINVAL;
else
sndstat_verbose = verbose;
sx_xunlock(&sndstat_lock);
- splx(s);
}
return error;
}
@@ -107,19 +104,15 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, verbose, CTLTYPE_INT | CTLFLAG_RW,
static int
sndstat_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
{
- intrmask_t s;
int error;
- s = spltty();
sx_xlock(&sndstat_lock);
if (sndstat_isopen) {
sx_xunlock(&sndstat_lock);
- splx(s);
return EBUSY;
}
sndstat_isopen = 1;
sx_xunlock(&sndstat_lock);
- splx(s);
if (sbuf_new(&sndstat_sbuf, NULL, 4096, 0) == NULL) {
error = ENXIO;
goto out;
@@ -128,11 +121,9 @@ sndstat_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
error = (sndstat_prepare(&sndstat_sbuf) > 0) ? 0 : ENOMEM;
out:
if (error) {
- s = spltty();
sx_xlock(&sndstat_lock);
sndstat_isopen = 0;
sx_xunlock(&sndstat_lock);
- splx(s);
}
return (error);
}
@@ -140,34 +131,26 @@ out:
static int
sndstat_close(struct cdev *i_dev, int flags, int mode, struct thread *td)
{
- intrmask_t s;
-
- s = spltty();
sx_xlock(&sndstat_lock);
if (!sndstat_isopen) {
sx_xunlock(&sndstat_lock);
- splx(s);
return EBADF;
}
sbuf_delete(&sndstat_sbuf);
sndstat_isopen = 0;
sx_xunlock(&sndstat_lock);
- splx(s);
return 0;
}
static int
sndstat_read(struct cdev *i_dev, struct uio *buf, int flag)
{
- intrmask_t s;
int l, err;
- s = spltty();
sx_xlock(&sndstat_lock);
if (!sndstat_isopen) {
sx_xunlock(&sndstat_lock);
- splx(s);
return EBADF;
}
l = min(buf->uio_resid, sbuf_len(&sndstat_sbuf) - sndstat_bufptr);
@@ -175,7 +158,6 @@ sndstat_read(struct cdev *i_dev, struct uio *buf, int flag)
sndstat_bufptr += l;
sx_xunlock(&sndstat_lock);
- splx(s);
return err;
}
@@ -195,9 +177,34 @@ sndstat_find(int type, int unit)
}
int
+sndstat_acquire(void)
+{
+ sx_xlock(&sndstat_lock);
+ if (sndstat_isopen) {
+ sx_xunlock(&sndstat_lock);
+ return EBUSY;
+ }
+ sndstat_isopen = 1;
+ sx_xunlock(&sndstat_lock);
+ return 0;
+}
+
+int
+sndstat_release(void)
+{
+ sx_xlock(&sndstat_lock);
+ if (!sndstat_isopen) {
+ sx_xunlock(&sndstat_lock);
+ return EBADF;
+ }
+ sndstat_isopen = 0;
+ sx_xunlock(&sndstat_lock);
+ return 0;
+}
+
+int
sndstat_register(device_t dev, char *str, sndstat_handler handler)
{
- intrmask_t s;
struct sndstat_entry *ent;
const char *devtype;
int type, unit;
@@ -228,14 +235,12 @@ sndstat_register(device_t dev, char *str, sndstat_handler handler)
ent->unit = unit;
ent->handler = handler;
- s = spltty();
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_xunlock(&sndstat_lock);
- splx(s);
return 0;
}
@@ -249,23 +254,19 @@ sndstat_registerfile(char *str)
int
sndstat_unregister(device_t dev)
{
- intrmask_t s;
struct sndstat_entry *ent;
- s = spltty();
sx_xlock(&sndstat_lock);
SLIST_FOREACH(ent, &sndstat_devlist, link) {
if (ent->dev == dev) {
SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link);
sx_xunlock(&sndstat_lock);
- splx(s);
free(ent, M_DEVBUF);
return 0;
}
}
sx_xunlock(&sndstat_lock);
- splx(s);
return ENXIO;
}
@@ -273,24 +274,20 @@ sndstat_unregister(device_t dev)
int
sndstat_unregisterfile(char *str)
{
- intrmask_t s;
struct sndstat_entry *ent;
- s = spltty();
sx_xlock(&sndstat_lock);
SLIST_FOREACH(ent, &sndstat_devlist, link) {
if (ent->dev == NULL && ent->str == str) {
SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link);
sndstat_files--;
sx_xunlock(&sndstat_lock);
- splx(s);
free(ent, M_DEVBUF);
return 0;
}
}
sx_xunlock(&sndstat_lock);
- splx(s);
return ENXIO;
}
@@ -353,13 +350,9 @@ sndstat_init(void)
static int
sndstat_uninit(void)
{
- intrmask_t s;
-
- s = spltty();
sx_xlock(&sndstat_lock);
if (sndstat_isopen) {
sx_xunlock(&sndstat_lock);
- splx(s);
return EBUSY;
}
@@ -367,18 +360,11 @@ sndstat_uninit(void)
destroy_dev(sndstat_dev);
sndstat_dev = 0;
- splx(s);
sx_xunlock(&sndstat_lock);
sx_destroy(&sndstat_lock);
return 0;
}
-int
-sndstat_busy(void)
-{
- return (sndstat_isopen);
-}
-
static void
sndstat_sysinit(void *p)
{
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index a5ce1d3..4a9b2f9 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -719,7 +719,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
d->inprog = 0;
SLIST_INIT(&d->channels);
- SLIST_INIT(&d->channels);
if (((numplay == 0) || (numrec == 0)) && (numplay != numrec))
d->flags |= SD_F_SIMPLEX;
@@ -758,24 +757,25 @@ pcm_unregister(device_t dev)
struct snddev_channel *sce;
struct pcm_channel *ch;
+ if (sndstat_acquire() != 0) {
+ device_printf(dev, "unregister: sndstat busy\n");
+ return EBUSY;
+ }
+
snd_mtxlock(d->lock);
if (d->inprog) {
device_printf(dev, "unregister: operation in progress\n");
snd_mtxunlock(d->lock);
- return EBUSY;
- }
- if (sndstat_busy() != 0) {
- device_printf(dev, "unregister: sndstat busy\n");
- snd_mtxunlock(d->lock);
+ sndstat_release();
return EBUSY;
}
-
SLIST_FOREACH(sce, &d->channels, link) {
ch = sce->channel;
if (ch->refcount > 0) {
device_printf(dev, "unregister: channel %s busy (pid %d)\n", ch->name, ch->pid);
snd_mtxunlock(d->lock);
+ sndstat_release();
return EBUSY;
}
}
@@ -783,6 +783,7 @@ pcm_unregister(device_t dev)
if (mixer_uninit(dev)) {
device_printf(dev, "unregister: mixer busy\n");
snd_mtxunlock(d->lock);
+ sndstat_release();
return EBUSY;
}
@@ -807,9 +808,10 @@ pcm_unregister(device_t dev)
chn_kill(d->fakechan);
fkchan_kill(d->fakechan);
- sndstat_unregister(dev);
snd_mtxunlock(d->lock);
snd_mtxfree(d->lock);
+ sndstat_unregister(dev);
+ sndstat_release();
return 0;
}
@@ -905,7 +907,8 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose)
sbuf_printf(s, "(0x%08x -> 0x%08x)", f->desc->in, f->desc->out);
if (f->desc->type == FEEDER_RATE)
sbuf_printf(s, "(%d -> %d)", FEEDER_GET(f, FEEDRATE_SRC), FEEDER_GET(f, FEEDRATE_DST));
- if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER)
+ if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER ||
+ f->desc->type == FEEDER_VOLUME)
sbuf_printf(s, "(0x%08x)", f->desc->out);
sbuf_printf(s, " -> ");
f = f->parent;
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 471e51d..af539a6 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -130,7 +130,8 @@ nomenclature:
#define PCMMKMINOR(u, d, c) ((((c) & 0xff) << 16) | (((u) & 0x0f) << 4) | ((d) & 0x0f))
#define SD_F_SIMPLEX 0x00000001
-#define SD_F_AUTOVCHAN 0x00000002
+#define SD_F_AUTOVCHAN 0x00000002
+#define SD_F_SOFTVOL 0x00000004
#define SD_F_PRIO_RD 0x10000000
#define SD_F_PRIO_WR 0x20000000
#define SD_F_PRIO_SET (SD_F_PRIO_RD | SD_F_PRIO_WR)
@@ -238,11 +239,12 @@ void snd_mtxassert(void *m);
int sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS);
typedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose);
+int sndstat_acquire(void);
+int sndstat_release(void);
int sndstat_register(device_t dev, char *str, sndstat_handler handler);
int sndstat_registerfile(char *str);
int sndstat_unregister(device_t dev);
int sndstat_unregisterfile(char *str);
-int sndstat_busy(void);
#define SND_DECLARE_FILE(version) \
_SND_DECLARE_FILE(__LINE__, version)
OpenPOWER on IntegriCloud