From b4bd3617ed069a0aae701ed451cb6ec370fbd45f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 4 Nov 2015 18:55:21 +0100 Subject: [PATCH] greybus: es1: add more structure to probe error handling 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. Compile-only tested. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/es1.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/staging/greybus/es1.c b/drivers/staging/greybus/es1.c index 3047769..858c4aa 100644 --- a/drivers/staging/greybus/es1.c +++ b/drivers/staging/greybus/es1.c @@ -359,19 +359,11 @@ static int check_urb_status(struct urb *urb) return -EAGAIN; } -static void ap_disconnect(struct usb_interface *interface) +static void es1_destroy(struct es1_ap_dev *es1) { - struct es1_ap_dev *es1; struct usb_device *udev; int i; - es1 = usb_get_intfdata(interface); - if (!es1) - return; - - for (i = 0; i < NUM_CPORT_IN_URB; ++i) - usb_kill_urb(es1->cport_in_urb[i]); - debugfs_remove(apb1_log_enable_dentry); usb_log_disable(es1); @@ -397,13 +389,23 @@ static void ap_disconnect(struct usb_interface *interface) es1->cport_in_buffer[i] = NULL; } - usb_set_intfdata(interface, NULL); udev = es1->usb_dev; gb_hd_remove(es1->hd); usb_put_dev(udev); } +static void ap_disconnect(struct usb_interface *interface) +{ + struct es1_ap_dev *es1 = usb_get_intfdata(interface); + int i; + + for (i = 0; i < NUM_CPORT_IN_URB; ++i) + usb_kill_urb(es1->cport_in_urb[i]); + + es1_destroy(es1); +} + static void cport_in_callback(struct urb *urb) { struct gb_host_device *hd = urb->context; @@ -693,12 +695,16 @@ static int ap_probe(struct usb_interface *interface, for (i = 0; i < NUM_CPORT_IN_URB; ++i) { retval = usb_submit_urb(es1->cport_in_urb[i], GFP_KERNEL); if (retval) - goto error; + goto err_kill_in_urbs; } return 0; + +err_kill_in_urbs: + for (--i; i >= 0; --i) + usb_kill_urb(es1->cport_in_urb[i]); error: - ap_disconnect(interface); + es1_destroy(es1); return retval; } -- 2.7.4