diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-04-10 15:34:56 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-04-10 15:34:56 -0400 |
commit | 27762b2ce16d5c6f7bc8ab1aad1b9179076f997a (patch) | |
tree | 04108617a1ccc18e3cef39e780c67460da9d5a0d /sound/usb | |
parent | 7b7b9042263f5cafb6ce85b3764375a8de7e22da (diff) | |
parent | 29aac005ff4dc8a5f50b80f4e5c4f59b21c0fb50 (diff) |
Merge branch 'fix/misc' into topic/usb
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/midi.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index c6ee4a18e513..2c1558c327bb 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -987,6 +987,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
987 | DEFINE_WAIT(wait); | 987 | DEFINE_WAIT(wait); |
988 | long timeout = msecs_to_jiffies(50); | 988 | long timeout = msecs_to_jiffies(50); |
989 | 989 | ||
990 | if (ep->umidi->disconnected) | ||
991 | return; | ||
990 | /* | 992 | /* |
991 | * The substream buffer is empty, but some data might still be in the | 993 | * The substream buffer is empty, but some data might still be in the |
992 | * currently active URBs, so we have to wait for those to complete. | 994 | * currently active URBs, so we have to wait for those to complete. |
@@ -1124,14 +1126,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1124 | * Frees an output endpoint. | 1126 | * Frees an output endpoint. |
1125 | * May be called when ep hasn't been initialized completely. | 1127 | * May be called when ep hasn't been initialized completely. |
1126 | */ | 1128 | */ |
1127 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) | 1129 | static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) |
1128 | { | 1130 | { |
1129 | unsigned int i; | 1131 | unsigned int i; |
1130 | 1132 | ||
1131 | for (i = 0; i < OUTPUT_URBS; ++i) | 1133 | for (i = 0; i < OUTPUT_URBS; ++i) |
1132 | if (ep->urbs[i].urb) | 1134 | if (ep->urbs[i].urb) { |
1133 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, | 1135 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, |
1134 | ep->max_transfer); | 1136 | ep->max_transfer); |
1137 | ep->urbs[i].urb = NULL; | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) | ||
1142 | { | ||
1143 | snd_usbmidi_out_endpoint_clear(ep); | ||
1135 | kfree(ep); | 1144 | kfree(ep); |
1136 | } | 1145 | } |
1137 | 1146 | ||
@@ -1263,15 +1272,18 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1263 | usb_kill_urb(ep->out->urbs[j].urb); | 1272 | usb_kill_urb(ep->out->urbs[j].urb); |
1264 | if (umidi->usb_protocol_ops->finish_out_endpoint) | 1273 | if (umidi->usb_protocol_ops->finish_out_endpoint) |
1265 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); | 1274 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); |
1275 | ep->out->active_urbs = 0; | ||
1276 | if (ep->out->drain_urbs) { | ||
1277 | ep->out->drain_urbs = 0; | ||
1278 | wake_up(&ep->out->drain_wait); | ||
1279 | } | ||
1266 | } | 1280 | } |
1267 | if (ep->in) | 1281 | if (ep->in) |
1268 | for (j = 0; j < INPUT_URBS; ++j) | 1282 | for (j = 0; j < INPUT_URBS; ++j) |
1269 | usb_kill_urb(ep->in->urbs[j]); | 1283 | usb_kill_urb(ep->in->urbs[j]); |
1270 | /* free endpoints here; later call can result in Oops */ | 1284 | /* free endpoints here; later call can result in Oops */ |
1271 | if (ep->out) { | 1285 | if (ep->out) |
1272 | snd_usbmidi_out_endpoint_delete(ep->out); | 1286 | snd_usbmidi_out_endpoint_clear(ep->out); |
1273 | ep->out = NULL; | ||
1274 | } | ||
1275 | if (ep->in) { | 1287 | if (ep->in) { |
1276 | snd_usbmidi_in_endpoint_delete(ep->in); | 1288 | snd_usbmidi_in_endpoint_delete(ep->in); |
1277 | ep->in = NULL; | 1289 | ep->in = NULL; |