From 29ca956710b112d79ad24157caac5c1597949208 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 20 Nov 2014 10:58:14 -0800 Subject: [PATCH] sound/pcm - Attempt to fix 'play interrupt timeout, channel dead' error * Fix the timeout calculation to properly calculate the buffering timeout. * Adjusted code taken from bug 2067 submission. PR: 2067 --- sys/dev/sound/pcm/channel.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index d43cbcbe2b..31533fa47e 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -342,10 +342,24 @@ chn_write(struct pcm_channel *c, struct uio *buf, int ioflags) if (nbio) ret = EWOULDBLOCK; else { - timeout = (hz * sndbuf_getblksz(bs)) / (sndbuf_getspd(bs) * sndbuf_getbps(bs)); - if (timeout < 1) - timeout = 1; - timeout = 1; + int denom; + + /* + * Ceiling of calculation, minimum 2 ticks. + * 1 tick can timeout instantly if the next + * tick interval occurs immediately. + * + * Also ensure the calculation is +1 to + * handle other edge cases. e.g. if the + * fractional calculation is 3.9 ticks the + * result is 4 + 1 = 5, because 4 can actually + * be anywhere from 3 to 4 ticks. + */ + denom = sndbuf_getspd(bs) * sndbuf_getbps(bs); + timeout = (hz * sndbuf_getblksz(bs) + + denom - 1) / denom + 1; + if (timeout < 2) + timeout = 2; ret = chn_sleep(c, "pcmwr", timeout); if (ret == EWOULDBLOCK) { count -= timeout; -- 2.41.0