Hi,
The emu10k1 driver is missing a few unlocks on error exit paths.
Patch attached against 2.4.1-pre8.
Rui Sousa
diff -uNr linux-2.4.1-pre8/drivers/sound/emu10k1/audio.c
linux-2.4.1-pre8.new/drivers/sound/emu10k1/audio.c
--- linux-2.4.1-pre8/drivers/sound/emu10k1/audio.c Thu Sep 21 22:25:09 2000
+++ linux-2.4.1-pre8.new/drivers/sound/emu10k1/audio.c Wed Jan 17 13:52:50 2001
@@ -375,8 +375,10 @@
format = wiinst->format;
format.samplingrate = val;
- if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+ if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
+ spin_unlock_irqrestore(&wiinst->lock, flags);
return -EINVAL;
+ }
val = wiinst->format.samplingrate;
@@ -393,8 +395,10 @@
format = woinst->format;
format.samplingrate = val;
- if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+ if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+{
+ spin_unlock_irqrestore(&woinst->lock, flags);
return -EINVAL;
+ }
val = woinst->format.samplingrate;
@@ -430,8 +434,10 @@
format = wiinst->format;
format.channels = val ? 2 : 1;
- if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+ if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
+ spin_unlock_irqrestore(&wiinst->lock, flags);
return -EINVAL;
+ }
val = wiinst->format.channels - 1;
@@ -447,8 +453,10 @@
format = woinst->format;
format.channels = val ? 2 : 1;
- if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+ if (emu10k1_waveout_setformat(wave_dev, &format) < 0) {
+ spin_unlock_irqrestore(&woinst->lock, flags);
return -EINVAL;
+ }
val = woinst->format.channels - 1;
@@ -478,8 +486,10 @@
format = wiinst->format;
format.channels = val;
- if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+ if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
+ spin_unlock_irqrestore(&wiinst->lock, flags);
return -EINVAL;
+ }
val = wiinst->format.channels;
@@ -495,8 +505,10 @@
format = woinst->format;
format.channels = val;
- if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+ if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+{
+ spin_unlock_irqrestore(&woinst->lock, flags);
return -EINVAL;
+ }
val = woinst->format.channels;
@@ -542,8 +554,10 @@
format = wiinst->format;
format.bitsperchannel = val;
- if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+ if (emu10k1_wavein_setformat(wave_dev, &format) < 0) {
+ spin_unlock_irqrestore(&wiinst->lock, flags);
return -EINVAL;
+ }
val = wiinst->format.bitsperchannel;
@@ -559,8 +573,10 @@
format = woinst->format;
format.bitsperchannel = val;
- if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+ if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+{
+ spin_unlock_irqrestore(&woinst->lock, flags);
return -EINVAL;
+ }
val = woinst->format.bitsperchannel;
@@ -968,6 +984,7 @@
for (i = 0; i < woinst->buffer.pages; i++) {
if (remap_page_range(vma->vm_start + (i * PAGE_SIZE),
virt_to_phys(woinst->buffer.addr[i]), PAGE_SIZE, vma->vm_page_prot)) {
spin_unlock_irqrestore(&woinst->lock, flags);
+ unlock_kernel();
return -EAGAIN;
}
}