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; } }