From bf28cfba58b1a7895383d4ec68d72573fb5cd2a6 Mon Sep 17 00:00:00 2001 From: cg Date: Wed, 29 Aug 2001 02:49:54 +0000 Subject: add some extra diagnostic info to sndstat output. --- sys/dev/sound/pcm/channel.c | 30 +++++++++++++++++++----------- sys/dev/sound/pcm/channel.h | 1 + sys/dev/sound/pcm/sound.c | 28 +++++++++++++++++++++------- 3 files changed, 41 insertions(+), 18 deletions(-) (limited to 'sys/dev/sound/pcm') diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index 93d4593..59f5660f 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -188,6 +188,8 @@ chn_wrfeed(struct pcm_channel *c) }) amt = sndbuf_getfree(b); + if (sndbuf_getready(bs) < amt) + c->xruns++; ret = (amt > 0)? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC; if (ret == 0 && sndbuf_getfree(b) < amt) chn_wakeup(c); @@ -216,7 +218,7 @@ chn_wrintr(struct pcm_channel *c) } /* - * user write routine - uiomove data into secondary bufhard, trigger if necessary + * user write routine - uiomove data into secondary buffer, trigger if necessary * if blocking, sleep, rinse and repeat. * * called externally, so must handle locking @@ -293,7 +295,7 @@ chn_rddump(struct pcm_channel *c, unsigned int cnt) } /* - * Feed new data from the read bufhard. Can be called in the bottom half. + * Feed new data from the read buffer. Can be called in the bottom half. * Hence must be called at spltty. */ int @@ -301,7 +303,7 @@ chn_rdfeed(struct pcm_channel *c) { struct snd_dbuf *b = c->bufhard; struct snd_dbuf *bs = c->bufsoft; - int ret; + unsigned int ret, amt; CHN_LOCKASSERT(c); DEB( @@ -310,10 +312,16 @@ chn_rdfeed(struct pcm_channel *c) sndbuf_dump(bs, "bs", 0x02); }) - ret = sndbuf_feed(b, bs, c, c->feeder, sndbuf_getblksz(b)); + amt = sndbuf_getready(b); + if (sndbuf_getfree(bs) < amt) + c->xruns++; + ret = (amt > 0)? sndbuf_feed(b, bs, c, c->feeder, amt) : 0; - if (ret == 0) - chn_wakeup(c); + amt -= sndbuf_getready(b); + if (amt > 0) + chn_rddump(c, amt); + + chn_wakeup(c); return ret; } @@ -340,18 +348,15 @@ chn_rdupdate(struct pcm_channel *c) static void chn_rdintr(struct pcm_channel *c) { - struct snd_dbuf *b = c->bufhard; int ret; CHN_LOCKASSERT(c); - /* tell the driver to update the primary bufhard if non-dma */ + /* tell the driver to update the primary buffer if non-dma */ chn_trigger(c, PCMTRIG_EMLDMARD); /* update pointers in primary bufhard */ chn_dmaupdate(c); /* ...and feed from primary to secondary */ ret = chn_rdfeed(c); - if (ret) - chn_rddump(c, sndbuf_getblksz(b)); } /* @@ -406,6 +411,7 @@ void chn_intr(struct pcm_channel *c) { CHN_LOCK(c); + c->interrupts++; if (c->direction == PCMDIR_PLAY) chn_wrintr(c); else @@ -603,6 +609,8 @@ chn_reset(struct pcm_channel *c, u_int32_t fmt) CHN_LOCKASSERT(c); c->flags &= CHN_F_RESET; + c->interrupts = 0; + c->xruns = 0; CHANNEL_RESET(c->methods, c->devinfo); if (fmt) { hwspd = DSP_DEFAULT_SPEED; @@ -633,7 +641,7 @@ chn_init(struct pcm_channel *c, void *devinfo, int dir) chn_lockinit(c); CHN_LOCK(c); - /* Initialize the hardware and DMA bufhard first. */ + c->feeder = NULL; fc = feeder_getclass(NULL); if (fc == NULL) diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index 9095c1b..8e2454f 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -54,6 +54,7 @@ struct pcm_channel { u_int32_t blocks; int direction; + unsigned int interrupts, xruns; struct snd_dbuf *bufhard, *bufsoft; struct snddev_info *parentsnddev; struct pcm_channel *parentchannel; diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c index 08da0a4..4ea2b58 100644 --- a/sys/dev/sound/pcm/sound.c +++ b/sys/dev/sound/pcm/sound.c @@ -633,6 +633,7 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) struct snddev_channel *sce; struct pcm_channel *c; struct pcm_feeder *f; + char *fsep; int pc, rc, vc; if (verbose < 1) @@ -667,25 +668,38 @@ sndstat_prepare_pcm(struct sbuf *s, device_t dev, int verbose) goto skipverbose; SLIST_FOREACH(sce, &d->channels, link) { c = sce->channel; - sbuf_printf(s, "\n\t%s[%s]: speed %d, format %08x, flags %08x", - c->parentchannel? c->parentchannel->name : "", - c->name, c->speed, c->format, c->flags); + sbuf_printf(s, "\n\t"); + + sbuf_printf(s, "%s[%s]: ", c->parentchannel? c->parentchannel->name : "", c->name); + sbuf_printf(s, "speed %d, format %08x, flags %08x", c->speed, c->format, c->flags); if (c->pid != -1) sbuf_printf(s, ", pid %d", c->pid); sbuf_printf(s, "\n\t"); + if (c->pid != -1 && c->bufhard != NULL && c->bufsoft != NULL) { + sbuf_printf(s, "interrupts %d, ", c->interrupts); + if (c->direction == PCMDIR_REC) + sbuf_printf(s, "overruns %d, hfree %d, sfree %d", + c->xruns, sndbuf_getfree(c->bufhard), sndbuf_getfree(c->bufsoft)); + else + sbuf_printf(s, "underruns %d, hready %d, sready %d", + c->xruns, sndbuf_getready(c->bufhard), sndbuf_getready(c->bufsoft)); + sbuf_printf(s, "\n\t"); + } + fsep = (c->direction == PCMDIR_REC)? " -> " : " <- "; + sbuf_printf(s, "[hardware]%s", fsep); f = c->feeder; while (f) { sbuf_printf(s, "%s", f->class->name); if (f->desc->type == FEEDER_FMT) - sbuf_printf(s, "(%08x <- %08x)", f->desc->out, f->desc->in); + sbuf_printf(s, "(%08x%s%08x)", f->desc->out, fsep, f->desc->in); if (f->desc->type == FEEDER_RATE) - sbuf_printf(s, "(%d <- %d)", FEEDER_GET(f, FEEDRATE_DST), FEEDER_GET(f, FEEDRATE_SRC)); + sbuf_printf(s, "(%d%s%d)", FEEDER_GET(f, FEEDRATE_DST), fsep, FEEDER_GET(f, FEEDRATE_SRC)); if (f->desc->type == FEEDER_ROOT || f->desc->type == FEEDER_MIXER) sbuf_printf(s, "(%08x)", f->desc->out); - if (f->source) - sbuf_printf(s, " <- "); + sbuf_printf(s, "%s", fsep); f = f->source; } + sbuf_printf(s, "[userland]"); } skipverbose: } else -- cgit v1.1