when usb audio device removes, we need to stop the current pcm substream when detecting hw disconnects. otherwise the read / write thread may sleep for long time before timeout, thus upper layer is blocked for long time and can't repsond quickly to the hw disconnection. also substream & pcm may still be used after audio unbind, and we should only set null to it in audio_pcm_close. Signed-off-by: Qiao Zhou <zhouqiao@xxxxxxxxxxx> --- drivers/usb/gadget/f_audio_source.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/f_audio_source.c b/drivers/usb/gadget/f_audio_source.c index c757409..8d4f58e 100644 --- a/drivers/usb/gadget/f_audio_source.c +++ b/drivers/usb/gadget/f_audio_source.c @@ -620,15 +620,21 @@ static void audio_unbind(struct usb_configuration *c, struct usb_function *f) { struct audio_dev *audio = func_to_audio(f); + struct snd_pcm_substream *substream = audio->substream; struct usb_request *req; while ((req = audio_req_get(audio))) audio_request_free(req, audio->in_ep); + /* stop pcm stream when audio unbind after hw disconnect */ + if (substream && substream->runtime && snd_pcm_running(substream)) { + snd_pcm_stream_lock_irq(substream); + snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED); + snd_pcm_stream_unlock_irq(substream); + } + snd_card_free_when_closed(audio->card); audio->card = NULL; - audio->pcm = NULL; - audio->substream = NULL; audio->in_ep = NULL; } @@ -670,6 +676,7 @@ static int audio_pcm_close(struct snd_pcm_substream *substream) unsigned long flags; spin_lock_irqsave(&audio->lock, flags); + audio->pcm = NULL; audio->substream = NULL; spin_unlock_irqrestore(&audio->lock, flags); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html