aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristos Margiolis <christos@FreeBSD.org>2025-11-21 16:14:13 +0000
committerChristos Margiolis <christos@FreeBSD.org>2025-11-21 16:14:13 +0000
commitb4c32d67d40a862620aa3e565ed0cb9ad59f1e60 (patch)
treedaa95ca94acc72e481aa9348d59c8750ab0ba2e6
parente13664f6a44b4970ea5e8378b8e1a4879fa5d5a0 (diff)
sound: Simplify logic in dsp_io_ops()
Use CHN_LOCK()/CHN_UNLOCK() directly, instead of dsp_lock_chans()/dsp_unlock_chans(). These functions are useful when we want to potentially lock both channels. Here we know which channel we are locking, so we can just lock it directly. This way we get rid of the prio variable as well. Related to runpid again, there is no reason to assign it when CHN_F_RUNNING is not set. channel->pid (as well as channel->comm) is always assigned in dsp_chn_alloc(). Get rid of runpid. I do not see how we can end up with channel->pid (td->td_proc->p_pid) not matching buf->uio_td->td_proc->p_pid. Also improve errno values. Sponsored by: The FreeBSD Foundation MFC after: 1 week Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D53736
-rw-r--r--sys/dev/sound/pcm/dsp.c32
1 files changed, 10 insertions, 22 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 1ae090f252c2..cb8b5414973c 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -464,8 +464,7 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
struct snddev_info *d;
struct pcm_channel *ch;
int (*chn_io)(struct pcm_channel *, struct uio *);
- int prio, ret;
- pid_t runpid;
+ int ret;
d = priv->sc;
if (!DSP_REGISTERED(d))
@@ -475,37 +474,27 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
switch (buf->uio_rw) {
case UIO_READ:
- prio = FREAD;
ch = priv->rdch;
chn_io = chn_read;
break;
case UIO_WRITE:
- prio = FWRITE;
ch = priv->wrch;
chn_io = chn_write;
break;
}
-
- runpid = buf->uio_td->td_proc->p_pid;
-
- dsp_lock_chans(priv, prio);
-
- if (ch == NULL || !(ch->flags & CHN_F_BUSY)) {
- if (priv->rdch != NULL || priv->wrch != NULL)
- dsp_unlock_chans(priv, prio);
+ if (ch == NULL) {
PCM_GIANT_EXIT(d);
- return (EBADF);
+ return (ENXIO);
}
+ CHN_LOCK(ch);
- if (ch->flags & (CHN_F_MMAP | CHN_F_DEAD) ||
- (ch->flags & CHN_F_RUNNING && ch->pid != runpid)) {
- dsp_unlock_chans(priv, prio);
+ if (!(ch->flags & CHN_F_BUSY) ||
+ (ch->flags & (CHN_F_MMAP | CHN_F_DEAD))) {
+ CHN_UNLOCK(ch);
PCM_GIANT_EXIT(d);
- return (EINVAL);
- } else if (!(ch->flags & CHN_F_RUNNING)) {
+ return (ENXIO);
+ } else if (!(ch->flags & CHN_F_RUNNING))
ch->flags |= CHN_F_RUNNING;
- ch->pid = runpid;
- }
/*
* chn_read/write must give up channel lock in order to copy bytes
@@ -517,8 +506,7 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
ch->inprog--;
CHN_BROADCAST(&ch->cv);
-
- dsp_unlock_chans(priv, prio);
+ CHN_UNLOCK(ch);
PCM_GIANT_LEAVE(d);