All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH]: Keep sound-module usage correct, even if audio_open fails
@ 2001-01-11  0:12 Chris Rankin
  0 siblings, 0 replies; only message in thread
From: Chris Rankin @ 2001-01-11  0:12 UTC (permalink / raw)
  To: linux-kernel, linux-sound

Hi,
I noticed that if you try to (e.g.) play two WAV file simultaneously,
then not only does the second one fail ("Device or resource busy", of
course) but the sound-card module's usage count breaks.

Here is a patch. And Alan, since you seem to be the person collecting
these sound patches, I should point out that this patch to
drivers/sound/audio.c completely replaces the patch to audio.c that I
submitted earlier. That patch was related to the coprocessor module
locking, but this new patch has reworked the way that audio_open()
cleans up after itself anyway. This clean-up now includes the
coprocessor too.

Cheers,
Chris

--- linux-vanilla/drivers/sound/audio.c	Fri Aug 11 16:26:43 2000
+++ linux-2.4.0-ac3/drivers/sound/audio.c	Wed Jan 10 23:53:23 2001
@@ -21,6 +21,9 @@
  * Daniel Rodriksson: reworked the use of the device specific copy_user
  *                    still generic
  * Horst von Brand:  Add missing #include <linux/string.h>
+ * Chris Rankin    : Update the module-usage counter for the coprocessor,
+ *                   and decrement the counters again if we cannot open
+ *                   the audio device.
  */
 
 #include <linux/stddef.h>
@@ -71,6 +74,8 @@
 	int bits;
 	int dev_type = dev & 0x0f;
 	int mode = translate_mode(file);
+	const struct audio_driver *driver;
+	const struct coproc_operations *coprocessor;
 
 	dev = dev >> 4;
 
@@ -82,18 +87,20 @@
 	if (dev < 0 || dev >= num_audiodevs)
 		return -ENXIO;
 
-	if (audio_devs[dev]->d->owner)
-		__MOD_INC_USE_COUNT (audio_devs[dev]->d->owner);
+	driver = audio_devs[dev]->d;
+	if (driver->owner)
+		__MOD_INC_USE_COUNT(driver->owner);
 
 	if ((ret = DMAbuf_open(dev, mode)) < 0)
-		return ret;
+		goto error_1;
 
-	if (audio_devs[dev]->coproc) {
-		if ((ret = audio_devs[dev]->coproc->
-			open(audio_devs[dev]->coproc->devc, COPR_PCM)) < 0) {
-			audio_release(dev, file);
+	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
+		if (coprocessor->owner)
+			__MOD_INC_USE_COUNT(coprocessor->owner);
+
+		if ((ret = coprocessor->open(coprocessor->devc, COPR_PCM)) < 0) {
 			printk(KERN_WARNING "Sound: Can't access coprocessor device\n");
-			return ret;
+			goto error_2;
 		}
 	}
 	
@@ -106,6 +113,20 @@
 
 	audio_devs[dev]->audio_mode = AM_NONE;
 
+	return 0;
+
+	/*
+	 * Clean-up stack: this is what needs (un)doing if
+	 * we can't open the audio device ...
+	 */
+	error_2:
+	if (coprocessor->owner)
+		__MOD_DEC_USE_COUNT(coprocessor->owner);
+	DMAbuf_release(dev, mode);
+
+	error_1:
+	if (driver->owner)
+		__MOD_DEC_USE_COUNT(driver->owner);
 
 	return ret;
 }
@@ -156,7 +177,8 @@
 
 void audio_release(int dev, struct file *file)
 {
-	int             mode = translate_mode(file);
+	const struct coproc_operations *coprocessor;
+	int mode = translate_mode(file);
 
 	dev = dev >> 4;
 
@@ -176,8 +198,12 @@
 	if (mode & OPEN_WRITE)
 		sync_output(dev);
 
-	if (audio_devs[dev]->coproc)
-		audio_devs[dev]->coproc->close(audio_devs[dev]->coproc->devc, COPR_PCM);
+	if ( (coprocessor = audio_devs[dev]->coproc) != NULL ) {
+		coprocessor->close(coprocessor->devc, COPR_PCM);
+
+		if (coprocessor->owner)
+			__MOD_DEC_USE_COUNT(coprocessor->owner);
+	}
 	DMAbuf_release(dev, mode);
 
 	if (audio_devs[dev]->d->owner)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-01-11  0:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-01-11  0:12 [PATCH]: Keep sound-module usage correct, even if audio_open fails Chris Rankin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.