Merge branch 'for-next' into for-linus
[sfrench/cifs-2.6.git] / sound / usb / midi.c
index fe3fd6e4bb9bc7dbcfb90529701713f2070a958e..df639fe031181561290ca8f2295dac1c98e78d9e 100644 (file)
@@ -1499,6 +1499,8 @@ void snd_usbmidi_disconnect(struct list_head *p)
        spin_unlock_irq(&umidi->disc_lock);
        up_write(&umidi->disc_rwsem);
 
+       del_timer_sync(&umidi->error_timer);
+
        for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
                struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
                if (ep->out)
@@ -1525,7 +1527,6 @@ void snd_usbmidi_disconnect(struct list_head *p)
                        ep->in = NULL;
                }
        }
-       del_timer_sync(&umidi->error_timer);
 }
 EXPORT_SYMBOL(snd_usbmidi_disconnect);
 
@@ -2301,16 +2302,22 @@ void snd_usbmidi_input_stop(struct list_head *p)
 }
 EXPORT_SYMBOL(snd_usbmidi_input_stop);
 
-static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint *ep)
+static void snd_usbmidi_input_start_ep(struct snd_usb_midi *umidi,
+                                      struct snd_usb_midi_in_endpoint *ep)
 {
        unsigned int i;
+       unsigned long flags;
 
        if (!ep)
                return;
        for (i = 0; i < INPUT_URBS; ++i) {
                struct urb *urb = ep->urbs[i];
-               urb->dev = ep->umidi->dev;
-               snd_usbmidi_submit_urb(urb, GFP_KERNEL);
+               spin_lock_irqsave(&umidi->disc_lock, flags);
+               if (!atomic_read(&urb->use_count)) {
+                       urb->dev = ep->umidi->dev;
+                       snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+               }
+               spin_unlock_irqrestore(&umidi->disc_lock, flags);
        }
 }
 
@@ -2326,7 +2333,7 @@ void snd_usbmidi_input_start(struct list_head *p)
        if (umidi->input_running || !umidi->opened[1])
                return;
        for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
-               snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
+               snd_usbmidi_input_start_ep(umidi, umidi->endpoints[i].in);
        umidi->input_running = 1;
 }
 EXPORT_SYMBOL(snd_usbmidi_input_start);