diff options
Diffstat (limited to 'sys/dev/sound/pcm/buffer.c')
-rw-r--r-- | sys/dev/sound/pcm/buffer.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/sys/dev/sound/pcm/buffer.c b/sys/dev/sound/pcm/buffer.c index 0021c25..46759cb 100644 --- a/sys/dev/sound/pcm/buffer.c +++ b/sys/dev/sound/pcm/buffer.c @@ -31,13 +31,14 @@ SND_DECLARE_FILE("$FreeBSD$"); struct snd_dbuf * -sndbuf_create(device_t dev, char *drv, char *desc) +sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel) { struct snd_dbuf *b; b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO); snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc); b->dev = dev; + b->channel = channel; return b; } @@ -113,27 +114,38 @@ sndbuf_free(struct snd_dbuf *b) int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz) { - u_int8_t *tmpbuf; + u_int8_t *tmpbuf, *f2; + + chn_lock(b->channel); if (b->maxsize == 0) - return 0; + goto out; if (blkcnt == 0) blkcnt = b->blkcnt; if (blksz == 0) blksz = b->blksz; - if (blkcnt < 2 || blksz < 16 || (blkcnt * blksz > b->maxsize)) + if (blkcnt < 2 || blksz < 16 || (blkcnt * blksz > b->maxsize)) { + chn_unlock(b->channel); return EINVAL; + } if (blkcnt == b->blkcnt && blksz == b->blksz) - return 0; - b->blkcnt = blkcnt; - b->blksz = blksz; - b->bufsize = blkcnt * blksz; + goto out; - tmpbuf = malloc(b->bufsize, M_DEVBUF, M_NOWAIT); + chn_unlock(b->channel); + tmpbuf = malloc(blkcnt * blksz, M_DEVBUF, M_WAITOK); if (tmpbuf == NULL) return ENOMEM; - free(b->tmpbuf, M_DEVBUF); + chn_lock(b->channel); + b->blkcnt = blkcnt; + b->blksz = blksz; + b->bufsize = blkcnt * blksz; + f2 = b->tmpbuf; b->tmpbuf = tmpbuf; sndbuf_reset(b); + chn_unlock(b->channel); + free(f2, M_DEVBUF); + return 0; +out: + chn_unlock(b->channel); return 0; } @@ -142,21 +154,27 @@ sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz) { u_int8_t *buf, *tmpbuf, *f1, *f2; unsigned int bufsize; + int ret; if (blkcnt < 2 || blksz < 16) return EINVAL; bufsize = blksz * blkcnt; - buf = malloc(bufsize, M_DEVBUF, M_NOWAIT); - if (buf == NULL) - return ENOMEM; + chn_unlock(b->channel); + buf = malloc(bufsize, M_DEVBUF, M_WAITOK); + if (buf == NULL) { + ret = ENOMEM; + goto out; + } - tmpbuf = malloc(bufsize, M_DEVBUF, M_NOWAIT); + tmpbuf = malloc(bufsize, M_DEVBUF, M_WAITOK); if (tmpbuf == NULL) { free(buf, M_DEVBUF); - return ENOMEM; + ret = ENOMEM; + goto out; } + chn_lock(b->channel); b->blkcnt = blkcnt; b->blksz = blksz; @@ -167,13 +185,18 @@ sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz) b->buf = buf; b->tmpbuf = tmpbuf; + sndbuf_reset(b); + + chn_unlock(b->channel); if (f1) free(f1, M_DEVBUF); if (f2) free(f2, M_DEVBUF); - sndbuf_reset(b); - return 0; + ret = 0; +out: + chn_lock(b->channel); + return ret; } void |