aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/function/f_midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function/f_midi.c')
-rw-r--r--drivers/usb/gadget/function/f_midi.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index 84c0ee5ebd1e..58fc199a18ec 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -24,6 +24,7 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/kfifo.h> 26#include <linux/kfifo.h>
27#include <linux/spinlock.h>
27 28
28#include <sound/core.h> 29#include <sound/core.h>
29#include <sound/initval.h> 30#include <sound/initval.h>
@@ -89,6 +90,7 @@ struct f_midi {
89 unsigned int buflen, qlen; 90 unsigned int buflen, qlen;
90 /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */ 91 /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
91 DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *); 92 DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
93 spinlock_t transmit_lock;
92 unsigned int in_last_port; 94 unsigned int in_last_port;
93 95
94 struct gmidi_in_port in_ports_array[/* in_ports */]; 96 struct gmidi_in_port in_ports_array[/* in_ports */];
@@ -358,7 +360,9 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
358 /* allocate a bunch of read buffers and queue them all at once. */ 360 /* allocate a bunch of read buffers and queue them all at once. */
359 for (i = 0; i < midi->qlen && err == 0; i++) { 361 for (i = 0; i < midi->qlen && err == 0; i++) {
360 struct usb_request *req = 362 struct usb_request *req =
361 midi_alloc_ep_req(midi->out_ep, midi->buflen); 363 midi_alloc_ep_req(midi->out_ep,
364 max_t(unsigned, midi->buflen,
365 bulk_out_desc.wMaxPacketSize));
362 if (req == NULL) 366 if (req == NULL)
363 return -ENOMEM; 367 return -ENOMEM;
364 368
@@ -597,17 +601,24 @@ static void f_midi_transmit(struct f_midi *midi)
597{ 601{
598 struct usb_ep *ep = midi->in_ep; 602 struct usb_ep *ep = midi->in_ep;
599 int ret; 603 int ret;
604 unsigned long flags;
600 605
601 /* We only care about USB requests if IN endpoint is enabled */ 606 /* We only care about USB requests if IN endpoint is enabled */
602 if (!ep || !ep->enabled) 607 if (!ep || !ep->enabled)
603 goto drop_out; 608 goto drop_out;
604 609
610 spin_lock_irqsave(&midi->transmit_lock, flags);
611
605 do { 612 do {
606 ret = f_midi_do_transmit(midi, ep); 613 ret = f_midi_do_transmit(midi, ep);
607 if (ret < 0) 614 if (ret < 0) {
615 spin_unlock_irqrestore(&midi->transmit_lock, flags);
608 goto drop_out; 616 goto drop_out;
617 }
609 } while (ret); 618 } while (ret);
610 619
620 spin_unlock_irqrestore(&midi->transmit_lock, flags);
621
611 return; 622 return;
612 623
613drop_out: 624drop_out:
@@ -1201,6 +1212,8 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
1201 if (status) 1212 if (status)
1202 goto setup_fail; 1213 goto setup_fail;
1203 1214
1215 spin_lock_init(&midi->transmit_lock);
1216
1204 ++opts->refcnt; 1217 ++opts->refcnt;
1205 mutex_unlock(&opts->lock); 1218 mutex_unlock(&opts->lock);
1206 1219