From 1ec1d6dd357766cb6d1816ad61cc0f7ca3dbc960 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 20 Oct 2014 10:28:00 -0500 Subject: [PATCH] greybus: leverage ap_disconnect() in ap_probe() 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 --- drivers/staging/greybus/es1-ap-usb.c | 58 ++++++++++++++-------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/staging/greybus/es1-ap-usb.c b/drivers/staging/greybus/es1-ap-usb.c index 4473c9af97c6..12eb9b2bee0f 100644 --- a/drivers/staging/greybus/es1-ap-usb.c +++ b/drivers/staging/greybus/es1-ap-usb.c @@ -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; } -- 2.39.5