[ALSA] Fix hang-up at disconnection of usb-audio
authorTakashi Iwai <tiwai@suse.de>
Wed, 8 Nov 2006 14:41:29 +0000 (15:41 +0100)
committerJaroslav Kysela <perex@suse.cz>
Tue, 28 Nov 2006 12:46:38 +0000 (13:46 +0100)
Fix hang-up at disconnection of usb-audio devices while accessing PCM.
Don't handle PCM operations any more after shutdown flag is set.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
sound/core/oss/pcm_oss.c
sound/core/pcm_native.c
sound/usb/usbaudio.c

index 505b23ec4058c29a4407d8cd29c78e0c3509bdb1..e0821eb3d8517b2f258bb0353ebe0c10418f8b73 100644 (file)
@@ -2359,7 +2359,8 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file)
                substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
        snd_assert(substream != NULL, return -ENXIO);
        pcm = substream->pcm;
-       snd_pcm_oss_sync(pcm_oss_file);
+       if (!pcm->card->shutdown)
+               snd_pcm_oss_sync(pcm_oss_file);
        mutex_lock(&pcm->open_mutex);
        snd_pcm_oss_release_file(pcm_oss_file);
        mutex_unlock(&pcm->open_mutex);
index 37b4b10850ae0358cdbbf654fffd6754aa5a11d4..66e24b5da4694dbaa40529a98b14743520aa41ef 100644 (file)
@@ -1310,7 +1310,8 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
                               int f_flags)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
-       if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+       if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
        if (snd_pcm_running(substream))
                return -EBUSY;
@@ -1568,7 +1569,8 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        runtime = substream->runtime;
        card = substream->pcm->card;
 
-       if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
+       if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
 
        snd_power_lock(card);
index c82b01c7ad3ad9871f5fe619db8929fb596cbc51..67202b9eeb77c09bf4c3d10fb372c5582e92394c 100644 (file)
@@ -1469,7 +1469,8 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
        subs->cur_audiofmt = NULL;
        subs->cur_rate = 0;
        subs->period_bytes = 0;
-       release_substream_urbs(subs, 0);
+       if (!subs->stream->chip->shutdown)
+               release_substream_urbs(subs, 0);
        return snd_pcm_free_vmalloc_buffer(substream);
 }