On Sat, Apr 02 2016, Dan Carpenter wrote:
> We added some new locking here, but missed an error path where we need
> to unlock.
>
> Fixes: 9acdf4df2fc4 ('usb: gadget: f_midi: added spinlock on transmit
> function')
> Signed-off-by: Dan Carpenter <[email protected]>
>
Acked-by: Michal Nazarewicz <[email protected]>
But perhaps this would be cleaner:
diff --git a/drivers/usb/gadget/function/f_midi.c
b/drivers/usb/gadget/function/f_midi.c
index 56e2dde..c04436f 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -606,19 +606,14 @@ static void f_midi_transmit(struct f_midi *midi)
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);
-
+ while ((ret = f_midi_do_transmit(midi, ep)) > 0) {
+ /* nop */
+ }
spin_unlock_irqrestore(&midi->transmit_lock, flags);
- return;
-
+ if (ret < 0)
drop_out:
- f_midi_drop_out_substreams(midi);
+ f_midi_drop_out_substreams(midi);
}
static void f_midi_in_tasklet(unsigned long data)
Or maybe even this which gets away with gotos all together:
diff --git a/drivers/usb/gadget/function/f_midi.c
b/drivers/usb/gadget/function/f_midi.c
index 56e2dde..91cae60 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -598,27 +598,20 @@ done:
static void f_midi_transmit(struct f_midi *midi)
{
struct usb_ep *ep = midi->in_ep;
- int ret;
unsigned long flags;
+ int ret = -1;
/* 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;
+ if (ep && ep->enabled) {
+ spin_lock_irqsave(&midi->transmit_lock, flags);
+ while ((ret = f_midi_do_transmit(midi, ep)) > 0) {
+ /* nop */
+ }
+ spin_unlock_irqrestore(&midi->transmit_lock, flags);
+ }
-drop_out:
- f_midi_drop_out_substreams(midi);
+ if (ret < 0)
+ f_midi_drop_out_substreams(midi);
}
static void f_midi_in_tasklet(unsigned long data)
> diff --git a/drivers/usb/gadget/function/f_midi.c
> b/drivers/usb/gadget/function/f_midi.c
> index 56e2dde..2c0616c 100644
> --- a/drivers/usb/gadget/function/f_midi.c
> +++ b/drivers/usb/gadget/function/f_midi.c
> @@ -609,8 +609,10 @@ static void f_midi_transmit(struct f_midi *midi)
>
> 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);
--
Best regards
ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ
«If at first you don’t succeed, give up skydiving»
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html