usb: gadget: f_midi: fix in_last_port looping logic
authorMichal Nazarewicz <mina86@mina86.com>
Mon, 18 Jan 2016 17:30:15 +0000 (18:30 +0100)
committerFelipe Balbi <balbi@kernel.org>
Fri, 4 Mar 2016 13:14:33 +0000 (15:14 +0200)
In general case, all of midi->in_port pointers may be non-NULL which
implies that the ‘if (\!port)’ condition will never execute thus never
zeroing midi->in_last_port.  Fix by rewriting the loop such that the
field is set to zero if \!port or end of loop has been reached.

Signed-off-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
drivers/usb/gadget/function/f_midi.c

index 75853a3..896f02c 100644 (file)
@@ -534,6 +534,7 @@ static void f_midi_drop_out_substreams(struct f_midi *midi)
 static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep)
 {
        struct usb_request *req = NULL;
+       struct gmidi_in_port *port;
        unsigned int len, i;
        bool active = false;
        int err;
@@ -557,16 +558,9 @@ static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep)
        if (req->length > 0)
                return 0;
 
-       for (i = midi->in_last_port; i < MAX_PORTS; i++) {
-               struct gmidi_in_port *port = midi->in_port[i];
+       i = midi->in_last_port;
+       for (; i < MAX_PORTS && (port = midi->in_port[i]); ++i) {
                struct snd_rawmidi_substream *substream = midi->in_substream[i];
-
-               if (!port) {
-                       /* Reset counter when we reach the last available port */
-                       midi->in_last_port = 0;
-                       break;
-               }
-
                if (!port->active || !substream)
                        continue;
 
@@ -581,20 +575,13 @@ static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep)
                }
 
                active = !!port->active;
-               /*
-                * Check if last port is still active, which means that there is
-                * still data on that substream but this current request run out
-                * of space.
-                */
-               if (active) {
-                       midi->in_last_port = i;
-                       /* There is no need to re-iterate though midi ports. */
+               if (active)
                        break;
-               }
        }
+       midi->in_last_port = active ? i : 0;
 
        if (req->length <= 0)
-               return active;
+               goto done;
 
        err = usb_ep_queue(ep, req, GFP_ATOMIC);
        if (err < 0) {
@@ -607,6 +594,7 @@ static int f_midi_do_transmit(struct f_midi *midi, struct usb_ep *ep)
                kfifo_put(&midi->in_req_fifo, req);
        }
 
+done:
        return active;
 }