git: 6378079427be - stable/14 - sound: Improve simplex handling in dsp_open()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 10 Jul 2024 16:49:05 UTC
The branch stable/14 has been updated by christos: URL: https://cgit.FreeBSD.org/src/commit/?id=6378079427be35962d36a8e9b587eb63b1159e99 commit 6378079427be35962d36a8e9b587eb63b1159e99 Author: Christos Margiolis <christos@FreeBSD.org> AuthorDate: 2024-07-06 18:22:45 +0000 Commit: Christos Margiolis <christos@FreeBSD.org> CommitDate: 2024-07-10 16:48:13 +0000 sound: Improve simplex handling in dsp_open() If we are in simplex mode, make sure we do not open in both directions (read/write) and also that we do not open in a direction opposite of what is already opened. For example, if the device is already doing playback, we cannot open the device for recording at the same time, and vice-versa. While here, remove dsp_cdevpriv->simplex as it's no longer needed. Sponsored by: The FreeBSD Foundation MFC after: 2 days Reviewed by: dev_submerge.ch Differential Revision: https://reviews.freebsd.org/D45835 (cherry picked from commit be04a9d9387f6b5d4e83fc4976d8d83bb03fe5af) --- sys/dev/sound/pcm/dsp.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c index f2cead08783c..26a2919ed1da 100644 --- a/sys/dev/sound/pcm/dsp.c +++ b/sys/dev/sound/pcm/dsp.c @@ -52,7 +52,6 @@ struct dsp_cdevpriv { struct pcm_channel *rdch; struct pcm_channel *wrch; struct pcm_channel *volch; - int simplex; }; static int dsp_mmap_allow_prot_exec = 0; @@ -301,10 +300,10 @@ static int dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) { struct dsp_cdevpriv *priv; - struct pcm_channel *rdch, *wrch; + struct pcm_channel *rdch, *wrch, *ch; struct snddev_info *d; uint32_t fmt, spd; - int error, rderror, wrerror; + int error, rderror, wrerror, dir; /* Kind of impossible.. */ if (i_dev == NULL || td == NULL) @@ -319,7 +318,6 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) priv->rdch = NULL; priv->wrch = NULL; priv->volch = NULL; - priv->simplex = (pcm_getflags(d->dev) & SD_F_SIMPLEX) ? 1 : 0; error = devfs_set_cdevpriv(priv, dsp_close); if (error != 0) @@ -333,6 +331,36 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td) error = 0; DSP_FIXUP_ERROR(); + if (pcm_getflags(d->dev) & SD_F_SIMPLEX) { + if (DSP_F_DUPLEX(flags)) { + /* + * If no channels are opened yet, and we request + * DUPLEX, limit to playback only, otherwise open one + * channel in a direction that already exists. + */ + if (CHN_EMPTY(d, channels.pcm.opened)) { + if (d->playcount > 0) + flags &= ~FREAD; + else if (d->reccount > 0) + flags &= ~FWRITE; + } else { + ch = CHN_FIRST(d, channels.pcm.opened); + if (ch->direction == PCMDIR_PLAY) + flags &= ~FREAD; + else if (ch->direction == PCMDIR_REC) + flags &= ~FWRITE; + } + } else if (!CHN_EMPTY(d, channels.pcm.opened)) { + /* + * If we requested SIMPLEX, make sure we do not open a + * channel in the opposite direction. + */ + ch = CHN_FIRST(d, channels.pcm.opened); + dir = DSP_F_READ(flags) ? PCMDIR_REC : PCMDIR_PLAY; + if (ch->direction != dir) + error = ENOTSUP; + } + } if (error != 0) { PCM_UNLOCK(d); PCM_GIANT_EXIT(d);