diff options
author | cg <cg@FreeBSD.org> | 1999-11-22 21:16:01 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 1999-11-22 21:16:01 +0000 |
commit | fe6a86187cd648995de5a5be2d7d43f68daa1739 (patch) | |
tree | 96a2b278d11803a015f879044bc4e2f81c0b142e | |
parent | a3b4d655fdd5459bbb71da7fcf76cdb839c2130f (diff) | |
download | FreeBSD-src-fe6a86187cd648995de5a5be2d7d43f68daa1739.zip FreeBSD-src-fe6a86187cd648995de5a5be2d7d43f68daa1739.tar.gz |
fix panic for large writes in non-blocking mode
-rw-r--r-- | sys/dev/sound/pcm/channel.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 7e441a8..146770e 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -273,7 +273,10 @@ chn_write(pcm_channel *c, struct uio *buf) chn_dmaupdate(c); splx(s); if (b->fl < DMA_ALIGN_THRESHOLD) { - if (c->flags & CHN_F_NBIO) break; + if (c->flags & CHN_F_NBIO) { + ret = -1; + break; + } timeout = (buf->uio_resid >= b->dl)? hz : 1; ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout); if (ret == EINTR) chn_abort(c); @@ -283,7 +286,7 @@ chn_write(pcm_channel *c, struct uio *buf) } /* ensure we always have a whole number of samples */ l = min(b->fl, b->bufsize - b->fp) & ~a; - if (l == 0) break; + if (l == 0) continue; w = c->feeder->feed(c->feeder, c, b->buf + b->fp, l, buf); if (w == 0) panic("no feed"); s = spltty(); @@ -300,7 +303,7 @@ chn_write(pcm_channel *c, struct uio *buf) c->smegcnt += l; } c->flags &= ~CHN_F_WRITING; - return ret; + return (ret > 0)? ret : 0; } /* |