diff options
author | ariff <ariff@FreeBSD.org> | 2007-06-11 00:49:46 +0000 |
---|---|---|
committer | ariff <ariff@FreeBSD.org> | 2007-06-11 00:49:46 +0000 |
commit | fafa308f2ba94d67208e15f425b8034c98a4eddf (patch) | |
tree | 795c3b5265f3bcbcabb27dd644db79e60a617e78 | |
parent | a3226c8185423f9e8977c68b703d0f6f9676c357 (diff) | |
download | FreeBSD-src-fafa308f2ba94d67208e15f425b8034c98a4eddf.zip FreeBSD-src-fafa308f2ba94d67208e15f425b8034c98a4eddf.tar.gz |
Filter/compress the amount of channel trigger. This should reduce
much of lock/unlock contentions within the interrupt handler. Most
of these drivers only need PCMTRIG_START or STOP (ABORT).
Discussed with: scottl
29 files changed, 75 insertions, 31 deletions
diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c index 89722a8..27d88f1 100644 --- a/sys/dev/sound/isa/ad1816.c +++ b/sys/dev/sound/isa/ad1816.c @@ -411,7 +411,7 @@ ad1816chan_trigger(kobj_t obj, void *data, int go) struct ad1816_info *ad1816 = ch->parent; int wr, reg; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; sndbuf_dma(ch->buffer, go); diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c index 53a8d8d..e6709ec 100644 --- a/sys/dev/sound/isa/ess.c +++ b/sys/dev/sound/isa/ess.c @@ -611,7 +611,7 @@ esschan_trigger(kobj_t obj, void *data, int go) { struct ess_chinfo *ch = data; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; switch (go) { diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c index ae14994..297bc87 100644 --- a/sys/dev/sound/isa/mss.c +++ b/sys/dev/sound/isa/mss.c @@ -1201,7 +1201,7 @@ msschan_trigger(kobj_t obj, void *data, int go) struct mss_chinfo *ch = data; struct mss_info *mss = ch->parent; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; sndbuf_dma(ch->buffer, go); diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c index 7e967bf..2cdaf49 100644 --- a/sys/dev/sound/isa/sb16.c +++ b/sys/dev/sound/isa/sb16.c @@ -724,7 +724,7 @@ sb16chan_trigger(kobj_t obj, void *data, int go) struct sb_chinfo *ch = data; struct sb_info *sb = ch->parent; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (go == PCMTRIG_START) diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c index f4cc837..9de879c 100644 --- a/sys/dev/sound/isa/sb8.c +++ b/sys/dev/sound/isa/sb8.c @@ -637,7 +637,7 @@ sbchan_trigger(kobj_t obj, void *data, int go) { struct sb_chinfo *ch = data; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; sndbuf_dma(ch->buffer, go); diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 9ff6283..30513c8 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -391,14 +391,20 @@ alspchan_trigger(kobj_t obj, void *data, int go) struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; + if (!PCMTRIG_COMMON(go)) + return 0; + snd_mtxlock(sc->lock); switch(go) { case PCMTRIG_START: als_playback_start(ch); break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: als_playback_stop(ch); break; + default: + break; } snd_mtxunlock(sc->lock); return 0; @@ -489,6 +495,7 @@ alsrchan_trigger(kobj_t obj, void *data, int go) case PCMTRIG_START: als_capture_start(ch); break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: als_capture_stop(ch); break; diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c index 325e506..1b325ef 100644 --- a/sys/dev/sound/pci/atiixp.c +++ b/sys/dev/sound/pci/atiixp.c @@ -712,6 +712,9 @@ atiixp_chan_trigger(kobj_t obj, void *data, int go) uint32_t value; int pollticks; + if (!PCMTRIG_COMMON(go)) + return (0); + atiixp_lock(sc); switch (go) { diff --git a/sys/dev/sound/pci/aureal.c b/sys/dev/sound/pci/aureal.c index 4417cf1..e714fe6 100644 --- a/sys/dev/sound/pci/aureal.c +++ b/sys/dev/sound/pci/aureal.c @@ -339,12 +339,12 @@ auchan_trigger(kobj_t obj, void *data, int go) struct au_chinfo *ch = data; struct au_info *au = ch->parent; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (ch->dir == PCMDIR_PLAY) { au_setadb(au, 0x11, (go)? 1 : 0); - if (!go) { + if (go != PCMTRIG_START) { au_wr(au, 0, 0xf800, 0, 4); au_wr(au, 0, 0xf804, 0, 4); au_delroute(au, 0x58); diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index ce1db2e..c52bbd6 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -475,12 +475,16 @@ cmichan_trigger(kobj_t obj, void *data, int go) struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; + if (!PCMTRIG_COMMON(go)) + return 0; + snd_mtxlock(sc->lock); if (ch->dir == PCMDIR_PLAY) { switch(go) { case PCMTRIG_START: cmi_ch0_start(sc, ch); break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: cmi_ch0_stop(sc, ch); break; @@ -490,6 +494,7 @@ cmichan_trigger(kobj_t obj, void *data, int go) case PCMTRIG_START: cmi_ch1_start(sc, ch); break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: cmi_ch1_stop(sc, ch); break; diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c index c7b70de..769603a 100644 --- a/sys/dev/sound/pci/cs4281.c +++ b/sys/dev/sound/pci/cs4281.c @@ -425,6 +425,7 @@ cs4281chan_trigger(kobj_t obj, void *data, int go) adcdac_prog(ch); adcdac_go(ch, 1); break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: adcdac_go(ch, 0); break; diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c index 786ec47..21c261f 100644 --- a/sys/dev/sound/pci/csapcm.c +++ b/sys/dev/sound/pci/csapcm.c @@ -569,7 +569,7 @@ csachan_trigger(kobj_t obj, void *data, int go) struct csa_chinfo *ch = data; struct csa_info *csa = ch->parent; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (go == PCMTRIG_START) { diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c index 15aff42..958b587 100644 --- a/sys/dev/sound/pci/ds1.c +++ b/sys/dev/sound/pci/ds1.c @@ -545,7 +545,7 @@ ds1pchan_trigger(kobj_t obj, void *data, int go) struct sc_info *sc = ch->parent; int stereo; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; stereo = (ch->fmt & AFMT_STEREO)? 1 : 0; if (go == PCMTRIG_START) { @@ -673,7 +673,7 @@ ds1rchan_trigger(kobj_t obj, void *data, int go) struct sc_info *sc = ch->parent; u_int32_t x; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (go == PCMTRIG_START) { ch->run = 1; diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c index 9280f67..120c1b8 100644 --- a/sys/dev/sound/pci/emu10k1.c +++ b/sys/dev/sound/pci/emu10k1.c @@ -795,7 +795,7 @@ emupchan_trigger(kobj_t obj, void *data, int go) struct sc_pchinfo *ch = data; struct sc_info *sc = ch->parent; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; snd_mtxlock(sc->lock); @@ -958,6 +958,9 @@ emurchan_trigger(kobj_t obj, void *data, int go) struct sc_info *sc = ch->parent; u_int32_t val, sz; + if (!PCMTRIG_COMMON(go)) + return 0; + switch(sc->bufsz) { case 4096: sz = ADCBS_BUFSIZE_4096; diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c index d3b392c..4d63c57 100644 --- a/sys/dev/sound/pci/emu10kx-pcm.c +++ b/sys/dev/sound/pci/emu10kx-pcm.c @@ -513,8 +513,9 @@ emupchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) struct emu_pcm_pchinfo *ch = c_devinfo; struct emu_pcm_info *sc = ch->pcm; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return (0); + snd_mtxlock(sc->lock); /* XXX can we trigger on parallel threads ? */ if (go == PCMTRIG_START) { emu_vsetup(ch->master, ch->fmt, ch->spd); @@ -654,6 +655,9 @@ emurchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) struct emu_pcm_info *sc = ch->pcm; uint32_t val, sz; + if (!PCMTRIG_COMMON(go)) + return (0); + switch (sc->bufsz) { case 4096: sz = ADCBS_BUFSIZE_4096; @@ -806,6 +810,9 @@ emufxrchan_trigger(kobj_t obj __unused, void *c_devinfo, int go) struct emu_pcm_info *sc = ch->pcm; uint32_t sz; + if (!PCMTRIG_COMMON(go)) + return (0); + switch (sc->bufsz) { case 4096: sz = ADCBS_BUFSIZE_4096; diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c index e7f1655..0daaad8 100644 --- a/sys/dev/sound/pci/es137x.c +++ b/sys/dev/sound/pci/es137x.c @@ -727,8 +727,8 @@ eschan_trigger(kobj_t obj, void *data, int go) struct es_info *es = ch->parent; uint32_t cnt, b = 0; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) - return (0); + if (!PCMTRIG_COMMON(go)) + return 0; ES_LOCK(es); cnt = (ch->blksz / sndbuf_getbps(ch->buffer)) - 1; diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c index f064524..de6de1d 100644 --- a/sys/dev/sound/pci/fm801.c +++ b/sys/dev/sound/pci/fm801.c @@ -443,9 +443,8 @@ fm801ch_trigger(kobj_t obj, void *data, int go) DPRINT("fm801ch_trigger go %d , ", go); - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) { + if (!PCMTRIG_COMMON(go)) return 0; - } if (ch->dir == PCMDIR_PLAY) { if (go == PCMTRIG_START) { diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c index b71a164..69cff37 100644 --- a/sys/dev/sound/pci/hda/hdac.c +++ b/sys/dev/sound/pci/hda/hdac.c @@ -3133,6 +3133,9 @@ hdac_channel_trigger(kobj_t obj, void *data, int go) struct hdac_chan *ch = data; struct hdac_softc *sc = ch->devinfo->codec->sc; + if (!PCMTRIG_COMMON(go)) + return (0); + hdac_lock(sc); switch (go) { case PCMTRIG_START: diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 95ca987..6a191d2 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -522,13 +522,15 @@ ichchan_trigger(kobj_t obj, void *data, int go) ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1); ICH_UNLOCK(sc); break; - + case PCMTRIG_STOP: case PCMTRIG_ABORT: ICH_LOCK(sc); ich_resetchan(sc, ch->num); ICH_UNLOCK(sc); ch->run = 0; break; + default: + break; } return (0); } diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c index 5bc7848..aaceefd 100644 --- a/sys/dev/sound/pci/maestro3.c +++ b/sys/dev/sound/pci/maestro3.c @@ -573,6 +573,9 @@ m3_pchan_trigger(kobj_t kobj, void *chdata, int go) struct sc_info *sc = ch->parent; int ret; + if (!PCMTRIG_COMMON(go)) + return (0); + M3_LOCK(sc); ret = m3_pchan_trigger_locked(kobj, chdata, go); M3_UNLOCK(sc); @@ -916,6 +919,9 @@ m3_rchan_trigger(kobj_t kobj, void *chdata, int go) struct sc_info *sc = ch->parent; int ret; + if (!PCMTRIG_COMMON(go)) + return (0); + M3_LOCK(sc); ret = m3_rchan_trigger_locked(kobj, chdata, go); M3_UNLOCK(sc); diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c index 5ef43d4..6148968 100644 --- a/sys/dev/sound/pci/neomagic.c +++ b/sys/dev/sound/pci/neomagic.c @@ -406,7 +406,7 @@ nmchan_trigger(kobj_t obj, void *data, int go) struct sc_info *sc = ch->parent; int ssz; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c index 112dcb2..5b4960d 100644 --- a/sys/dev/sound/pci/solo.c +++ b/sys/dev/sound/pci/solo.c @@ -585,10 +585,11 @@ esschan_trigger(kobj_t obj, void *data, int go) struct ess_chinfo *ch = data; struct ess_info *sc = ch->parent; - DEB(printf("esschan_trigger: %d\n",go)); - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; + DEB(printf("esschan_trigger: %d\n",go)); + ess_lock(sc); switch (go) { case PCMTRIG_START: diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c index 50989ee..a1012d2 100644 --- a/sys/dev/sound/pci/t4dwave.c +++ b/sys/dev/sound/pci/t4dwave.c @@ -533,7 +533,7 @@ trpchan_trigger(kobj_t obj, void *data, int go) { struct tr_chinfo *ch = data; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (go == PCMTRIG_START) { @@ -658,7 +658,7 @@ trrchan_trigger(kobj_t obj, void *data, int go) struct tr_info *tr = ch->parent; u_int32_t i; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; if (go == PCMTRIG_START) { diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index a8b9057..c351293 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -889,6 +889,9 @@ via8233chan_trigger(kobj_t obj, void* data, int go) struct via_info *via = ch->parent; int pollticks; + if (!PCMTRIG_COMMON(go)) + return (0); + snd_mtxlock(via->lock); switch(go) { case PCMTRIG_START: diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 4810122..45e2b4d 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -342,7 +342,7 @@ viachan_trigger(kobj_t obj, void *data, int go) struct via_dma_op *ado; bus_addr_t sgd_addr = ch->sgd_addr; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; ado = ch->sgd_table; diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c index 36a8a16..3018395b 100644 --- a/sys/dev/sound/pci/vibes.c +++ b/sys/dev/sound/pci/vibes.c @@ -336,6 +336,7 @@ svrchan_trigger(kobj_t obj, void *data, int go) sv_indirect_set(sc, SV_REG_ENABLE, enable); ch->dma_active = 1; break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: enable = sv_indirect_get(sc, SV_REG_ENABLE) & ~SV_RECORD_ENABLE; sv_indirect_set(sc, SV_REG_ENABLE, enable); @@ -412,6 +413,7 @@ svpchan_trigger(kobj_t obj, void *data, int go) sv_indirect_set(sc, SV_REG_ENABLE, enable); ch->dma_active = 1; break; + case PCMTRIG_STOP: case PCMTRIG_ABORT: enable = sv_indirect_get(sc, SV_REG_ENABLE) & ~SV_PLAY_ENABLE; sv_indirect_set(sc, SV_REG_ENABLE, enable); diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c index c9831ff..c1c472d 100644 --- a/sys/dev/sound/pcm/channel.c +++ b/sys/dev/sound/pcm/channel.c @@ -688,7 +688,6 @@ chn_start(struct pcm_channel *c, int force) (sndbuf_getbps(b) * sndbuf_getspd(b))); } chn_trigger(c, PCMTRIG_START); - return 0; } return 0; @@ -1777,9 +1776,8 @@ chn_trigger(struct pcm_channel *c, int go) if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)) sndbuf_dmabounce(b); #endif - if ((go == PCMTRIG_START || go == PCMTRIG_STOP || - go == PCMTRIG_ABORT) && go == c->trigger) - return 0; + if (PCMTRIG_COMMON(go) && go == c->trigger) + return (0); ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); @@ -1821,7 +1819,7 @@ chn_trigger(struct pcm_channel *c, int go) } } - return ret; + return (ret); } /** diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h index d443a01..42e3921 100644 --- a/sys/dev/sound/pcm/channel.h +++ b/sys/dev/sound/pcm/channel.h @@ -281,6 +281,7 @@ extern int chn_latency; extern int chn_latency_profile; extern int report_soft_formats; +#define PCMDIR_FAKE 0 #define PCMDIR_PLAY 1 #define PCMDIR_PLAY_VIRTUAL 2 #define PCMDIR_REC -1 @@ -292,6 +293,10 @@ extern int report_soft_formats; #define PCMTRIG_STOP 0 #define PCMTRIG_ABORT -1 +#define PCMTRIG_COMMON(x) ((x) == PCMTRIG_START || \ + (x) == PCMTRIG_STOP || \ + (x) == PCMTRIG_ABORT) + #define CHN_F_CLOSING 0x00000004 /* a pending close */ #define CHN_F_ABORTING 0x00000008 /* a pending abort */ #define CHN_F_RUNNING 0x00000010 /* dma is running */ diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c index 28f4a4a..81684d7 100644 --- a/sys/dev/sound/pcm/vchan.c +++ b/sys/dev/sound/pcm/vchan.c @@ -431,8 +431,7 @@ vchan_trigger(kobj_t obj, void *data, int go) struct pcm_channel *c, *p; int otrigger; - if (!(go == PCMTRIG_START || go == PCMTRIG_STOP || - go == PCMTRIG_ABORT) || go == ch->trigger) + if (!PCMTRIG_COMMON(go) || go == ch->trigger) return (0); c = ch->channel; diff --git a/sys/dev/sound/usb/uaudio_pcm.c b/sys/dev/sound/usb/uaudio_pcm.c index e2f9511..5e01e8b 100644 --- a/sys/dev/sound/usb/uaudio_pcm.c +++ b/sys/dev/sound/usb/uaudio_pcm.c @@ -206,7 +206,7 @@ ua_chan_trigger(kobj_t obj, void *data, int go) struct ua_info *ua; struct ua_chinfo *ch = data; - if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) + if (!PCMTRIG_COMMON(go)) return 0; ua = ch->parent; |