aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/sound
diff options
context:
space:
mode:
authorHans Petter Selasky <hselasky@FreeBSD.org>2020-03-04 17:23:20 +0000
committerHans Petter Selasky <hselasky@FreeBSD.org>2020-03-04 17:23:20 +0000
commitcc1efc23c8f94991ae65f43c9a311a7e43918480 (patch)
treebec88a39464c993ff3d482340b748b51b4c500c4 /sys/dev/sound
parent3818c25a1d1fb4e573c4a7ca6826d759d6eb57b6 (diff)
downloadsrc-cc1efc23c8f94991ae65f43c9a311a7e43918480.tar.gz
src-cc1efc23c8f94991ae65f43c9a311a7e43918480.zip
Implement a detaching flag for the sound(4) subsystem to take
appropriate actions when we are trying to detach an audio device, but cannot because someone is using it. This avoids applications having to wait for the DSP read data timeout before they receive any error indication. Tested with virtual_oss(8). Remove some unused definitions while at it. PR: 194727 MFC after: 1 week Sponsored by: Mellanox Technologies
Notes
Notes: svn path=/head/; revision=358629
Diffstat (limited to 'sys/dev/sound')
-rw-r--r--sys/dev/sound/pcm/dsp.c16
-rw-r--r--sys/dev/sound/pcm/mixer.c10
-rw-r--r--sys/dev/sound/pcm/sound.c2
-rw-r--r--sys/dev/sound/pcm/sound.h13
4 files changed, 20 insertions, 21 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 99fcf8a16dbb..885b05aed1ad 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -460,7 +460,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
return (ENODEV);
d = dsp_get_info(i_dev);
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
return (EBADF);
PCM_GIANT_ENTER(d);
@@ -830,7 +830,7 @@ dsp_io_ops(struct cdev *i_dev, struct uio *buf)
("%s(): io train wreck!", __func__));
d = dsp_get_info(i_dev);
- if (!DSP_REGISTERED(d, i_dev))
+ if (PCM_DETACHING(d) || !DSP_REGISTERED(d, i_dev))
return (EBADF);
PCM_GIANT_ENTER(d);
@@ -1075,7 +1075,7 @@ dsp_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
int *arg_i, ret, tmp;
d = dsp_get_info(i_dev);
- if (!DSP_REGISTERED(d, i_dev))
+ if (PCM_DETACHING(d) || !DSP_REGISTERED(d, i_dev))
return (EBADF);
PCM_GIANT_ENTER(d);
@@ -2170,9 +2170,11 @@ dsp_poll(struct cdev *i_dev, int events, struct thread *td)
int ret, e;
d = dsp_get_info(i_dev);
- if (!DSP_REGISTERED(d, i_dev))
- return (EBADF);
-
+ if (PCM_DETACHING(d) || !DSP_REGISTERED(d, i_dev)) {
+ /* XXX many clients don't understand POLLNVAL */
+ return (events & (POLLHUP | POLLPRI | POLLIN |
+ POLLRDNORM | POLLOUT | POLLWRNORM));
+ }
PCM_GIANT_ENTER(d);
wrch = NULL;
@@ -2246,7 +2248,7 @@ dsp_mmap_single(struct cdev *i_dev, vm_ooffset_t *offset,
return (EINVAL);
d = dsp_get_info(i_dev);
- if (!DSP_REGISTERED(d, i_dev))
+ if (PCM_DETACHING(d) || !DSP_REGISTERED(d, i_dev))
return (EINVAL);
PCM_GIANT_ENTER(d);
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index c58988758b62..5bc27d653552 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -153,7 +153,7 @@ mixer_set_softpcmvol(struct snd_mixer *m, struct snddev_info *d,
struct pcm_channel *c;
int dropmtx, acquiremtx;
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
return (EINVAL);
if (mtx_owned(m->lock))
@@ -206,7 +206,7 @@ mixer_set_eq(struct snd_mixer *m, struct snddev_info *d,
else
return (EINVAL);
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
return (EINVAL);
if (mtx_owned(m->lock))
@@ -1046,7 +1046,7 @@ mixer_open(struct cdev *i_dev, int flags, int mode, struct thread *td)
m = i_dev->si_drv1;
d = device_get_softc(m->dev);
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
return (EBADF);
/* XXX Need Giant magic entry ??? */
@@ -1202,7 +1202,7 @@ mixer_ioctl(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
return (EBADF);
d = device_get_softc(((struct snd_mixer *)i_dev->si_drv1)->dev);
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
return (EBADF);
PCM_GIANT_ENTER(d);
@@ -1411,7 +1411,7 @@ mixer_oss_mixerinfo(struct cdev *i_dev, oss_mixerinfo *mi)
for (i = 0; pcm_devclass != NULL &&
i < devclass_get_maxunit(pcm_devclass); i++) {
d = devclass_get_softc(pcm_devclass, i);
- if (!PCM_REGISTERED(d))
+ if (PCM_DETACHING(d) || !PCM_REGISTERED(d))
continue;
/* XXX Need Giant magic entry */
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
index bd3b4c684365..601474190d10 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -1162,6 +1162,8 @@ pcm_unregister(device_t dev)
PCM_LOCK(d);
PCM_WAIT(d);
+ d->flags |= SD_F_DETACHING;
+
if (d->inprog != 0) {
device_printf(dev, "unregister: operation in progress\n");
PCM_UNLOCK(d);
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
index 829ffcf6b721..5730e7fa39aa 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -131,15 +131,8 @@ struct snd_mixer;
#define SD_F_SIMPLEX 0x00000001
#define SD_F_AUTOVCHAN 0x00000002
#define SD_F_SOFTPCMVOL 0x00000004
-/*
- * Obsolete due to better matrixing
- */
-#if 0
-#define SD_F_PSWAPLR 0x00000008
-#define SD_F_RSWAPLR 0x00000010
-#endif
#define SD_F_DYING 0x00000008
-#define SD_F_SUICIDE 0x00000010
+#define SD_F_DETACHING 0x00000010
#define SD_F_BUSY 0x00000020
#define SD_F_MPSAFE 0x00000040
#define SD_F_REGISTERED 0x00000080
@@ -165,7 +158,7 @@ struct snd_mixer;
"\002AUTOVCHAN" \
"\003SOFTPCMVOL" \
"\004DYING" \
- "\005SUICIDE" \
+ "\005DETACHING" \
"\006BUSY" \
"\007MPSAFE" \
"\010REGISTERED" \
@@ -184,6 +177,8 @@ struct snd_mixer;
#define PCM_REGISTERED(x) (PCM_ALIVE(x) && \
((x)->flags & SD_F_REGISTERED))
+#define PCM_DETACHING(x) ((x)->flags & SD_F_DETACHING)
+
/* many variables should be reduced to a range. Here define a macro */
#define RANGE(var, low, high) (var) = \
(((var)<(low))? (low) : ((var)>(high))? (high) : (var))