diff options
| author | Ingo Molnar <mingo@kernel.org> | 2016-05-05 09:57:27 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-05-05 09:57:27 +0200 |
| commit | e8c8ce54807b19e90ac84e609b13f7d4e337eab1 (patch) | |
| tree | ae7d65ae17d55aee197b605ce1a193fe594af614 /drivers/usb/gadget/function/f_midi.c | |
| parent | 5db4298133d99b3dfc60d6899ac9df169769c899 (diff) | |
| parent | 04974df8049fc4240d22759a91e035082ccd18b4 (diff) | |
Merge tag 'v4.6-rc6' into locking/core, to pick up fixes
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/usb/gadget/function/f_midi.c')
| -rw-r--r-- | drivers/usb/gadget/function/f_midi.c | 17 |
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 @@ #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 */]; @@ -358,7 +360,9 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* allocate a bunch of read buffers and queue them all at once. */ for (i = 0; i < midi->qlen && err == 0; i++) { struct usb_request *req = - midi_alloc_ep_req(midi->out_ep, midi->buflen); + midi_alloc_ep_req(midi->out_ep, + max_t(unsigned, midi->buflen, + bulk_out_desc.wMaxPacketSize)); if (req == NULL) return -ENOMEM; @@ -597,17 +601,24 @@ 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) + if (ret < 0) { + spin_unlock_irqrestore(&midi->transmit_lock, flags); goto drop_out; + } } while (ret); + spin_unlock_irqrestore(&midi->transmit_lock, flags); + return; drop_out: @@ -1201,6 +1212,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); |
