]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: leverage ap_disconnect() in ap_probe()
authorAlex Elder <elder@linaro.org>
Mon, 20 Oct 2014 15:28:00 +0000 (10:28 -0500)
committerGreg Kroah-Hartman <greg@kroah.com>
Mon, 20 Oct 2014 22:32:01 +0000 (06:32 +0800)
With a few minor changes, ap_disconnect() can correctly handle
cleaning up even a partially initialized USB interface.  Make those
changes, and then use ap_disconnect() to simplify cleanup for all
the error paths in ap_probe().  Reset all fields as they're cleaned
up to facilitate debugging.

Signed-off-by: Alex Elder <elder@linaro.org>
drivers/staging/greybus/es1-ap-usb.c

index 4473c9af97c6b69f0cfb6829a421b4e040bfea16..12eb9b2bee0f074b2ec55f56698f9defe9d42565 100644 (file)
@@ -277,22 +277,37 @@ static void ap_disconnect(struct usb_interface *interface)
 
        /* Tear down everything! */
        for (i = 0; i < NUM_CPORT_OUT_URB; ++i) {
-               usb_kill_urb(es1->cport_out_urb[i]);
-               usb_free_urb(es1->cport_out_urb[i]);
+               struct urb *urb = es1->cport_out_urb[i];
+
+               if (!urb)
+                       break;
+               usb_kill_urb(urb);
+               usb_free_urb(urb);
+               es1->cport_out_urb[i] = NULL;
+               es1->cport_out_urb_busy[i] = false;     /* just to be anal */
        }
 
        for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
-               usb_kill_urb(es1->cport_in_urb[i]);
-               usb_free_urb(es1->cport_in_urb[i]);
+               struct urb *urb = es1->cport_in_urb[i];
+
+               if (!urb)
+                       break;
+               usb_kill_urb(urb);
+               usb_free_urb(urb);
                kfree(es1->cport_in_buffer[i]);
+               es1->cport_in_buffer[i] = NULL;
        }
 
        usb_kill_urb(es1->svc_urb);
        usb_free_urb(es1->svc_urb);
-       usb_put_dev(es1->usb_dev);
+       es1->svc_urb = NULL;
        kfree(es1->svc_buffer);
-       greybus_remove_hd(es1->hd);
+       es1->svc_buffer = NULL;
+
        usb_set_intfdata(interface, NULL);
+       greybus_remove_hd(es1->hd);
+
+       usb_put_dev(es1->usb_dev);
 }
 
 /* Callback for when we get a SVC message */
@@ -466,7 +481,7 @@ static int ap_probe(struct usb_interface *interface,
 
        es1->svc_urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!es1->svc_urb)
-               goto error_int_urb;
+               goto error;
 
        usb_fill_int_urb(es1->svc_urb, udev,
                         usb_rcvintpipe(udev, es1->svc_endpoint),
@@ -474,7 +489,7 @@ static int ap_probe(struct usb_interface *interface,
                         es1, svc_interval);
        retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL);
        if (retval)
-               goto error_submit_urb;
+               goto error;
 
        /* Allocate buffers for our cport in messages and start them up */
        for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
@@ -483,10 +498,10 @@ static int ap_probe(struct usb_interface *interface,
 
                urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!urb)
-                       goto error_bulk_in_urb;
+                       goto error;
                buffer = kmalloc(ES1_GBUF_MSG_SIZE, GFP_KERNEL);
                if (!buffer)
-                       goto error_bulk_in_urb;
+                       goto error;
 
                usb_fill_bulk_urb(urb, udev,
                                  usb_rcvbulkpipe(udev, es1->cport_in_endpoint),
@@ -495,7 +510,7 @@ static int ap_probe(struct usb_interface *interface,
                es1->cport_in_buffer[i] = buffer;
                retval = usb_submit_urb(urb, GFP_KERNEL);
                if (retval)
-                       goto error_bulk_in_urb;
+                       goto error;
        }
 
        /* Allocate urbs for our CPort OUT messages */
@@ -504,31 +519,16 @@ static int ap_probe(struct usb_interface *interface,
 
                urb = usb_alloc_urb(0, GFP_KERNEL);
                if (!urb)
-                       goto error_bulk_out_urb;
+                       goto error;
 
                es1->cport_out_urb[i] = urb;
                es1->cport_out_urb_busy[i] = false;     /* just to be anal */
        }
 
        return 0;
-
-error_bulk_out_urb:
-       for (i = 0; i < NUM_CPORT_OUT_URB; ++i)
-               usb_free_urb(es1->cport_out_urb[i]);
-
-error_bulk_in_urb:
-       for (i = 0; i < NUM_CPORT_IN_URB; ++i) {
-               usb_kill_urb(es1->cport_in_urb[i]);
-               usb_free_urb(es1->cport_in_urb[i]);
-               kfree(es1->cport_in_buffer[i]);
-       }
-
-error_submit_urb:
-       usb_free_urb(es1->svc_urb);
-error_int_urb:
-       kfree(es1->svc_buffer);
 error:
-       greybus_remove_hd(es1->hd);
+       ap_disconnect(interface);
+
        return retval;
 }