diff options
| author | Orion Hodson <orion@FreeBSD.org> | 2002-08-18 14:17:06 +0000 |
|---|---|---|
| committer | Orion Hodson <orion@FreeBSD.org> | 2002-08-18 14:17:06 +0000 |
| commit | 42e67fd3e71b5af677062d8c728162dc837ca276 (patch) | |
| tree | 4eadfe559063ed9765d3308a640c52be50283c75 /sys/dev | |
| parent | 1652b7bde4f20083145db3fc7221f89a09d337ec (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/sound/pcm/dsp.c | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index b7eb4b9e5c96..1d4a66059e09 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -283,40 +283,34 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td) /* finished with snddev, new channels still locked */ /* bump refcounts, reset and unlock any channels that we just opened */ - if (rdch) { - if (flags & FREAD) { - if (chn_reset(rdch, fmt)) { - pcm_lock(d); - pcm_chnrelease(rdch); - if (wrch && (flags & FWRITE)) - pcm_chnrelease(wrch); - pcm_unlock(d); - splx(s); - return ENODEV; - } - if (flags & O_NONBLOCK) - rdch->flags |= CHN_F_NBIO; - } else - CHN_LOCK(rdch); + if (flags & FREAD) { + if (chn_reset(rdch, fmt)) { + pcm_lock(d); + pcm_chnrelease(rdch); + if (wrch && (flags & FWRITE)) + pcm_chnrelease(wrch); + pcm_unlock(d); + splx(s); + return ENODEV; + } + if (flags & O_NONBLOCK) + rdch->flags |= CHN_F_NBIO; pcm_chnref(rdch, 1); CHN_UNLOCK(rdch); } - if (wrch) { - if (flags & FWRITE) { - if (chn_reset(wrch, fmt)) { - pcm_lock(d); - pcm_chnrelease(wrch); - if (rdch && (flags & FREAD)) - pcm_chnrelease(rdch); - pcm_unlock(d); - splx(s); - return ENODEV; - } - if (flags & O_NONBLOCK) - wrch->flags |= CHN_F_NBIO; - } else - CHN_LOCK(wrch); + if (flags & FWRITE) { + if (chn_reset(wrch, fmt)) { + pcm_lock(d); + pcm_chnrelease(wrch); + if (rdch && (flags & FREAD)) + pcm_chnrelease(rdch); + pcm_unlock(d); + splx(s); + return ENODEV; + } + if (flags & O_NONBLOCK) + wrch->flags |= CHN_F_NBIO; pcm_chnref(wrch, 1); CHN_UNLOCK(wrch); @@ -345,18 +339,23 @@ dsp_close(dev_t i_dev, int flags, int mode, struct thread *td) if (rdch) { CHN_LOCK(rdch); if (pcm_chnref(rdch, -1) > 0) { - CHN_UNLOCK(rdch); exit = 1; } + CHN_UNLOCK(rdch); } if (wrch) { CHN_LOCK(wrch); if (pcm_chnref(wrch, -1) > 0) { - CHN_UNLOCK(wrch); exit = 1; } + CHN_UNLOCK(wrch); } + /* XXX And what happens if one of the channels had 2 references and + the other has but one? The latter won't get reset. Can that + happen? */ if (exit) { + i_dev->si_drv1 = NULL; + i_dev->si_drv2 = NULL; pcm_unlock(d); splx(s); return 0; @@ -367,9 +366,6 @@ dsp_close(dev_t i_dev, int flags, int mode, struct thread *td) if (pcm_getfakechan(d)) pcm_getfakechan(d)->flags = 0; - i_dev->si_drv1 = NULL; - i_dev->si_drv2 = NULL; - dsp_set_flags(i_dev, dsp_get_flags(i_dev) & ~SD_F_TRANSIENT); pcm_unlock(d); @@ -385,6 +381,8 @@ dsp_close(dev_t i_dev, int flags, int mode, struct thread *td) chn_reset(wrch, 0); pcm_chnrelease(wrch); } + i_dev->si_drv1 = NULL; + i_dev->si_drv2 = NULL; splx(s); return 0; |
