|
@@ -24,6 +24,7 @@
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/device.h>
|
|
|
#include <linux/kfifo.h>
|
|
|
+#include <linux/spinlock.h>
|
|
|
|
|
|
#include <sound/core.h>
|
|
|
#include <sound/initval.h>
|
|
@@ -89,6 +90,7 @@ struct f_midi {
|
|
|
unsigned int buflen, qlen;
|
|
|
/* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
|
|
|
DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
|
|
|
+ spinlock_t transmit_lock;
|
|
|
unsigned int in_last_port;
|
|
|
|
|
|
struct gmidi_in_port in_ports_array[/* in_ports */];
|
|
@@ -597,17 +599,22 @@ static void f_midi_transmit(struct f_midi *midi)
|
|
|
{
|
|
|
struct usb_ep *ep = midi->in_ep;
|
|
|
int ret;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
/* We only care about USB requests if IN endpoint is enabled */
|
|
|
if (!ep || !ep->enabled)
|
|
|
goto drop_out;
|
|
|
|
|
|
+ spin_lock_irqsave(&midi->transmit_lock, flags);
|
|
|
+
|
|
|
do {
|
|
|
ret = f_midi_do_transmit(midi, ep);
|
|
|
if (ret < 0)
|
|
|
goto drop_out;
|
|
|
} while (ret);
|
|
|
|
|
|
+ spin_unlock_irqrestore(&midi->transmit_lock, flags);
|
|
|
+
|
|
|
return;
|
|
|
|
|
|
drop_out:
|
|
@@ -1201,6 +1208,8 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
|
|
|
if (status)
|
|
|
goto setup_fail;
|
|
|
|
|
|
+ spin_lock_init(&midi->transmit_lock);
|
|
|
+
|
|
|
++opts->refcnt;
|
|
|
mutex_unlock(&opts->lock);
|
|
|
|