svn commit: r358629 - head/sys/dev/sound/pcm

Hans Petter Selasky hselasky at FreeBSD.org
Wed Mar 4 17:23:22 UTC 2020


Author: hselasky
Date: Wed Mar  4 17:23:20 2020
New Revision: 358629
URL: https://svnweb.freebsd.org/changeset/base/358629

Log:
  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

Modified:
  head/sys/dev/sound/pcm/dsp.c
  head/sys/dev/sound/pcm/mixer.c
  head/sys/dev/sound/pcm/sound.c
  head/sys/dev/sound/pcm/sound.h

Modified: head/sys/dev/sound/pcm/dsp.c
==============================================================================
--- head/sys/dev/sound/pcm/dsp.c	Wed Mar  4 17:21:49 2020	(r358628)
+++ head/sys/dev/sound/pcm/dsp.c	Wed Mar  4 17:23:20 2020	(r358629)
@@ -460,7 +460,7 @@ dsp_open(struct cdev *i_dev, int flags, int mode, stru
 		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 *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
 	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 *offs
 		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);

Modified: head/sys/dev/sound/pcm/mixer.c
==============================================================================
--- head/sys/dev/sound/pcm/mixer.c	Wed Mar  4 17:21:49 2020	(r358628)
+++ head/sys/dev/sound/pcm/mixer.c	Wed Mar  4 17:23:20 2020	(r358629)
@@ -153,7 +153,7 @@ mixer_set_softpcmvol(struct snd_mixer *m, struct sndde
 	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 *
 	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, st
 
 	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 ar
 		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 
 	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 */

Modified: head/sys/dev/sound/pcm/sound.c
==============================================================================
--- head/sys/dev/sound/pcm/sound.c	Wed Mar  4 17:21:49 2020	(r358628)
+++ head/sys/dev/sound/pcm/sound.c	Wed Mar  4 17:23:20 2020	(r358629)
@@ -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);

Modified: head/sys/dev/sound/pcm/sound.h
==============================================================================
--- head/sys/dev/sound/pcm/sound.h	Wed Mar  4 17:21:49 2020	(r358628)
+++ head/sys/dev/sound/pcm/sound.h	Wed Mar  4 17:23:20 2020	(r358629)
@@ -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"			\
@@ -183,6 +176,8 @@ struct snd_mixer;
 				 !((x)->flags & SD_F_DYING))
 #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) = \


More information about the svn-src-all mailing list