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 <dan.carpen...@oracle.com>
>

Acked-by: Michal Nazarewicz <min...@mina86.com>

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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to