summaryrefslogtreecommitdiff
path: root/sound/usb/usx2y/us144mkii.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/usx2y/us144mkii.c')
-rw-r--r--sound/usb/usx2y/us144mkii.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sound/usb/usx2y/us144mkii.c b/sound/usb/usx2y/us144mkii.c
index 94553b61013c..58ef23146f20 100644
--- a/sound/usb/usx2y/us144mkii.c
+++ b/sound/usb/usx2y/us144mkii.c
@@ -585,19 +585,24 @@ static void tascam_disconnect(struct usb_interface *intf)
return;
if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
- /* Ensure all deferred work is complete before freeing resources */
snd_card_disconnect(tascam->card);
- cancel_work_sync(&tascam->stop_work);
- cancel_work_sync(&tascam->capture_work);
- cancel_work_sync(&tascam->midi_in_work);
- cancel_work_sync(&tascam->midi_out_work);
- cancel_work_sync(&tascam->stop_pcm_work);
+ /*
+ * Kill the URBs before cancelling the work, so a late URB
+ * completion cannot re-arm a work that then runs after
+ * snd_card_free().
+ */
usb_kill_anchored_urbs(&tascam->playback_anchor);
usb_kill_anchored_urbs(&tascam->capture_anchor);
usb_kill_anchored_urbs(&tascam->feedback_anchor);
usb_kill_anchored_urbs(&tascam->midi_in_anchor);
usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+
+ cancel_work_sync(&tascam->stop_work);
+ cancel_work_sync(&tascam->capture_work);
+ cancel_work_sync(&tascam->midi_in_work);
+ cancel_work_sync(&tascam->midi_out_work);
+ cancel_work_sync(&tascam->stop_pcm_work);
timer_delete_sync(&tascam->error_timer);
tascam_free_urbs(tascam);
snd_card_free(tascam->card);