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
This commit is contained in:
ariff 2007-06-11 00:49:46 +00:00
parent a3226c8185
commit fafa308f2b
29 changed files with 75 additions and 31 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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:

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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) {

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
/**

View File

@ -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 */

View File

@ -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;

View File

@ -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;