summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2002-11-25 17:17:43 +0000
committercg <cg@FreeBSD.org>2002-11-25 17:17:43 +0000
commitc9457db52b78b8fe2844cb837ee11d32cb013d0b (patch)
treeac1448d81f09f0d496c1b9ce490a1df51856353d /sys/dev/sound
parent79ac90c6dbdb26a4402c5fb31a4a94d6e72e133e (diff)
downloadFreeBSD-src-c9457db52b78b8fe2844cb837ee11d32cb013d0b.zip
FreeBSD-src-c9457db52b78b8fe2844cb837ee11d32cb013d0b.tar.gz
various fixes to eliminate locking warnings
Approved by: re Reviewed by: orion
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/pcm/buffer.c38
-rw-r--r--sys/dev/sound/pcm/channel.c18
-rw-r--r--sys/dev/sound/pcm/feeder.c2
-rw-r--r--sys/dev/sound/pcm/feeder_fmt.c6
-rw-r--r--sys/dev/sound/pcm/feeder_rate.c4
-rw-r--r--sys/dev/sound/pcm/sndstat.c4
-rw-r--r--sys/dev/sound/pcm/sound.c42
-rw-r--r--sys/dev/sound/pcm/sound.h6
-rw-r--r--sys/dev/sound/pcm/vchan.c16
9 files changed, 79 insertions, 57 deletions
diff --git a/sys/dev/sound/pcm/buffer.c b/sys/dev/sound/pcm/buffer.c
index 1604b9d..d498591 100644
--- a/sys/dev/sound/pcm/buffer.c
+++ b/sys/dev/sound/pcm/buffer.c
@@ -143,7 +143,7 @@ sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
b->bufsize = blkcnt * blksz;
if (b->tmpbuf)
free(b->tmpbuf, M_DEVBUF);
- b->tmpbuf = malloc(b->bufsize, M_DEVBUF, M_WAITOK);
+ b->tmpbuf = malloc(b->bufsize, M_DEVBUF, M_NOWAIT);
sndbuf_reset(b);
return 0;
}
@@ -151,26 +151,38 @@ sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
int
sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
{
+ u_int8_t *buf, *tmpbuf, *f1, *f2;
+ unsigned int bufsize;
+
if (blkcnt < 2 || blksz < 16)
return EINVAL;
- b->blkcnt = blkcnt;
- b->blksz = blksz;
+ bufsize = blksz * blkcnt;
- b->maxsize = blkcnt * blksz;
- b->bufsize = b->maxsize;
- if (b->buf)
- free(b->buf, M_DEVBUF);
- b->buf = malloc(b->bufsize, M_DEVBUF, M_WAITOK);
- if (b->buf == NULL)
+ buf = malloc(bufsize, M_DEVBUF, M_NOWAIT);
+ if (buf == NULL)
return ENOMEM;
- if (b->tmpbuf)
- free(b->tmpbuf, M_DEVBUF);
- b->tmpbuf = malloc(b->bufsize, M_DEVBUF, M_WAITOK);
- if (b->tmpbuf == NULL)
+ tmpbuf = malloc(bufsize, M_DEVBUF, M_NOWAIT);
+ if (tmpbuf == NULL) {
+ free(buf, M_DEVBUF);
return ENOMEM;
+ }
+
+ b->blkcnt = blkcnt;
+ b->blksz = blksz;
+ b->bufsize = bufsize;
+ b->maxsize = bufsize;
+ f1 = b->buf;
+ f2 = b->tmpbuf;
+ b->buf = buf;
+ b->tmpbuf = tmpbuf;
+
+ if (f1)
+ free(f1, M_DEVBUF);
+ if (f2)
+ free(f2, M_DEVBUF);
sndbuf_reset(b);
return 0;
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index d81125b..9bf9158 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -674,7 +674,6 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir)
int ret;
chn_lockinit(c);
- CHN_LOCK(c);
b = NULL;
bs = NULL;
@@ -739,7 +738,6 @@ out:
return ret;
}
- CHN_UNLOCK(c);
return 0;
}
@@ -749,7 +747,6 @@ chn_kill(struct pcm_channel *c)
struct snd_dbuf *b = c->bufhard;
struct snd_dbuf *bs = c->bufsoft;
- CHN_LOCK(c);
if (c->flags & CHN_F_TRIGGERED)
chn_trigger(c, PCMTRIG_ABORT);
while (chn_removefeeder(c) == 0);
@@ -929,7 +926,7 @@ chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
blkcnt = CHN_2NDBUFMAXSIZE / blksz;
RANGE(blksz, 16, CHN_2NDBUFMAXSIZE / 2);
- RANGE(blkcnt, 2, CHN_2NDBUFMAXSIZE / blksz);
+ RANGE(blkcnt, 2, CHN_2NDBUFMAXSIZE / blksz);
DEB(printf("%s: defaulting to (%d, %d)\n", __func__, blkcnt, blksz));
} else {
blkcnt = sndbuf_getblkcnt(bs);
@@ -946,10 +943,9 @@ chn_setblocksize(struct pcm_channel *c, int blkcnt, int blksz)
bufsz = blkcnt * blksz;
- ret = ENOMEM;
- if (sndbuf_remalloc(bs, blkcnt, blksz))
+ ret = sndbuf_remalloc(bs, blkcnt, blksz);
+ if (ret)
goto out;
- ret = 0;
/* adjust for different hw format/speed */
irqhz = (sndbuf_getbps(bs) * sndbuf_getspd(bs)) / sndbuf_getblksz(bs);
@@ -1127,6 +1123,14 @@ chn_buildfeeder(struct pcm_channel *c)
tmp[1] = 0;
hwfmt = chn_fmtchain(c, tmp);
} else {
+#if 0
+ u_int32_t *x = chn_getcaps(c)->fmtlist;
+ printf("acceptable formats for %s:\n", c->name);
+ while (*x) {
+ printf("[%8x] ", *x);
+ x++;
+ }
+#endif
hwfmt = chn_fmtchain(c, chn_getcaps(c)->fmtlist);
}
}
diff --git a/sys/dev/sound/pcm/feeder.c b/sys/dev/sound/pcm/feeder.c
index 1848639..424da4d 100644
--- a/sys/dev/sound/pcm/feeder.c
+++ b/sys/dev/sound/pcm/feeder.c
@@ -137,7 +137,7 @@ feeder_create(struct feeder_class *fc, struct pcm_feederdesc *desc)
struct pcm_feeder *f;
int err;
- f = (struct pcm_feeder *)kobj_create((kobj_class_t)fc, M_FEEDER, M_WAITOK | M_ZERO);
+ f = (struct pcm_feeder *)kobj_create((kobj_class_t)fc, M_FEEDER, M_NOWAIT | M_ZERO);
if (f == NULL)
return NULL;
diff --git a/sys/dev/sound/pcm/feeder_fmt.c b/sys/dev/sound/pcm/feeder_fmt.c
index 059d5b7..b4fa4f3 100644
--- a/sys/dev/sound/pcm/feeder_fmt.c
+++ b/sys/dev/sound/pcm/feeder_fmt.c
@@ -209,7 +209,7 @@ FEEDER_DECLARE(feeder_8to16le, 0, NULL);
static int
feed_16to8_init(struct pcm_feeder *f)
{
- f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
+ f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT | M_ZERO);
return (f->data)? 0 : ENOMEM;
}
@@ -318,7 +318,7 @@ FEEDER_DECLARE(feeder_monotostereo16, 0, NULL);
static int
feed_stereotomono8_init(struct pcm_feeder *f)
{
- f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
+ f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT | M_ZERO);
return (f->data)? 0 : ENOMEM;
}
@@ -363,7 +363,7 @@ FEEDER_DECLARE(feeder_stereotomono8, 1, NULL);
static int
feed_stereotomono16_init(struct pcm_feeder *f)
{
- f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_WAITOK | M_ZERO);
+ f->data = malloc(FEEDBUFSZ, M_FMTFEEDER, M_NOWAIT | M_ZERO);
return (f->data)? 0 : ENOMEM;
}
diff --git a/sys/dev/sound/pcm/feeder_rate.c b/sys/dev/sound/pcm/feeder_rate.c
index 0cd8a6b..fca795c 100644
--- a/sys/dev/sound/pcm/feeder_rate.c
+++ b/sys/dev/sound/pcm/feeder_rate.c
@@ -92,10 +92,10 @@ feed_rate_init(struct pcm_feeder *f)
{
struct feed_rate_info *info;
- info = malloc(sizeof(*info), M_RATEFEEDER, M_WAITOK | M_ZERO);
+ info = malloc(sizeof(*info), M_RATEFEEDER, M_NOWAIT | M_ZERO);
if (info == NULL)
return ENOMEM;
- info->buffer = malloc(FEEDBUFSZ, M_RATEFEEDER, M_WAITOK | M_ZERO);
+ info->buffer = malloc(FEEDBUFSZ, M_RATEFEEDER, M_NOWAIT | M_ZERO);
if (info->buffer == NULL) {
free(info, M_RATEFEEDER);
return ENOMEM;
diff --git a/sys/dev/sound/pcm/sndstat.c b/sys/dev/sound/pcm/sndstat.c
index bd9cb32..bdaff2b 100644
--- a/sys/dev/sound/pcm/sndstat.c
+++ b/sys/dev/sound/pcm/sndstat.c
@@ -261,9 +261,9 @@ sndstat_unregister(device_t dev)
SLIST_FOREACH(ent, &sndstat_devlist, link) {
if (ent->dev == dev) {
SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link);
- free(ent, M_DEVBUF);
mtx_unlock(&sndstat_lock);
splx(s);
+ free(ent, M_DEVBUF);
return 0;
}
@@ -285,10 +285,10 @@ sndstat_unregisterfile(char *str)
SLIST_FOREACH(ent, &sndstat_devlist, link) {
if (ent->dev == NULL && ent->str == str) {
SLIST_REMOVE(&sndstat_devlist, ent, sndstat_entry, link);
- free(ent, M_DEVBUF);
sndstat_files--;
mtx_unlock(&sndstat_lock);
splx(s);
+ free(ent, M_DEVBUF);
return 0;
}
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index 3ee33d1..1284947 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -107,7 +107,7 @@ snd_mtxfree(void *m)
#ifdef USING_MUTEX
struct mtx *mtx = m;
- mtx_assert(mtx, MA_OWNED);
+ /* mtx_assert(mtx, MA_OWNED); */
mtx_destroy(mtx);
free(mtx, M_DEVBUF);
#endif
@@ -124,7 +124,7 @@ snd_mtxassert(void *m)
#endif
#endif
}
-
+/*
void
snd_mtxlock(void *m)
{
@@ -144,7 +144,7 @@ snd_mtxunlock(void *m)
mtx_unlock(mtx);
#endif
}
-
+*/
int
snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
{
@@ -375,20 +375,24 @@ pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t c
return NULL;
}
+ snd_mtxlock(d->lock);
ch->num = (*pnum)++;
+ snd_mtxunlock(d->lock);
ch->pid = -1;
ch->parentsnddev = d;
ch->parentchannel = parent;
ch->dev = d->dev;
- snprintf(ch->name, 32, "%s:%s:%d", device_get_nameunit(d->dev), dirs, ch->num);
+ snprintf(ch->name, 32, "%s:%s:%d", device_get_nameunit(ch->dev), dirs, ch->num);
err = chn_init(ch, devinfo, dir);
if (err) {
device_printf(d->dev, "chn_init(%s) failed: err = %d\n", ch->name, err);
kobj_delete(ch->methods, M_DEVBUF);
free(ch, M_DEVBUF);
+ snd_mtxlock(d->lock);
(*pnum)--;
+ snd_mtxunlock(d->lock);
return NULL;
}
@@ -409,13 +413,6 @@ pcm_chn_destroy(struct pcm_channel *ch)
return err;
}
- if (ch->direction == PCMDIR_REC)
- d->reccount--;
- else if (ch->flags & CHN_F_VIRTUAL)
- d->vchancount--;
- else
- d->playcount--;
-
kobj_delete(ch->methods, M_DEVBUF);
free(ch, M_DEVBUF);
@@ -427,6 +424,7 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
{
struct snddev_channel *sce, *tmp, *after;
int unit = device_get_unit(d->dev);
+ int x = -1;
sce = malloc(sizeof(*sce), M_DEVBUF, M_WAITOK | M_ZERO);
if (!sce) {
@@ -434,7 +432,6 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
}
snd_mtxlock(d->lock);
-
sce->channel = ch;
if (SLIST_EMPTY(&d->channels)) {
SLIST_INSERT_HEAD(&d->channels, sce, link);
@@ -445,15 +442,16 @@ pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch, int mkdev)
}
SLIST_INSERT_AFTER(after, sce, link);
}
+ if (mkdev)
+ x = d->devcount++;
+ snd_mtxunlock(d->lock);
if (mkdev) {
- dsp_register(unit, d->devcount++);
+ dsp_register(unit, x);
if (ch->direction == PCMDIR_REC)
dsp_registerrec(unit, ch->num);
}
- snd_mtxunlock(d->lock);
-
return 0;
}
@@ -472,14 +470,21 @@ pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch, int rmdev)
return EINVAL;
gotit:
SLIST_REMOVE(&d->channels, sce, snddev_channel, link);
- free(sce, M_DEVBUF);
-
if (rmdev) {
dsp_unregister(unit, --d->devcount);
if (ch->direction == PCMDIR_REC)
dsp_unregisterrec(unit, ch->num);
}
+
+ if (ch->direction == PCMDIR_REC)
+ d->reccount--;
+ else if (ch->flags & CHN_F_VIRTUAL)
+ d->vchancount--;
+ else
+ d->playcount--;
+
snd_mtxunlock(d->lock);
+ free(sce, M_DEVBUF);
return 0;
}
@@ -500,6 +505,7 @@ pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
err = pcm_chn_add(d, ch, 1);
if (err) {
device_printf(d->dev, "pcm_chn_add(%s) failed, err=%d\n", ch->name, err);
+ snd_mtxunlock(d->lock);
pcm_chn_destroy(ch);
return err;
}
@@ -613,7 +619,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
}
d->lock = snd_mtxcreate(device_get_nameunit(dev), "sound cdev");
- snd_mtxlock(d->lock);
d->flags = 0;
d->dev = dev;
@@ -647,7 +652,6 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
if (numplay == 1)
d->flags |= SD_F_AUTOVCHAN;
- snd_mtxunlock(d->lock);
sndstat_register(dev, d->status, sndstat_prepare_pcm);
return 0;
no:
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 5966e36..5038a28 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -249,9 +249,10 @@ int snd_setup_intr(device_t dev, struct resource *res, int flags,
void *snd_mtxcreate(const char *desc, const char *type);
void snd_mtxfree(void *m);
void snd_mtxassert(void *m);
+/*
void snd_mtxlock(void *m);
void snd_mtxunlock(void *m);
-
+*/
int sysctl_hw_snd_vchans(SYSCTL_HANDLER_ARGS);
typedef int (*sndstat_handler)(struct sbuf *s, device_t dev, int verbose);
@@ -280,6 +281,9 @@ int sndstat_busy(void);
#define DV_F_DEV_MASK 0x0000ff00 /* force device type/class */
#define DV_F_DEV_SHIFT 8 /* force device type/class */
+#define snd_mtxlock(m) mtx_lock(m)
+#define snd_mtxunlock(m) mtx_unlock(m)
+
#endif /* _KERNEL */
#endif /* _OS_H_ */
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index 3f754a7..8da3c3e 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -237,15 +237,8 @@ vchan_create(struct pcm_channel *parent)
struct pcm_channel *child;
int err, first;
- CHN_LOCK(parent);
- if (!(parent->flags & CHN_F_BUSY)) {
- CHN_UNLOCK(parent);
- return EBUSY;
- }
-
pce = malloc(sizeof(*pce), M_DEVBUF, M_WAITOK | M_ZERO);
if (!pce) {
- CHN_UNLOCK(parent);
return ENOMEM;
}
@@ -253,10 +246,15 @@ vchan_create(struct pcm_channel *parent)
child = pcm_chn_create(d, parent, &vchan_class, PCMDIR_VIRTUAL, parent);
if (!child) {
free(pce, M_DEVBUF);
- CHN_UNLOCK(parent);
return ENODEV;
}
+ CHN_LOCK(parent);
+ if (!(parent->flags & CHN_F_BUSY)) {
+ CHN_UNLOCK(parent);
+ return EBUSY;
+ }
+
first = SLIST_EMPTY(&parent->children);
/* add us to our parent channel's children */
pce->channel = child;
@@ -270,7 +268,7 @@ vchan_create(struct pcm_channel *parent)
free(pce, M_DEVBUF);
}
- /* XXX gross ugly hack, kill murder death */
+ /* XXX gross ugly hack, murder death kill */
if (first && !err) {
err = chn_reset(parent, AFMT_STEREO | AFMT_S16_LE);
if (err)
OpenPOWER on IntegriCloud