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:
parent
a3226c8185
commit
fafa308f2b
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user