If an endpoint uses another endpoint for synchronization, and the other endpoint is stopped, an oops will occur on NULL dereference. Clearing the prepare/retire callbacks solves this issue.
Signed-off-by: Eldad Zack eldad@fogrefinery.com
--- Note sure if the oops happens because of pcm_stream is NULLified, or somewhere else. Needs a closer look.
I suspect this condition does not happen in practice since the call to snd_usb_endpoint_deactivate() will unconditionally deactivate the URBs. --- sound/usb/pcm.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index f612c4e..aa1e21f 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1166,6 +1166,8 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) subs->interface = -1; }
+ subs->data_endpoint->prepare_data_urb = NULL; + subs->data_endpoint->retire_data_urb = NULL; subs->pcm_substream = NULL; snd_usb_autosuspend(subs->stream->chip);
@@ -1492,6 +1494,8 @@ static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substrea subs->running = 1; return 0; case SNDRV_PCM_TRIGGER_STOP: + subs->data_endpoint->prepare_data_urb = NULL; + subs->data_endpoint->retire_data_urb = NULL; stop_endpoints(subs, false); subs->running = 0; return 0; @@ -1522,6 +1526,7 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream subs->running = 1; return 0; case SNDRV_PCM_TRIGGER_STOP: + subs->data_endpoint->retire_data_urb = NULL; stop_endpoints(subs, false); subs->running = 0; return 0;