greybus: es2: add more structure to probe error handling
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 4 Nov 2015 17:55:20 +0000 (18:55 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 Nov 2015 04:35:18 +0000 (20:35 -0800)
Add more structure to probe error handling rather than use the big
hammer and call disconnect directly.

This is needed to fix some host-device life-time issues.

Note that there was never any need to clear the USB interface data as
this will be done by driver core.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/es2.c

index 18cfcd6b65786f2f096d9525c6d372ad901e3609..96ba1a74bb69ef65dce054cb60eb93b1b0fa5490 100644 (file)
@@ -547,21 +547,13 @@ static int check_urb_status(struct urb *urb)
        return -EAGAIN;
 }
 
-static void ap_disconnect(struct usb_interface *interface)
+static void es2_destroy(struct es2_ap_dev *es2)
 {
-       struct es2_ap_dev *es2;
        struct usb_device *udev;
        int *cport_to_ep;
        int bulk_in;
        int i;
 
-       es2 = usb_get_intfdata(interface);
-       if (!es2)
-               return;
-
-       for (i = 0; i < NUM_BULKS; ++i)
-               es2_cport_in_disable(es2, &es2->cport_in[i]);
-
        debugfs_remove(es2->apb_log_enable_dentry);
        usb_log_disable(es2);
 
@@ -591,7 +583,6 @@ static void ap_disconnect(struct usb_interface *interface)
                }
        }
 
-       usb_set_intfdata(interface, NULL);
        udev = es2->usb_dev;
        cport_to_ep = es2->cport_to_ep;
        gb_hd_remove(es2->hd);
@@ -600,6 +591,17 @@ static void ap_disconnect(struct usb_interface *interface)
        usb_put_dev(udev);
 }
 
+static void ap_disconnect(struct usb_interface *interface)
+{
+       struct es2_ap_dev *es2 = usb_get_intfdata(interface);
+       int i;
+
+       for (i = 0; i < NUM_BULKS; ++i)
+               es2_cport_in_disable(es2, &es2->cport_in[i]);
+
+       es2_destroy(es2);
+}
+
 static void cport_in_callback(struct urb *urb)
 {
        struct gb_host_device *hd = urb->context;
@@ -943,12 +945,16 @@ static int ap_probe(struct usb_interface *interface,
        for (i = 0; i < NUM_BULKS; ++i) {
                retval = es2_cport_in_enable(es2, &es2->cport_in[i]);
                if (retval)
-                       goto error;
+                       goto err_disable_cport_in;
        }
 
        return 0;
+
+err_disable_cport_in:
+       for (--i; i >= 0; --i)
+               es2_cport_in_disable(es2, &es2->cport_in[i]);
 error:
-       ap_disconnect(interface);
+       es2_destroy(es2);
 
        return retval;
 }