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.
v2: Thanks to Daniel Mack, fixed (an ironic) NULL dereference when the pcm substream is opened and closed immediately.
Signed-off-by: Eldad Zack eldad@fogrefinery.com --- sound/usb/pcm.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 1a9a018..525bc8c 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1205,6 +1205,11 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) subs->interface = -1; }
+ if (subs->data_endpoint) { + subs->data_endpoint->prepare_data_urb = NULL; + subs->data_endpoint->retire_data_urb = NULL; + } + subs->pcm_substream = NULL; snd_usb_autosuspend(subs->stream->chip);
@@ -1535,6 +1540,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; @@ -1565,6 +1572,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;