: Keep sound-module usage correct, even if audio_open fails
PATCH 1/1 : Keep sound-module usage correct, even if audio_open fails
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
drivers/sound/audio.c +37 -11
@@ -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 [email protected]
Please read the FAQ at http://www.tux.org/lkml/