--- x/sound/usb/midi.c +++ y/sound/usb/midi.c @@ -307,6 +307,8 @@ static void snd_usbmidi_do_output(struct for (;;) { if (!(ep->active_urbs & (1 << urb_index))) { urb = ep->urbs[urb_index].urb; + if (!urb) + goto next; urb->transfer_buffer_length = 0; ep->umidi->usb_protocol_ops->output(ep, urb); if (urb->transfer_buffer_length == 0) @@ -319,6 +321,7 @@ static void snd_usbmidi_do_output(struct break; ep->active_urbs |= 1 << urb_index; } + next: if (++urb_index >= OUTPUT_URBS) urb_index = 0; if (urb_index == ep->next_urb) @@ -1396,13 +1399,19 @@ static int snd_usbmidi_in_endpoint_creat static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) { unsigned int i; + unsigned long flags; + spin_lock_irqsave(&ep->buffer_lock, flags); for (i = 0; i < OUTPUT_URBS; ++i) if (ep->urbs[i].urb) { - free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, - ep->max_transfer); + struct urb *urb = ep->urbs[i].urb; + ep->urbs[i].urb = NULL; + spin_unlock_irqrestore(&ep->buffer_lock, flags); + free_urb_and_buffer(ep->umidi, urb, ep->max_transfer); + spin_lock_irqsave(&ep->buffer_lock, flags); } + spin_unlock_irqrestore(&ep->buffer_lock, flags); } static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)