aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/usb/usbmidi.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index b2da478a0fae..c7cb207963f5 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -984,6 +984,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
984 DEFINE_WAIT(wait); 984 DEFINE_WAIT(wait);
985 long timeout = msecs_to_jiffies(50); 985 long timeout = msecs_to_jiffies(50);
986 986
987 if (ep->umidi->disconnected)
988 return;
987 /* 989 /*
988 * The substream buffer is empty, but some data might still be in the 990 * The substream buffer is empty, but some data might still be in the
989 * currently active URBs, so we have to wait for those to complete. 991 * currently active URBs, so we have to wait for those to complete.
@@ -1121,14 +1123,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1121 * Frees an output endpoint. 1123 * Frees an output endpoint.
1122 * May be called when ep hasn't been initialized completely. 1124 * May be called when ep hasn't been initialized completely.
1123 */ 1125 */
1124static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) 1126static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
1125{ 1127{
1126 unsigned int i; 1128 unsigned int i;
1127 1129
1128 for (i = 0; i < OUTPUT_URBS; ++i) 1130 for (i = 0; i < OUTPUT_URBS; ++i)
1129 if (ep->urbs[i].urb) 1131 if (ep->urbs[i].urb) {
1130 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, 1132 free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
1131 ep->max_transfer); 1133 ep->max_transfer);
1134 ep->urbs[i].urb = NULL;
1135 }
1136}
1137
1138static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
1139{
1140 snd_usbmidi_out_endpoint_clear(ep);
1132 kfree(ep); 1141 kfree(ep);
1133} 1142}
1134 1143
@@ -1260,15 +1269,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
1260 usb_kill_urb(ep->out->urbs[j].urb); 1269 usb_kill_urb(ep->out->urbs[j].urb);
1261 if (umidi->usb_protocol_ops->finish_out_endpoint) 1270 if (umidi->usb_protocol_ops->finish_out_endpoint)
1262 umidi->usb_protocol_ops->finish_out_endpoint(ep->out); 1271 umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
1272 ep->out->active_urbs = 0;
1273 if (ep->out->drain_urbs) {
1274 ep->out->drain_urbs = 0;
1275 wake_up(&ep->out->drain_wait);
1276 }
1263 } 1277 }
1264 if (ep->in) 1278 if (ep->in)
1265 for (j = 0; j < INPUT_URBS; ++j) 1279 for (j = 0; j < INPUT_URBS; ++j)
1266 usb_kill_urb(ep->in->urbs[j]); 1280 usb_kill_urb(ep->in->urbs[j]);
1267 /* free endpoints here; later call can result in Oops */ 1281 /* free endpoints here; later call can result in Oops */
1268 if (ep->out) { 1282 if (ep->out)
1269 snd_usbmidi_out_endpoint_delete(ep->out); 1283 snd_usbmidi_out_endpoint_clear(ep->out);
1270 ep->out = NULL;
1271 }
1272 if (ep->in) { 1284 if (ep->in) {
1273 snd_usbmidi_in_endpoint_delete(ep->in); 1285 snd_usbmidi_in_endpoint_delete(ep->in);
1274 ep->in = NULL; 1286 ep->in = NULL;