diff options
author | scottl <scottl@FreeBSD.org> | 2003-11-11 05:38:28 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-11-11 05:38:28 +0000 |
commit | b1f6b54a9b03a8c61b8ef229f3f4ba40905bcd45 (patch) | |
tree | b489e6d70819d26baf14c77df12889db048aca11 /sys/dev/sound/pci/cmi.c | |
parent | cc852a80a31de8499d7cb796db663450b8fd1596 (diff) | |
download | FreeBSD-src-b1f6b54a9b03a8c61b8ef229f3f4ba40905bcd45.zip FreeBSD-src-b1f6b54a9b03a8c61b8ef229f3f4ba40905bcd45.tar.gz |
Fix sound LOR problems:
dsp_open: rearrange to only hold one lock at a time
dsp_close: ditto
mixer_hwvol_init: delete locking, the only consumer seems to
be the ess driver and it only call it a creation time, I
think the device will be stable across the sleepable malloc.
cmi interrupt routine: Release locks while caller chn_intr,
either this or do what emu10k1 does which is have no locks
at in the interrupt handler.
Submitted by: mat@cnd.mcgill.ca
Diffstat (limited to 'sys/dev/sound/pci/cmi.c')
-rw-r--r-- | sys/dev/sound/pci/cmi.c | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c index 52c519a..bc99893 100644 --- a/sys/dev/sound/pci/cmi.c +++ b/sys/dev/sound/pci/cmi.c @@ -516,41 +516,41 @@ cmi_intr(void *data) { struct sc_info *sc = data; u_int32_t intrstat; + u_int32_t toclear; snd_mtxlock(sc->lock); intrstat = cmi_rd(sc, CMPCI_REG_INTR_STATUS, 4); - if ((intrstat & CMPCI_REG_ANY_INTR) == 0) { - goto out; - } + if ((intrstat & CMPCI_REG_ANY_INTR) != 0) { - /* Disable interrupts */ - if (intrstat & CMPCI_REG_CH0_INTR) { - cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); - } + toclear = 0; + if (intrstat & CMPCI_REG_CH0_INTR) { + toclear |= CMPCI_REG_CH0_INTR_ENABLE; + //cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); + } - if (intrstat & CMPCI_REG_CH1_INTR) { - cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); - } + if (intrstat & CMPCI_REG_CH1_INTR) { + toclear |= CMPCI_REG_CH1_INTR_ENABLE; + //cmi_clr4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); + } - /* Signal interrupts to channel */ - if (intrstat & CMPCI_REG_CH0_INTR) { - chn_intr(sc->pch.channel); - } + if (toclear) { + cmi_clr4(sc, CMPCI_REG_INTR_CTRL, toclear); + snd_mtxunlock(sc->lock); - if (intrstat & CMPCI_REG_CH1_INTR) { - chn_intr(sc->rch.channel); - } + /* Signal interrupts to channel */ + if (intrstat & CMPCI_REG_CH0_INTR) { + chn_intr(sc->pch.channel); + } - /* Enable interrupts */ - if (intrstat & CMPCI_REG_CH0_INTR) { - cmi_set4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH0_INTR_ENABLE); - } + if (intrstat & CMPCI_REG_CH1_INTR) { + chn_intr(sc->rch.channel); + } - if (intrstat & CMPCI_REG_CH1_INTR) { - cmi_set4(sc, CMPCI_REG_INTR_CTRL, CMPCI_REG_CH1_INTR_ENABLE); - } + snd_mtxlock(sc->lock); + cmi_set4(sc, CMPCI_REG_INTR_CTRL, toclear); -out: + } + } snd_mtxunlock(sc->lock); return; } |