diff options
-rw-r--r-- | sys/dev/sound/pci/als4000.c | 15 | ||||
-rw-r--r-- | sys/dev/sound/pci/via8233.c | 44 | ||||
-rw-r--r-- | sys/dev/sound/pci/via82c686.c | 10 |
3 files changed, 47 insertions, 22 deletions
diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c index 5693370..2df70dc 100644 --- a/sys/dev/sound/pci/als4000.c +++ b/sys/dev/sound/pci/als4000.c @@ -271,9 +271,12 @@ static int alschan_getptr(kobj_t obj, void *data) { struct sc_chinfo *ch = data; + struct sc_info *sc = ch->parent; int32_t pos, sz; + snd_mtxlock(sc->lock); pos = als_gcr_rd(ch->parent, ch->gcr_fifo_status) & 0xffff; + snd_mtxunlock(sc->lock); sz = sndbuf_getsize(ch->buffer); return (2 * sz - pos - 1) % sz; } @@ -386,7 +389,9 @@ static int alspchan_trigger(kobj_t obj, void *data, int go) { struct sc_chinfo *ch = data; + struct sc_info *sc = ch->parent; + snd_mtxlock(sc->lock); switch(go) { case PCMTRIG_START: als_playback_start(ch); @@ -395,6 +400,7 @@ alspchan_trigger(kobj_t obj, void *data, int go) als_playback_stop(ch); break; } + snd_mtxunlock(sc->lock); return 0; } @@ -476,7 +482,9 @@ static int alsrchan_trigger(kobj_t obj, void *data, int go) { struct sc_chinfo *ch = data; + struct sc_info *sc = ch->parent; + snd_mtxlock(sc->lock); switch(go) { case PCMTRIG_START: als_capture_start(ch); @@ -485,6 +493,7 @@ alsrchan_trigger(kobj_t obj, void *data, int go) als_capture_stop(ch); break; } + snd_mtxunlock(sc->lock); return 0; } @@ -889,9 +898,11 @@ als_pci_suspend(device_t dev) { struct sc_info *sc = pcm_getdevinfo(dev); + snd_mtxlock(sc->lock); sc->pch.dma_was_active = als_playback_stop(&sc->pch); sc->rch.dma_was_active = als_capture_stop(&sc->rch); als_uninit(sc); + snd_mtxunlock(sc->lock); return 0; } @@ -901,13 +912,16 @@ als_pci_resume(device_t dev) struct sc_info *sc = pcm_getdevinfo(dev); + snd_mtxlock(sc->lock); if (als_init(sc) != 0) { device_printf(dev, "unable to reinitialize the card\n"); + snd_mtxunlock(sc->lock); return ENXIO; } if (mixer_reinit(dev) != 0) { device_printf(dev, "unable to reinitialize the mixer\n"); + snd_mtxunlock(sc->lock); return ENXIO; } @@ -918,6 +932,7 @@ als_pci_resume(device_t dev) if (sc->rch.dma_was_active) { als_capture_start(&sc->rch); } + snd_mtxunlock(sc->lock); return 0; } diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c index d262613..19e3507 100644 --- a/sys/dev/sound/pci/via8233.c +++ b/sys/dev/sound/pci/via8233.c @@ -100,7 +100,7 @@ struct via_info { struct ac97_info *codec; unsigned int bufsz; - int spdif_en, dxs_src; + int dxs_src; struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; struct via_chinfo rch[NWRCHANS]; @@ -127,13 +127,15 @@ sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) { struct via_info *via; device_t dev; - int err, new_en, r; + uint32_t r; + int err, new_en; dev = oidp->oid_arg1; via = pcm_getdevinfo(dev); snd_mtxlock(via->lock); - new_en = via->spdif_en; + r = pci_read_config(dev, VIA_PCI_SPDIF, 1); snd_mtxunlock(via->lock); + new_en = (r & VIA_SPDIF_EN) ? 1 : 0; err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req); if (err || req->newptr == NULL) @@ -141,12 +143,11 @@ sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) if (new_en < 0 || new_en > 1) return EINVAL; - snd_mtxlock(via->lock); - via->spdif_en = new_en; - - r = pci_read_config(dev, VIA_PCI_SPDIF, 1) & ~VIA_SPDIF_EN; if (new_en) r |= VIA_SPDIF_EN; + else + r &= ~VIA_SPDIF_EN; + snd_mtxlock(via->lock); pci_write_config(dev, VIA_PCI_SPDIF, r, 1); snd_mtxunlock(via->lock); @@ -184,13 +185,6 @@ static void via_init_sysctls(device_t dev) { #ifdef SND_DYNSYSCTL - struct via_info *via; - int r; - - via = pcm_getdevinfo(dev); - r = pci_read_config(dev, VIA_PCI_SPDIF, 1); - via->spdif_en = (r & VIA_SPDIF_EN) ? 1 : 0; - SYSCTL_ADD_PROC(snd_sysctl_tree(dev), SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), OID_AUTO, "spdif_enabled", @@ -206,7 +200,7 @@ via_init_sysctls(device_t dev) #endif } -static u_int32_t +static __inline u_int32_t via_rd(struct via_info *via, int regno, int size) { switch (size) { @@ -221,7 +215,7 @@ via_rd(struct via_info *via, int regno, int size) } } -static void +static __inline void via_wr(struct via_info *via, int regno, u_int32_t data, int size) { @@ -347,7 +341,9 @@ via8233wr_setformat(kobj_t obj, void *data, u_int32_t format) f |= WR_FORMAT_STEREO; if (format & AFMT_S16_LE) f |= WR_FORMAT_16BIT; + snd_mtxlock(via->lock); via_wr(via, VIA_WR0_FORMAT, f, 4); + snd_mtxunlock(via->lock); return 0; } @@ -360,6 +356,7 @@ via8233dxs_setformat(kobj_t obj, void *data, u_int32_t format) u_int32_t r, v; r = ch->rbase + VIA8233_RP_DXS_RATEFMT; + snd_mtxlock(via->lock); v = via_rd(via, r, 4); v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); @@ -368,6 +365,7 @@ via8233dxs_setformat(kobj_t obj, void *data, u_int32_t format) if (format & AFMT_16BIT) v |= VIA8233_DXS_RATEFMT_16BIT; via_wr(via, r, v, 4); + snd_mtxunlock(via->lock); return 0; } @@ -389,8 +387,10 @@ via8233msgd_setformat(kobj_t obj, void *data, u_int32_t format) s |= SLOT3(1) | SLOT4(1); } + snd_mtxlock(via->lock); via_wr(via, VIA_MC_SLOT_SELECT, s, 4); via_wr(via, VIA_MC_SGD_FORMAT, v, 1); + snd_mtxunlock(via->lock); return 0; } @@ -418,12 +418,14 @@ via8233dxs_setspeed(kobj_t obj, void *data, u_int32_t speed) u_int32_t r, v; r = ch->rbase + VIA8233_RP_DXS_RATEFMT; + snd_mtxlock(via->lock); v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); via_wr(via, r, v, 4); + snd_mtxunlock(via->lock); return speed; } @@ -505,7 +507,9 @@ via8233chan_getptr(kobj_t obj, void *data) u_int32_t v, index, count; int ptr; + snd_mtxlock(via->lock); v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); + snd_mtxunlock(via->lock); index = v >> 24; /* Last completed buffer */ count = v & 0x00ffffff; /* Bytes remaining */ ptr = (index + 1) * ch->blksz - count; @@ -540,13 +544,13 @@ via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_info *via = devinfo; struct via_chinfo *ch = &via->rch[c->num]; - snd_mtxlock(via->lock); ch->parent = via; ch->channel = c; ch->buffer = b; ch->dir = dir; ch->rbase = VIA_WR_BASE(c->num); + snd_mtxlock(via->lock); via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); snd_mtxunlock(via->lock); @@ -568,7 +572,6 @@ via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_info *via = devinfo; struct via_chinfo *ch = &via->pch[c->num]; - snd_mtxlock(via->lock); ch->parent = via; ch->channel = c; ch->buffer = b; @@ -579,6 +582,7 @@ via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, * channels. We therefore want to align first DXS channel to * DXS3. */ + snd_mtxlock(via->lock); ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); via->n_dxs_registered++; snd_mtxunlock(via->lock); @@ -601,13 +605,11 @@ via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct via_info *via = devinfo; struct via_chinfo *ch = &via->pch[c->num]; - snd_mtxlock(via->lock); ch->parent = via; ch->channel = c; ch->buffer = b; ch->dir = dir; ch->rbase = VIA_MC_SGD_STATUS; - snd_mtxunlock(via->lock); if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) return NULL; @@ -642,6 +644,7 @@ via8233chan_trigger(kobj_t obj, void* data, int go) struct via_chinfo *ch = data; struct via_info *via = ch->parent; + snd_mtxlock(via->lock); switch(go) { case PCMTRIG_START: via_buildsgdt(ch); @@ -658,6 +661,7 @@ via8233chan_trigger(kobj_t obj, void* data, int go) via8233chan_reset(via, ch); break; } + snd_mtxunlock(via->lock); return 0; } diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 0be2fd0..d0a910c 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -99,7 +99,7 @@ static u_int32_t via_fmt[] = { static struct pcmchan_caps via_vracaps = {4000, 48000, via_fmt, 0}; static struct pcmchan_caps via_caps = {48000, 48000, via_fmt, 0}; -static u_int32_t +static __inline u_int32_t via_rd(struct via_info *via, int regno, int size) { @@ -116,7 +116,7 @@ via_rd(struct via_info *via, int regno, int size) } -static void +static __inline void via_wr(struct via_info *via, int regno, u_int32_t data, int size) { @@ -290,10 +290,12 @@ viachan_setformat(kobj_t obj, void *data, u_int32_t format) mode_set |= VIA_RPMODE_16BIT; DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format)); + snd_mtxlock(via->lock); mode = via_rd(via, ch->mode, 1); mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO); mode |= mode_set; via_wr(via, ch->mode, mode, 1); + snd_mtxunlock(via->lock); return 0; } @@ -346,12 +348,14 @@ viachan_trigger(kobj_t obj, void *data, int go) ado = ch->sgd_table; DEB(printf("ado located at va=%p pa=%x\n", ado, sgd_addr)); + snd_mtxlock(via->lock); if (go == PCMTRIG_START) { via_buildsgdt(ch); via_wr(via, ch->base, sgd_addr, 4); via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1); } else via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1); + snd_mtxunlock(via->lock); DEB(printf("viachan_trigger: go=%d\n", go)); return 0; @@ -367,11 +371,13 @@ viachan_getptr(kobj_t obj, void *data) int ptr, base, base1, len, seg; ado = ch->sgd_table; + snd_mtxlock(via->lock); base1 = via_rd(via, ch->base, 4); len = via_rd(via, ch->count, 4); base = via_rd(via, ch->base, 4); if (base != base1) /* Avoid race hazard */ len = via_rd(via, ch->count, 4); + snd_mtxunlock(via->lock); DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base)); |