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