From 0008d9d0ad0a2e854f2f3f61d58cdc44d98760ff Mon Sep 17 00:00:00 2001 From: Rui Miguel Silva Date: Tue, 20 Jan 2015 16:38:44 +0000 Subject: [PATCH] greybus: es1: release urb on error path if error is return when submiting the urb, we need to make sure to release the urb from the pool, or from the dinamicly allocated. As in it, factor out the free code and create the free_urb function. Signed-off-by: Rui Miguel Silva Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/gb-es1.c | 43 ++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/drivers/staging/greybus/gb-es1.c b/drivers/staging/greybus/gb-es1.c index f44c26d21a20..96c7c816b590 100644 --- a/drivers/staging/greybus/gb-es1.c +++ b/drivers/staging/greybus/gb-es1.c @@ -184,6 +184,28 @@ static struct urb *next_free_urb(struct es1_ap_dev *es1, gfp_t gfp_mask) return urb; } +static void free_urb(struct es1_ap_dev *es1, struct urb *urb) +{ + unsigned long flags; + int i; + /* + * See if this was an urb in our pool, if so mark it "free", otherwise + * we need to free it ourselves. + */ + spin_lock_irqsave(&es1->cport_out_urb_lock, flags); + for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { + if (urb == es1->cport_out_urb[i]) { + es1->cport_out_urb_busy[i] = false; + urb = NULL; + break; + } + } + spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags); + + /* If urb is not NULL, then we need to free this urb */ + usb_free_urb(urb); +} + /* * Returns an opaque cookie value if successful, or a pointer coded * error otherwise. If the caller wishes to cancel the in-flight @@ -238,6 +260,7 @@ static void *buffer_send(struct greybus_host_device *hd, u16 cport_id, retval = usb_submit_urb(urb, gfp_mask); if (retval) { pr_err("error %d submitting URB\n", retval); + free_urb(es1, urb); return ERR_PTR(retval); } @@ -413,10 +436,8 @@ static void cport_out_callback(struct urb *urb) { struct greybus_host_device *hd = urb->context; struct es1_ap_dev *es1 = hd_to_es1(hd); - unsigned long flags; int status = check_urb_status(urb); u8 *data = urb->transfer_buffer + 1; - int i; /* * Tell the submitter that the buffer send (attempt) is @@ -426,23 +447,7 @@ static void cport_out_callback(struct urb *urb) data = urb->transfer_buffer + 1; greybus_data_sent(hd, data, status); - /* - * See if this was an urb in our pool, if so mark it "free", otherwise - * we need to free it ourselves. - */ - spin_lock_irqsave(&es1->cport_out_urb_lock, flags); - for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { - if (urb == es1->cport_out_urb[i]) { - es1->cport_out_urb_busy[i] = false; - urb = NULL; - break; - } - } - spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags); - - /* If urb is not NULL, then we need to free this urb */ - usb_free_urb(urb); - + free_urb(es1, urb); /* * Rest assured Greg, this craziness is getting fixed. * -- 2.11.0