On 03/07/07, Adrian McMenamin <adrianmcmenamin@xxxxxxxxx> wrote: > This patch stops the driver from crashing in certain situations (eg if > the network fails when NFS mounted), please apply. > Actually, looked at this again and while the previous patch stopped the driver from crashing it still locked the sound subsystem. This was because INIT_WORK was being called on the same work_struct when the device recovered from the network failure. The patch below ensures that this does not happen and that instead, PREPARE_WORK is called. Submitted by: Adrian McMenamin <adrian@xxxxxxxxxxxxxxxxx> Signed-off by: Adrian McMenamin <adrian@xxxxxxxxxxxxxxxxx> --- alsa-kernel/sh/aica.c 2007-06-23 15:25:55.000000000 +0100 +++ linux-2.6.21/sound/sh/aica.c 2007-07-04 00:01:23.000000000 +0100 @@ -68,6 +68,7 @@ static struct spu_work_holder { struct work_struct spu_dma_work; void *sspointer; + int already_started; } spu_working; static struct workqueue_struct *aica_queue; @@ -319,7 +320,13 @@ dreamcastcard = substream->pcm->private_data; /* Use queue to do the heavy lifting */ spu_working.sspointer = substream; - INIT_WORK(&(spu_working.spu_dma_work), run_spu_dma); + if (spu_working.already_started == 1) { + PREPARE_WORK(&(spu_working.spu_dma_work), run_spu_dma); + } + else { + INIT_WORK(&(spu_working.spu_dma_work), run_spu_dma); + spu_working.already_started = 1; + } queue_work(aica_queue, &(spu_working.spu_dma_work)); /* Timer may already be running */ if (unlikely(dreamcastcard->timer.data)) { @@ -366,7 +373,9 @@ *substream) { struct snd_card_aica *dreamcastcard = substream->pcm->private_data; + flush_workqueue(aica_queue); del_timer(&dreamcastcard->timer); + aica_chn_halt(); kfree(dreamcastcard->channel); spu_disable(); return 0; @@ -402,17 +411,10 @@ static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { - struct snd_card_aica *dreamcastcard; switch (cmd) { case SNDRV_PCM_TRIGGER_START: spu_begin_dma(substream); break; - case SNDRV_PCM_TRIGGER_STOP: - dreamcastcard = substream->pcm->private_data; - if (dreamcastcard->timer.data) - del_timer(&dreamcastcard->timer); - aica_chn_halt(); - break; default: return -EINVAL; } _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel