summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/pci/als4000.c15
-rw-r--r--sys/dev/sound/pci/via8233.c44
-rw-r--r--sys/dev/sound/pci/via82c686.c10
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));
OpenPOWER on IntegriCloud